aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorAlbert Lee <albertcc@tw.ibm.com>2005-08-12 02:15:34 -0400
committerJeff Garzik <jgarzik@pobox.com>2005-08-12 02:44:20 -0400
commit6ae4cfb5711b6f2878c9e384617971d98c34a7f5 (patch)
treed5e4f3ab6381c0c5429429eb9f4159e321af8431 /drivers/scsi
parentbc68552faad0e134eb22281343d5ae5a4873fa80 (diff)
[PATCH] libata ata_data_xfer() fix
PATCH 1/2: ata_data_xfer() fix Changes: - Modify ata_mmio_data_xfer() and ata_pio_data_xfer() to handle odd-lengthed buffer. - Add some function comments This patch does not reuse ap->pad as alignment buffer since using local variable seems good enough. Signed-off-by: Albert Lee <albertcc@tw.ibm.com> Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/libata-core.c111
1 files changed, 108 insertions, 3 deletions
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 73b1f72b7e43..8f6e536d8924 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -2519,6 +2519,20 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words)
2519#endif /* __BIG_ENDIAN */ 2519#endif /* __BIG_ENDIAN */
2520} 2520}
2521 2521
2522/**
2523 * ata_mmio_data_xfer - Transfer data by MMIO
2524 * @ap: port to read/write
2525 * @buf: data buffer
2526 * @buflen: buffer length
2527 * @do_write: read/write
2528 *
2529 * Transfer data from/to the device data register by MMIO.
2530 *
2531 * LOCKING:
2532 * Inherited from caller.
2533 *
2534 */
2535
2522static void ata_mmio_data_xfer(struct ata_port *ap, unsigned char *buf, 2536static void ata_mmio_data_xfer(struct ata_port *ap, unsigned char *buf,
2523 unsigned int buflen, int write_data) 2537 unsigned int buflen, int write_data)
2524{ 2538{
@@ -2527,6 +2541,7 @@ static void ata_mmio_data_xfer(struct ata_port *ap, unsigned char *buf,
2527 u16 *buf16 = (u16 *) buf; 2541 u16 *buf16 = (u16 *) buf;
2528 void __iomem *mmio = (void __iomem *)ap->ioaddr.data_addr; 2542 void __iomem *mmio = (void __iomem *)ap->ioaddr.data_addr;
2529 2543
2544 /* Transfer multiple of 2 bytes */
2530 if (write_data) { 2545 if (write_data) {
2531 for (i = 0; i < words; i++) 2546 for (i = 0; i < words; i++)
2532 writew(le16_to_cpu(buf16[i]), mmio); 2547 writew(le16_to_cpu(buf16[i]), mmio);
@@ -2534,19 +2549,76 @@ static void ata_mmio_data_xfer(struct ata_port *ap, unsigned char *buf,
2534 for (i = 0; i < words; i++) 2549 for (i = 0; i < words; i++)
2535 buf16[i] = cpu_to_le16(readw(mmio)); 2550 buf16[i] = cpu_to_le16(readw(mmio));
2536 } 2551 }
2552
2553 /* Transfer trailing 1 byte, if any. */
2554 if (unlikely(buflen & 0x01)) {
2555 u16 align_buf[1] = { 0 };
2556 unsigned char *trailing_buf = buf + buflen - 1;
2557
2558 if (write_data) {
2559 memcpy(align_buf, trailing_buf, 1);
2560 writew(le16_to_cpu(align_buf[0]), mmio);
2561 } else {
2562 align_buf[0] = cpu_to_le16(readw(mmio));
2563 memcpy(trailing_buf, align_buf, 1);
2564 }
2565 }
2537} 2566}
2538 2567
2568/**
2569 * ata_pio_data_xfer - Transfer data by PIO
2570 * @ap: port to read/write
2571 * @buf: data buffer
2572 * @buflen: buffer length
2573 * @do_write: read/write
2574 *
2575 * Transfer data from/to the device data register by PIO.
2576 *
2577 * LOCKING:
2578 * Inherited from caller.
2579 *
2580 */
2581
2539static void ata_pio_data_xfer(struct ata_port *ap, unsigned char *buf, 2582static void ata_pio_data_xfer(struct ata_port *ap, unsigned char *buf,
2540 unsigned int buflen, int write_data) 2583 unsigned int buflen, int write_data)
2541{ 2584{
2542 unsigned int dwords = buflen >> 1; 2585 unsigned int words = buflen >> 1;
2543 2586
2587 /* Transfer multiple of 2 bytes */
2544 if (write_data) 2588 if (write_data)
2545 outsw(ap->ioaddr.data_addr, buf, dwords); 2589 outsw(ap->ioaddr.data_addr, buf, words);
2546 else 2590 else
2547 insw(ap->ioaddr.data_addr, buf, dwords); 2591 insw(ap->ioaddr.data_addr, buf, words);
2592
2593 /* Transfer trailing 1 byte, if any. */
2594 if (unlikely(buflen & 0x01)) {
2595 u16 align_buf[1] = { 0 };
2596 unsigned char *trailing_buf = buf + buflen - 1;
2597
2598 if (write_data) {
2599 memcpy(align_buf, trailing_buf, 1);
2600 outw(le16_to_cpu(align_buf[0]), ap->ioaddr.data_addr);
2601 } else {
2602 align_buf[0] = cpu_to_le16(inw(ap->ioaddr.data_addr));
2603 memcpy(trailing_buf, align_buf, 1);
2604 }
2605 }
2548} 2606}
2549 2607
2608/**
2609 * ata_data_xfer - Transfer data from/to the data register.
2610 * @ap: port to read/write
2611 * @buf: data buffer
2612 * @buflen: buffer length
2613 * @do_write: read/write
2614 *
2615 * Transfer data from/to the device data register.
2616 *
2617 * LOCKING:
2618 * Inherited from caller.
2619 *
2620 */
2621
2550static void ata_data_xfer(struct ata_port *ap, unsigned char *buf, 2622static void ata_data_xfer(struct ata_port *ap, unsigned char *buf,
2551 unsigned int buflen, int do_write) 2623 unsigned int buflen, int do_write)
2552{ 2624{
@@ -2556,6 +2628,16 @@ static void ata_data_xfer(struct ata_port *ap, unsigned char *buf,
2556 ata_pio_data_xfer(ap, buf, buflen, do_write); 2628 ata_pio_data_xfer(ap, buf, buflen, do_write);
2557} 2629}
2558 2630
2631/**
2632 * ata_pio_sector - Transfer ATA_SECT_SIZE (512 bytes) of data.
2633 * @qc: Command on going
2634 *
2635 * Transfer ATA_SECT_SIZE of data from/to the ATA device.
2636 *
2637 * LOCKING:
2638 * Inherited from caller.
2639 */
2640
2559static void ata_pio_sector(struct ata_queued_cmd *qc) 2641static void ata_pio_sector(struct ata_queued_cmd *qc)
2560{ 2642{
2561 int do_write = (qc->tf.flags & ATA_TFLAG_WRITE); 2643 int do_write = (qc->tf.flags & ATA_TFLAG_WRITE);
@@ -2594,6 +2676,18 @@ static void ata_pio_sector(struct ata_queued_cmd *qc)
2594 kunmap(page); 2676 kunmap(page);
2595} 2677}
2596 2678
2679/**
2680 * __atapi_pio_bytes - Transfer data from/to the ATAPI device.
2681 * @qc: Command on going
2682 * @bytes: number of bytes
2683 *
2684 * Transfer Transfer data from/to the ATAPI device.
2685 *
2686 * LOCKING:
2687 * Inherited from caller.
2688 *
2689 */
2690
2597static void __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes) 2691static void __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes)
2598{ 2692{
2599 int do_write = (qc->tf.flags & ATA_TFLAG_WRITE); 2693 int do_write = (qc->tf.flags & ATA_TFLAG_WRITE);
@@ -2645,6 +2739,17 @@ next_sg:
2645 } 2739 }
2646} 2740}
2647 2741
2742/**
2743 * atapi_pio_bytes - Transfer data from/to the ATAPI device.
2744 * @qc: Command on going
2745 *
2746 * Transfer Transfer data from/to the ATAPI device.
2747 *
2748 * LOCKING:
2749 * Inherited from caller.
2750 *
2751 */
2752
2648static void atapi_pio_bytes(struct ata_queued_cmd *qc) 2753static void atapi_pio_bytes(struct ata_queued_cmd *qc)
2649{ 2754{
2650 struct ata_port *ap = qc->ap; 2755 struct ata_port *ap = qc->ap;