296 ) |
296 ) |
297 { |
297 { |
298 off_t off = 0; |
298 off_t off = 0; |
299 unsigned int i; |
299 unsigned int i; |
300 |
300 |
301 if (entry->data_type == 0x0002 && entry->bit_length == 8) { // int8 |
301 if (entry->data_type == 0x0002) { // int8 |
302 off += sprintf(buffer + off, "%i\n", *((int8_t *) request->data)); |
302 int8_t value; |
303 } |
303 if (entry->bit_length != 8) |
304 else if (entry->data_type == 0x0003 && entry->bit_length == 16) { // int16 |
304 goto not_fit; |
305 off += sprintf(buffer + off, "%i\n", *((int16_t *) request->data)); |
305 value = EC_READ_S8(request->data); |
306 } |
306 off += sprintf(buffer + off, "%i (0x%02X)\n", value, value); |
307 else if (entry->data_type == 0x0004 && entry->bit_length == 32) { // int32 |
307 } |
308 off += sprintf(buffer + off, "%i\n", *((int32_t *) request->data)); |
308 else if (entry->data_type == 0x0003) { // int16 |
309 } |
309 int16_t value; |
310 else if (entry->data_type == 0x0005 && entry->bit_length == 8) { // uint8 |
310 if (entry->bit_length != 16) |
311 off += sprintf(buffer + off, "%i\n", *((uint8_t *) request->data)); |
311 goto not_fit; |
312 } |
312 value = EC_READ_S16(request->data); |
313 else if (entry->data_type == 0x0006 && entry->bit_length == 16) { // uint16 |
313 off += sprintf(buffer + off, "%i (0x%04X)\n", value, value); |
314 off += sprintf(buffer + off, "%i\n", *((uint16_t *) request->data)); |
314 } |
315 } |
315 else if (entry->data_type == 0x0004) { // int32 |
316 else if (entry->data_type == 0x0007 && entry->bit_length == 32) { // uint32 |
316 int32_t value; |
317 off += sprintf(buffer + off, "%i\n", *((uint32_t *) request->data)); |
317 if (entry->bit_length != 32) |
|
318 goto not_fit; |
|
319 value = EC_READ_S16(request->data); |
|
320 off += sprintf(buffer + off, "%i (0x%08X)\n", value, value); |
|
321 } |
|
322 else if (entry->data_type == 0x0005) { // uint8 |
|
323 uint8_t value; |
|
324 if (entry->bit_length != 8) |
|
325 goto not_fit; |
|
326 value = EC_READ_U8(request->data); |
|
327 off += sprintf(buffer + off, "%u (0x%02X)\n", value, value); |
|
328 } |
|
329 else if (entry->data_type == 0x0006) { // uint16 |
|
330 uint16_t value; |
|
331 if (entry->bit_length != 16) |
|
332 goto not_fit; |
|
333 value = EC_READ_U16(request->data); |
|
334 off += sprintf(buffer + off, "%u (0x%04X)\n", value, value); |
|
335 } |
|
336 else if (entry->data_type == 0x0007) { // uint32 |
|
337 uint32_t value; |
|
338 if (entry->bit_length != 32) |
|
339 goto not_fit; |
|
340 value = EC_READ_U32(request->data); |
|
341 off += sprintf(buffer + off, "%i (0x%08X)\n", value, value); |
318 } |
342 } |
319 else if (entry->data_type == 0x0009) { // string |
343 else if (entry->data_type == 0x0009) { // string |
320 off += sprintf(buffer + off, "%s\n", request->data); |
344 off += sprintf(buffer + off, "%s\n", request->data); |
321 } |
345 } |
322 else { |
346 else { |
323 for (i = 0; i < request->size; i++) |
347 off += sprintf(buffer + off, "Unknown data type %04X. Data:\n", |
324 off += sprintf(buffer + off, "%02X (%c)\n", |
348 entry->data_type); |
325 request->data[i], request->data[i]); |
349 goto raw_data; |
326 } |
350 } |
327 |
351 return off; |
|
352 |
|
353 not_fit: |
|
354 off += sprintf(buffer + off, |
|
355 "Invalid bit length %u for data type 0x%04X. Data:\n", |
|
356 entry->bit_length, entry->data_type); |
|
357 raw_data: |
|
358 for (i = 0; i < request->size; i++) |
|
359 off += sprintf(buffer + off, "%02X (%c)\n", |
|
360 request->data[i], request->data[i]); |
328 return off; |
361 return off; |
329 } |
362 } |
330 |
363 |
331 /*****************************************************************************/ |
364 /*****************************************************************************/ |
332 |
365 |
337 ec_sdo_t *sdo = entry->sdo; |
370 ec_sdo_t *sdo = entry->sdo; |
338 ec_master_t *master = sdo->slave->master; |
371 ec_master_t *master = sdo->slave->master; |
339 off_t off = 0; |
372 off_t off = 0; |
340 ec_sdo_request_t request; |
373 ec_sdo_request_t request; |
341 |
374 |
342 if (down_interruptible(&master->sdo_sem)) { |
375 ec_sdo_request_init_read(&request, sdo, entry); |
|
376 |
|
377 // schedule request. |
|
378 down(&master->sdo_sem); |
|
379 list_add_tail(&request.list, &master->sdo_requests); |
|
380 up(&master->sdo_sem); |
|
381 |
|
382 // wait for processing through FSM |
|
383 if (wait_event_interruptible(master->sdo_queue, |
|
384 request.state != EC_REQUEST_QUEUED)) { |
343 // interrupted by signal |
385 // interrupted by signal |
344 return -ERESTARTSYS; |
386 down(&master->sdo_sem); |
345 } |
387 if (request.state == EC_REQUEST_QUEUED) { |
346 |
388 list_del(&request.list); |
347 ec_sdo_request_init_read(&request, sdo, entry); |
389 up(&master->sdo_sem); |
348 |
390 return -EINTR; |
349 // this is necessary, because the completion object |
391 } |
350 // is completed by the ec_master_flush_sdo_requests() function. |
392 // request already processing: interrupt not possible. |
351 INIT_COMPLETION(master->sdo_complete); |
393 up(&master->sdo_sem); |
352 |
394 } |
353 master->sdo_request = &request; |
395 |
354 master->sdo_seq_user++; |
396 // wait until master FSM has finished processing |
355 master->sdo_timer.expires = jiffies + 10; |
397 wait_event(master->sdo_queue, request.state != EC_REQUEST_IN_PROGRESS); |
356 add_timer(&master->sdo_timer); |
398 |
357 |
399 if (request.state != EC_REQUEST_COMPLETE) |
358 wait_for_completion(&master->sdo_complete); |
400 return -EIO; |
359 |
401 |
360 master->sdo_request = NULL; |
402 off += ec_sdo_entry_format_data(entry, &request, buffer); |
361 up(&master->sdo_sem); |
|
362 |
|
363 if (request.return_code == 1 && request.data) { |
|
364 off += ec_sdo_entry_format_data(entry, &request, buffer); |
|
365 } |
|
366 else { |
|
367 off = -EINVAL; |
|
368 } |
|
369 |
403 |
370 ec_sdo_request_clear(&request); |
404 ec_sdo_request_clear(&request); |
371 return off; |
405 return off; |
372 } |
406 } |
373 |
407 |