master/master.c
changeset 2032 57c618557912
parent 2031 7a025a9e192d
child 2036 7fbc7bb7b95a
equal deleted inserted replaced
2031:7a025a9e192d 2032:57c618557912
  2304 
  2304 
  2305 int ecrt_master_write_idn(ec_master_t *master, uint16_t slave_position,
  2305 int ecrt_master_write_idn(ec_master_t *master, uint16_t slave_position,
  2306         uint8_t drive_no, uint16_t idn, uint8_t *data, size_t data_size,
  2306         uint8_t drive_no, uint16_t idn, uint8_t *data, size_t data_size,
  2307         uint16_t *error_code)
  2307         uint16_t *error_code)
  2308 {
  2308 {
  2309     ec_master_soe_request_t request;
  2309     ec_master_soe_request_t* request;
  2310     int retval;
  2310     int retval;
  2311 
  2311 
  2312     if (drive_no > 7) {
  2312     if (drive_no > 7) {
  2313         EC_MASTER_ERR(master, "Invalid drive number!\n");
  2313         EC_MASTER_ERR(master, "Invalid drive number!\n");
  2314         return -EINVAL;
  2314         return -EINVAL;
  2315     }
  2315     }
  2316 
  2316 
  2317     INIT_LIST_HEAD(&request.list);
  2317     request = kmalloc(sizeof(*request), GFP_KERNEL);
  2318     ec_soe_request_init(&request.req);
  2318     if (!request)
  2319     ec_soe_request_set_drive_no(&request.req, drive_no);
       
  2320     ec_soe_request_set_idn(&request.req, idn);
       
  2321 
       
  2322     if (ec_soe_request_alloc(&request.req, data_size)) {
       
  2323         ec_soe_request_clear(&request.req);
       
  2324         return -ENOMEM;
  2319         return -ENOMEM;
  2325     }
  2320     kref_init(&request->refcount);
  2326 
  2321 
  2327     memcpy(request.req.data, data, data_size);
  2322     INIT_LIST_HEAD(&request->list);
  2328     request.req.data_size = data_size;
  2323     ec_soe_request_init(&request->req);
  2329     ec_soe_request_write(&request.req);
  2324     ec_soe_request_set_drive_no(&request->req, drive_no);
  2330 
  2325     ec_soe_request_set_idn(&request->req, idn);
  2331     if (ec_mutex_lock_interruptible(&master->master_mutex))
  2326 
       
  2327     if (ec_soe_request_alloc(&request->req, data_size)) {
       
  2328         ec_soe_request_clear(&request->req);
       
  2329         kref_put(&request->refcount,ec_master_soe_request_release);
       
  2330         return -ENOMEM;
       
  2331     }
       
  2332 
       
  2333     memcpy(request->req.data, data, data_size);
       
  2334     request->req.data_size = data_size;
       
  2335     ec_soe_request_write(&request->req);
       
  2336 
       
  2337     if (ec_mutex_lock_interruptible(&master->master_mutex)) {
       
  2338         kref_put(&request->refcount,ec_master_soe_request_release);
  2332         return -EINTR;
  2339         return -EINTR;
  2333 
  2340     }
  2334     if (!(request.slave = ec_master_find_slave(
  2341 
       
  2342     if (!(request->slave = ec_master_find_slave(
  2335                     master, 0, slave_position))) {
  2343                     master, 0, slave_position))) {
  2336         ec_mutex_unlock(&master->master_mutex);
  2344         ec_mutex_unlock(&master->master_mutex);
  2337         EC_MASTER_ERR(master, "Slave %u does not exist!\n",
  2345         EC_MASTER_ERR(master, "Slave %u does not exist!\n",
  2338                 slave_position);
  2346                 slave_position);
  2339         ec_soe_request_clear(&request.req);
  2347         kref_put(&request->refcount,ec_master_soe_request_release);
  2340         return -EINVAL;
  2348         return -EINVAL;
  2341     }
  2349     }
  2342 
  2350 
  2343     EC_SLAVE_DBG(request.slave, 1, "Scheduling SoE write request.\n");
  2351     EC_SLAVE_DBG(request->slave, 1, "Scheduled SoE write request %p.\n",request);
  2344 
  2352 
  2345     // schedule SoE write request.
  2353     // schedule SoE write request.
  2346     list_add_tail(&request.list, &request.slave->soe_requests);
  2354     list_add_tail(&request->list, &request->slave->soe_requests);
       
  2355     kref_get(&request->refcount);
  2347 
  2356 
  2348     ec_mutex_unlock(&master->master_mutex);
  2357     ec_mutex_unlock(&master->master_mutex);
  2349 
  2358 
  2350     // wait for processing through FSM
  2359     // wait for processing through FSM
  2351     if (wait_event_interruptible(request.slave->soe_queue,
  2360     if (wait_event_interruptible(request->slave->soe_queue,
  2352                 request.req.state != EC_INT_REQUEST_QUEUED)) {
  2361           ((request->req.state == EC_INT_REQUEST_SUCCESS) || (request->req.state == EC_INT_REQUEST_FAILURE)))) {
  2353         // interrupted by signal
  2362            // interrupted by signal
  2354         ec_mutex_lock(&master->master_mutex);
  2363            kref_put(&request->refcount,ec_master_soe_request_release);
  2355         if (request.req.state == EC_INT_REQUEST_QUEUED) {
  2364            return -EINTR;
  2356             // abort request
  2365     }
  2357             list_del(&request.list);
       
  2358             ec_mutex_unlock(&master->master_mutex);
       
  2359             ec_soe_request_clear(&request.req);
       
  2360             return -EINTR;
       
  2361         }
       
  2362         ec_mutex_unlock(&master->master_mutex);
       
  2363     }
       
  2364 
       
  2365     // wait until master FSM has finished processing
       
  2366     wait_event(request.slave->soe_queue,
       
  2367             request.req.state != EC_INT_REQUEST_BUSY);
       
  2368 
  2366 
  2369     if (error_code) {
  2367     if (error_code) {
  2370         *error_code = request.req.error_code;
  2368         *error_code = request->req.error_code;
  2371     }
  2369     }
  2372     retval = request.req.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
  2370     retval = request->req.state == EC_INT_REQUEST_SUCCESS ? 0 : -EIO;
  2373     ec_soe_request_clear(&request.req);
  2371     kref_put(&request->refcount,ec_master_soe_request_release);
  2374 
  2372 
  2375     return retval;
  2373     return retval;
  2376 }
  2374 }
  2377 
  2375 
  2378 /*****************************************************************************/
  2376 /*****************************************************************************/
  2379 
  2377 
  2380 int ecrt_master_read_idn(ec_master_t *master, uint16_t slave_position,
  2378 int ecrt_master_read_idn(ec_master_t *master, uint16_t slave_position,
  2381         uint8_t drive_no, uint16_t idn, uint8_t *target, size_t target_size,
  2379         uint8_t drive_no, uint16_t idn, uint8_t *target, size_t target_size,
  2382         size_t *result_size, uint16_t *error_code)
  2380         size_t *result_size, uint16_t *error_code)
  2383 {
  2381 {
  2384     ec_master_soe_request_t request;
  2382     ec_master_soe_request_t* request;
  2385 
  2383 
  2386     if (drive_no > 7) {
  2384     if (drive_no > 7) {
  2387         EC_MASTER_ERR(master, "Invalid drive number!\n");
  2385         EC_MASTER_ERR(master, "Invalid drive number!\n");
  2388         return -EINVAL;
  2386         return -EINVAL;
  2389     }
  2387     }
  2390 
  2388 
  2391     INIT_LIST_HEAD(&request.list);
  2389     request = kmalloc(sizeof(*request), GFP_KERNEL);
  2392     ec_soe_request_init(&request.req);
  2390     if (!request)
  2393     ec_soe_request_set_drive_no(&request.req, drive_no);
  2391         return -ENOMEM;
  2394     ec_soe_request_set_idn(&request.req, idn);
  2392     kref_init(&request->refcount);
  2395     ec_soe_request_read(&request.req);
  2393 
  2396 
  2394     INIT_LIST_HEAD(&request->list);
  2397     if (ec_mutex_lock_interruptible(&master->master_mutex))
  2395     ec_soe_request_init(&request->req);
       
  2396     ec_soe_request_set_drive_no(&request->req, drive_no);
       
  2397     ec_soe_request_set_idn(&request->req, idn);
       
  2398     ec_soe_request_read(&request->req);
       
  2399 
       
  2400     if (ec_mutex_lock_interruptible(&master->master_mutex)) {
       
  2401         kref_put(&request->refcount,ec_master_soe_request_release);
  2398         return -EINTR;
  2402         return -EINTR;
  2399 
  2403     }
  2400     if (!(request.slave = ec_master_find_slave(master, 0, slave_position))) {
  2404 
       
  2405     if (!(request->slave = ec_master_find_slave(master, 0, slave_position))) {
  2401         ec_mutex_unlock(&master->master_mutex);
  2406         ec_mutex_unlock(&master->master_mutex);
  2402         ec_soe_request_clear(&request.req);
  2407         kref_put(&request->refcount,ec_master_soe_request_release);
  2403         EC_MASTER_ERR(master, "Slave %u does not exist!\n", slave_position);
  2408         EC_MASTER_ERR(master, "Slave %u does not exist!\n", slave_position);
  2404         return -EINVAL;
  2409         return -EINVAL;
  2405     }
  2410     }
  2406 
  2411 
  2407     // schedule request.
  2412     // schedule request.
  2408     list_add_tail(&request.list, &request.slave->soe_requests);
  2413     list_add_tail(&request->list, &request->slave->soe_requests);
       
  2414     kref_get(&request->refcount);
  2409 
  2415 
  2410     ec_mutex_unlock(&master->master_mutex);
  2416     ec_mutex_unlock(&master->master_mutex);
  2411 
  2417 
  2412     EC_SLAVE_DBG(request.slave, 1, "Scheduled SoE read request.\n");
  2418     EC_SLAVE_DBG(request->slave, 1, "Scheduled SoE read request %p.\n",request);
  2413 
  2419 
  2414     // wait for processing through FSM
  2420     // wait for processing through FSM
  2415     if (wait_event_interruptible(request.slave->soe_queue,
  2421     if (wait_event_interruptible(request->slave->soe_queue,
  2416                 request.req.state != EC_INT_REQUEST_QUEUED)) {
  2422           ((request->req.state == EC_INT_REQUEST_SUCCESS) || (request->req.state == EC_INT_REQUEST_FAILURE)))) {
  2417         // interrupted by signal
  2423            // interrupted by signal
  2418         ec_mutex_lock(&master->master_mutex);
  2424            kref_put(&request->refcount,ec_master_soe_request_release);
  2419         if (request.req.state == EC_INT_REQUEST_QUEUED) {
  2425            return -EINTR;
  2420             list_del(&request.list);
  2426     }
  2421             ec_mutex_unlock(&master->master_mutex);
       
  2422             ec_soe_request_clear(&request.req);
       
  2423             return -EINTR;
       
  2424         }
       
  2425         // request already processing: interrupt not possible.
       
  2426         ec_mutex_unlock(&master->master_mutex);
       
  2427     }
       
  2428 
       
  2429     // wait until master FSM has finished processing
       
  2430     wait_event(request.slave->soe_queue,
       
  2431             request.req.state != EC_INT_REQUEST_BUSY);
       
  2432 
  2427 
  2433     if (error_code) {
  2428     if (error_code) {
  2434         *error_code = request.req.error_code;
  2429         *error_code = request->req.error_code;
  2435     }
  2430     }
  2436 
  2431 
  2437     EC_SLAVE_DBG(request.slave, 1, "Read %zd bytes via SoE.\n",
  2432     EC_SLAVE_DBG(request->slave, 1, "SoE request %p read %zd bytes via SoE.\n",
  2438             request.req.data_size);
  2433             request,request->req.data_size);
  2439 
  2434 
  2440     if (request.req.state != EC_INT_REQUEST_SUCCESS) {
  2435     if (request->req.state != EC_INT_REQUEST_SUCCESS) {
  2441         if (result_size) {
  2436         if (result_size) {
  2442             *result_size = 0;
  2437             *result_size = 0;
  2443         }
  2438         }
  2444         ec_soe_request_clear(&request.req);
  2439         kref_put(&request->refcount,ec_master_soe_request_release);
  2445         return -EIO;
  2440         return -EIO;
  2446     } else {
  2441     } else {
  2447         if (request.req.data_size > target_size) {
  2442         if (request->req.data_size > target_size) {
  2448             EC_MASTER_ERR(master, "Buffer too small.\n");
  2443             EC_MASTER_ERR(master, "Buffer too small.\n");
  2449             ec_soe_request_clear(&request.req);
  2444             kref_put(&request->refcount,ec_master_soe_request_release);
  2450             return -EOVERFLOW;
  2445             return -EOVERFLOW;
  2451         }
  2446         }
  2452         if (result_size) {
  2447         if (result_size) {
  2453             *result_size = request.req.data_size;
  2448             *result_size = request->req.data_size;
  2454         }
  2449         }
  2455         memcpy(target, request.req.data, request.req.data_size);
  2450         memcpy(target, request->req.data, request->req.data_size);
       
  2451         kref_put(&request->refcount,ec_master_soe_request_release);
  2456         return 0;
  2452         return 0;
  2457     }
  2453     }
  2458 }
  2454 }
  2459 
  2455 
  2460 /*****************************************************************************/
  2456 /*****************************************************************************/