diff options
author | Jeff Garzik <jgarzik@pobox.com> | 2005-08-27 04:20:12 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-08-27 04:20:12 -0400 |
commit | 135932651fd1eeb95eb6c5d4f6652aae73fe2c24 (patch) | |
tree | 3a440b2a471ef4ab57b8aa75c3b068b2b52910ed /drivers/scsi | |
parent | d18d36b4edbb980c9de7fe00724c3ded5de1b7a7 (diff) |
[libata scsi] fix read/write translation edge cases
Fix bugs for unlikely edge cases noticed by Douglas Gilbert:
- When READ(6)/WRITE(6) sector count == 0, treat it as 256 sectors
- For other READ(x)/WRITE(x), when sector count == 0, error.
We don't support successfully completing zero-length transfers at
this time.
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/libata-scsi.c | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c index f58311b8c050..4074e7877ba3 100644 --- a/drivers/scsi/libata-scsi.c +++ b/drivers/scsi/libata-scsi.c | |||
@@ -630,11 +630,19 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) | |||
630 | tf->lbah = scsicmd[3]; | 630 | tf->lbah = scsicmd[3]; |
631 | 631 | ||
632 | VPRINTK("ten-byte command\n"); | 632 | VPRINTK("ten-byte command\n"); |
633 | if (qc->nsect == 0) /* we don't support length==0 cmds */ | ||
634 | return 1; | ||
633 | return 0; | 635 | return 0; |
634 | } | 636 | } |
635 | 637 | ||
636 | if (scsicmd[0] == READ_6 || scsicmd[0] == WRITE_6) { | 638 | if (scsicmd[0] == READ_6 || scsicmd[0] == WRITE_6) { |
637 | qc->nsect = tf->nsect = scsicmd[4]; | 639 | qc->nsect = tf->nsect = scsicmd[4]; |
640 | if (!qc->nsect) { | ||
641 | qc->nsect = 256; | ||
642 | if (lba48) | ||
643 | tf->hob_nsect = 1; | ||
644 | } | ||
645 | |||
638 | tf->lbal = scsicmd[3]; | 646 | tf->lbal = scsicmd[3]; |
639 | tf->lbam = scsicmd[2]; | 647 | tf->lbam = scsicmd[2]; |
640 | tf->lbah = scsicmd[1] & 0x1f; /* mask out reserved bits */ | 648 | tf->lbah = scsicmd[1] & 0x1f; /* mask out reserved bits */ |
@@ -674,6 +682,8 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) | |||
674 | tf->lbah = scsicmd[7]; | 682 | tf->lbah = scsicmd[7]; |
675 | 683 | ||
676 | VPRINTK("sixteen-byte command\n"); | 684 | VPRINTK("sixteen-byte command\n"); |
685 | if (qc->nsect == 0) /* we don't support length==0 cmds */ | ||
686 | return 1; | ||
677 | return 0; | 687 | return 0; |
678 | } | 688 | } |
679 | 689 | ||