diff options
Diffstat (limited to 'drivers/ata/libata-scsi.c')
-rw-r--r-- | drivers/ata/libata-scsi.c | 38 |
1 files changed, 34 insertions, 4 deletions
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 94144ed50a6b..a883bb03d4c7 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c | |||
@@ -2485,11 +2485,40 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc) | |||
2485 | if (!using_pio && ata_check_atapi_dma(qc)) | 2485 | if (!using_pio && ata_check_atapi_dma(qc)) |
2486 | using_pio = 1; | 2486 | using_pio = 1; |
2487 | 2487 | ||
2488 | /* Some controller variants snoop this value for Packet transfers | 2488 | /* Some controller variants snoop this value for Packet |
2489 | to do state machine and FIFO management. Thus we want to set it | 2489 | * transfers to do state machine and FIFO management. Thus we |
2490 | properly, and for DMA where it is effectively meaningless */ | 2490 | * want to set it properly, and for DMA where it is |
2491 | * effectively meaningless. | ||
2492 | */ | ||
2491 | nbytes = min(qc->nbytes, (unsigned int)63 * 1024); | 2493 | nbytes = min(qc->nbytes, (unsigned int)63 * 1024); |
2492 | 2494 | ||
2495 | /* Most ATAPI devices which honor transfer chunk size don't | ||
2496 | * behave according to the spec when odd chunk size which | ||
2497 | * matches the transfer length is specified. If the number of | ||
2498 | * bytes to transfer is 2n+1. According to the spec, what | ||
2499 | * should happen is to indicate that 2n+1 is going to be | ||
2500 | * transferred and transfer 2n+2 bytes where the last byte is | ||
2501 | * padding. | ||
2502 | * | ||
2503 | * In practice, this doesn't happen. ATAPI devices first | ||
2504 | * indicate and transfer 2n bytes and then indicate and | ||
2505 | * transfer 2 bytes where the last byte is padding. | ||
2506 | * | ||
2507 | * This inconsistency confuses several controllers which | ||
2508 | * perform PIO using DMA such as Intel AHCIs and sil3124/32. | ||
2509 | * These controllers use actual number of transferred bytes to | ||
2510 | * update DMA poitner and transfer of 4n+2 bytes make those | ||
2511 | * controller push DMA pointer by 4n+4 bytes because SATA data | ||
2512 | * FISes are aligned to 4 bytes. This causes data corruption | ||
2513 | * and buffer overrun. | ||
2514 | * | ||
2515 | * Always setting nbytes to even number solves this problem | ||
2516 | * because then ATAPI devices don't have to split data at 2n | ||
2517 | * boundaries. | ||
2518 | */ | ||
2519 | if (nbytes & 0x1) | ||
2520 | nbytes++; | ||
2521 | |||
2493 | qc->tf.lbam = (nbytes & 0xFF); | 2522 | qc->tf.lbam = (nbytes & 0xFF); |
2494 | qc->tf.lbah = (nbytes >> 8); | 2523 | qc->tf.lbah = (nbytes >> 8); |
2495 | 2524 | ||
@@ -2869,7 +2898,8 @@ static inline int __ata_scsi_queuecmd(struct scsi_cmnd *scmd, | |||
2869 | xlat_func = NULL; | 2898 | xlat_func = NULL; |
2870 | if (likely((scsi_op != ATA_16) || !atapi_passthru16)) { | 2899 | if (likely((scsi_op != ATA_16) || !atapi_passthru16)) { |
2871 | /* relay SCSI command to ATAPI device */ | 2900 | /* relay SCSI command to ATAPI device */ |
2872 | if (unlikely(scmd->cmd_len > dev->cdb_len)) | 2901 | int len = COMMAND_SIZE(scsi_op); |
2902 | if (unlikely(len > scmd->cmd_len || len > dev->cdb_len)) | ||
2873 | goto bad_cdb_len; | 2903 | goto bad_cdb_len; |
2874 | 2904 | ||
2875 | xlat_func = atapi_xlat; | 2905 | xlat_func = atapi_xlat; |