From b445c56815d84b9fce40707f99811bdc354458e0 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Fri, 29 Feb 2008 19:10:51 -0500 Subject: [libata] wrap kmap_atomic(KM_IRQ0) with local_irq_save/restore() Interrupts must be disabled if using kmap_atomic(KM_IRQ0), but that was not the case in a few code paths coming directly from ATA driver interrupt handlers (which use spin_lock rather than spin_lock_irqsave). Signed-off-by: Jeff Garzik --- drivers/ata/libata-scsi.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers/ata/libata-scsi.c') diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 0562b0a49f3..7b1f1ee8131 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -1694,12 +1694,17 @@ void ata_scsi_rbuf_fill(struct ata_scsi_args *args, u8 *rbuf; unsigned int buflen, rc; struct scsi_cmnd *cmd = args->cmd; + unsigned long flags; + + local_irq_save(flags); buflen = ata_scsi_rbuf_get(cmd, &rbuf); memset(rbuf, 0, buflen); rc = actor(args, rbuf, buflen); ata_scsi_rbuf_put(cmd, rbuf); + local_irq_restore(flags); + if (rc == 0) cmd->result = SAM_STAT_GOOD; args->done(cmd); @@ -2473,6 +2478,9 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc) if ((scsicmd[0] == INQUIRY) && ((scsicmd[1] & 0x03) == 0)) { u8 *buf = NULL; unsigned int buflen; + unsigned long flags; + + local_irq_save(flags); buflen = ata_scsi_rbuf_get(cmd, &buf); @@ -2490,6 +2498,8 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc) } ata_scsi_rbuf_put(cmd, buf); + + local_irq_restore(flags); } cmd->result = SAM_STAT_GOOD; -- cgit v1.2.3 From 7a85f8896f4b4a4a0249563b92af9e3161a6b467 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Tue, 4 Mar 2008 11:17:11 +0100 Subject: block: restore the meaning of rq->data_len to the true data length The meaning of rq->data_len was changed to the length of an allocated buffer from the true data length. It breaks SG_IO friends and bsg. This patch restores the meaning of rq->data_len to the true data length and adds rq->extra_len to store an extended length (due to drain buffer and padding). This patch also removes the code to update bio in blk_rq_map_user introduced by the commit 40b01b9bbdf51ae543a04744283bf2d56c4a6afa. The commit adjusts bio according to memory alignment (queue_dma_alignment). However, memory alignment is NOT padding alignment. This adjustment also breaks SG_IO friends and bsg. Padding alignment needs to be fixed in a proper way (by a separate patch). Signed-off-by: FUJITA Tomonori Signed-off-by: Jens Axboe --- drivers/ata/libata-scsi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/ata/libata-scsi.c') diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 7b1f1ee8131..fe47922dd69 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -2538,7 +2538,7 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc) } qc->tf.command = ATA_CMD_PACKET; - qc->nbytes = scsi_bufflen(scmd); + qc->nbytes = scsi_bufflen(scmd) + scmd->request->extra_len; /* check whether ATAPI DMA is safe */ if (!using_pio && ata_check_atapi_dma(qc)) @@ -2549,7 +2549,7 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc) * want to set it properly, and for DMA where it is * effectively meaningless. */ - nbytes = min(scmd->request->raw_data_len, (unsigned int)63 * 1024); + nbytes = min(scmd->request->data_len, (unsigned int)63 * 1024); /* Most ATAPI devices which honor transfer chunk size don't * behave according to the spec when odd chunk size which @@ -2875,7 +2875,7 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc) * TODO: find out if we need to do more here to * cover scatter/gather case. */ - qc->nbytes = scsi_bufflen(scmd); + qc->nbytes = scsi_bufflen(scmd) + scmd->request->extra_len; /* request result TF and be quiet about device error */ qc->flags |= ATA_QCFLAG_RESULT_TF | ATA_QCFLAG_QUIET; -- cgit v1.2.3 From e3790c7d42a545e8fe8b38b513613ca96687b670 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 4 Mar 2008 11:18:17 +0100 Subject: block: separate out padding from alignment Block layer alignment was used for two different purposes - memory alignment and padding. This causes problems in lower layers because drivers which only require memory alignment ends up with adjusted rq->data_len. Separate out padding such that padding occurs iff driver explicitly requests it. Tomo: restorethe code to update bio in blk_rq_map_user introduced by the commit 40b01b9bbdf51ae543a04744283bf2d56c4a6afa according to padding alignment. Signed-off-by: Tejun Heo Signed-off-by: FUJITA Tomonori Signed-off-by: Jens Axboe --- drivers/ata/libata-scsi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/ata/libata-scsi.c') diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index fe47922dd69..8f0e8f2bc62 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -862,9 +862,10 @@ static int ata_scsi_dev_config(struct scsi_device *sdev, struct request_queue *q = sdev->request_queue; void *buf; - /* set the min alignment */ + /* set the min alignment and padding */ blk_queue_update_dma_alignment(sdev->request_queue, ATA_DMA_PAD_SZ - 1); + blk_queue_dma_pad(sdev->request_queue, ATA_DMA_PAD_SZ - 1); /* configure draining */ buf = kmalloc(ATAPI_MAX_DRAIN, q->bounce_gfp | GFP_KERNEL); -- cgit v1.2.3