Commit 563a6e1f authored by Albert Lee's avatar Albert Lee Committed by Jeff Garzik

[PATCH] libata handle the case when device returns/needs extra data

PATCH 2/2:  handle the case when device returns/needs extra data

Description:
   Sometimes the device returns/needs extra data than expected.

Changes:
   Modify __atapi_pio_bytes() to handle the case where device returns/needs extra data.
     - for read case, discard trailing data from the device
     - for write case, padding zero data to the device
Signed-off-by: default avatarAlbert Lee <albertcc@tw.ibm.com>
Signed-off-by: default avatarJeff Garzik <jgarzik@pobox.com>
parent 6ae4cfb5
...@@ -2697,10 +2697,33 @@ static void __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes) ...@@ -2697,10 +2697,33 @@ static void __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes)
unsigned char *buf; unsigned char *buf;
unsigned int offset, count; unsigned int offset, count;
if (qc->curbytes == qc->nbytes - bytes) if (qc->curbytes + bytes >= qc->nbytes)
ap->pio_task_state = PIO_ST_LAST; ap->pio_task_state = PIO_ST_LAST;
next_sg: 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]; sg = &qc->sg[qc->cursg];
page = sg->page; page = sg->page;
...@@ -2734,9 +2757,8 @@ static void __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes) ...@@ -2734,9 +2757,8 @@ static void __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes)
kunmap(page); kunmap(page);
if (bytes) { if (bytes)
goto next_sg; goto next_sg;
}
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment