Jeff,

PATCH 3/3:

Sometimes the device returns/needs extra data than expected.

Changes:
  - Modify __atapi_pio_bytes() to handle the case when device returns/needs 
extra data.
    - for read case, discard trailing data from the device
    - for write case, padding zero data to the device

For your review, thanks.

Albert

Signed-off-by: Albert Lee <[EMAIL PROTECTED]>


--- 02_pio_odd/drivers/scsi/libata-core.c       2005-08-01 16:14:28.000000000 
+0800
+++ 03_pio_extra_data/drivers/scsi/libata-core.c        2005-08-01 
21:46:37.000000000 +0800
@@ -2722,6 +2722,29 @@
                ap->pio_task_state = PIO_ST_LAST;
 
 next_sg:
+       if (unlikely(qc->cursg >= qc->n_elem)) {
+               /* 
+                * The end of qc->sg is reached and the device expects
+                * more data to transfer. In order not to overrun qc->sg
+                * and fulfill length specified in the byte count register,
+                *    - for read case, discard trailing data from the device
+                *    - for write case, padding zero data to the device
+                */
+               u16 pad_buf[1] = { 0 };
+               unsigned int words = bytes >> 1;
+               unsigned int i;
+
+               if (words) /* warning if bytes > 1 */
+                       printk(KERN_WARNING "ata%u: %u bytes trailing data\n", 
+                              ap->id, bytes);
+
+               for (i = 0; i < words; i++)
+                       ata_data_xfer(ap, (unsigned char*)pad_buf, 2, do_write);
+
+               ap->pio_task_state = PIO_ST_LAST;
+               return;
+       }
+
        sg = &qc->sg[qc->cursg];
 
        page = sg->page;

Reply via email to