diff options
author | Jeff Garzik <jgarzik@pobox.com> | 2005-10-05 07:13:30 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-10-05 07:13:30 -0400 |
commit | cedc9a478d8c6265879dc3839ef3d4849a709184 (patch) | |
tree | 0c8e0fbffdb6081381c01b8cfd93c95b168acb44 /drivers/scsi/libata-scsi.c | |
parent | ed39f731ab2e77e58122232f6e27333331d7793d (diff) |
libata: fix ATAPI DMA alignment issues
ATAPI needs to be padded to next 4 byte boundary, if misaligned.
Original work by me, many fixes from Tejun Heo.
Diffstat (limited to 'drivers/scsi/libata-scsi.c')
-rw-r--r-- | drivers/scsi/libata-scsi.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c index 104fd9a63e7..ee3f1050fb5 100644 --- a/drivers/scsi/libata-scsi.c +++ b/drivers/scsi/libata-scsi.c @@ -150,10 +150,10 @@ struct ata_queued_cmd *ata_scsi_qc_new(struct ata_port *ap, qc->scsidone = done; if (cmd->use_sg) { - qc->sg = (struct scatterlist *) cmd->request_buffer; + qc->__sg = (struct scatterlist *) cmd->request_buffer; qc->n_elem = cmd->use_sg; } else { - qc->sg = &qc->sgent; + qc->__sg = &qc->sgent; qc->n_elem = 1; } } else { @@ -364,6 +364,16 @@ int ata_scsi_slave_config(struct scsi_device *sdev) */ blk_queue_max_sectors(sdev->request_queue, 2048); } + + /* + * SATA DMA transfers must be multiples of 4 byte, so + * we need to pad ATAPI transfers using an extra sg. + * Decrement max hw segments accordingly. + */ + if (dev->class == ATA_DEV_ATAPI) { + request_queue_t *q = sdev->request_queue; + blk_queue_max_hw_segments(q, q->max_hw_segments - 1); + } } return 0; /* scsi layer doesn't check return value, sigh */ |