* [PATCH #upstream-fixes] libata: use atapi_cmd_type() to determine cmd type instead of transfer size
@ 2008-03-11 2:35 Tejun Heo
2008-03-11 12:50 ` Rafael J. Wysocki
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Tejun Heo @ 2008-03-11 2:35 UTC (permalink / raw)
To: Jeff Garzik, IDE/ATA development list, Alan Cox,
Rafael J. Wysocki
pata_ali and pata_it821x were using qc->nbytes to determine whether a
command is data transfer type or not. As now qc->nbytes can be
extended by padding and draining buffers, this tests are not useful
anymore. Use atapi_cmd_type() instead.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Cc: Rafael J. Wysocki <rjw@sisk.pl>
---
drivers/ata/pata_ali.c | 2 +-
drivers/ata/pata_it821x.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/ata/pata_ali.c b/drivers/ata/pata_ali.c
index 7e68edf..8786455 100644
--- a/drivers/ata/pata_ali.c
+++ b/drivers/ata/pata_ali.c
@@ -295,7 +295,7 @@ static void ali_lock_sectors(struct ata_device *adev)
static int ali_check_atapi_dma(struct ata_queued_cmd *qc)
{
/* If its not a media command, its not worth it */
- if (qc->nbytes < 2048)
+ if (atapi_cmd_type(qc->cdb[0]) == ATAPI_MISC)
return -EOPNOTSUPP;
return 0;
}
diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c
index 109ddd4..f751749 100644
--- a/drivers/ata/pata_it821x.c
+++ b/drivers/ata/pata_it821x.c
@@ -564,7 +564,7 @@ static int it821x_check_atapi_dma(struct ata_queued_cmd *qc)
struct it821x_dev *itdev = ap->private_data;
/* Only use dma for transfers to/from the media. */
- if (qc->nbytes < 2048)
+ if (atapi_cmd_type(qc->cdb[0]) == ATAPI_MISC)
return -EOPNOTSUPP;
/* No ATAPI DMA in smart mode */
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [PATCH #upstream-fixes] libata: use atapi_cmd_type() to determine cmd type instead of transfer size 2008-03-11 2:35 [PATCH #upstream-fixes] libata: use atapi_cmd_type() to determine cmd type instead of transfer size Tejun Heo @ 2008-03-11 12:50 ` Rafael J. Wysocki 2008-03-12 13:18 ` Alan Cox 2008-03-17 12:27 ` Jeff Garzik 2 siblings, 0 replies; 7+ messages in thread From: Rafael J. Wysocki @ 2008-03-11 12:50 UTC (permalink / raw) To: Tejun Heo; +Cc: Jeff Garzik, IDE/ATA development list, Alan Cox On Tuesday, 11 of March 2008, Tejun Heo wrote: > pata_ali and pata_it821x were using qc->nbytes to determine whether a > command is data transfer type or not. As now qc->nbytes can be > extended by padding and draining buffers, this tests are not useful > anymore. Use atapi_cmd_type() instead. > > Signed-off-by: Tejun Heo <htejun@gmail.com> > Cc: Alan Cox <alan@lxorguk.ukuu.org.uk> > Cc: Rafael J. Wysocki <rjw@sisk.pl> Tested-by: Rafael J. Wysocki <rjw@sisk.pl> > --- > drivers/ata/pata_ali.c | 2 +- > drivers/ata/pata_it821x.c | 2 +- > 2 files changed, 2 insertions(+), 2 deletions(-) > > diff --git a/drivers/ata/pata_ali.c b/drivers/ata/pata_ali.c > index 7e68edf..8786455 100644 > --- a/drivers/ata/pata_ali.c > +++ b/drivers/ata/pata_ali.c > @@ -295,7 +295,7 @@ static void ali_lock_sectors(struct ata_device *adev) > static int ali_check_atapi_dma(struct ata_queued_cmd *qc) > { > /* If its not a media command, its not worth it */ > - if (qc->nbytes < 2048) > + if (atapi_cmd_type(qc->cdb[0]) == ATAPI_MISC) > return -EOPNOTSUPP; > return 0; > } > diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c > index 109ddd4..f751749 100644 > --- a/drivers/ata/pata_it821x.c > +++ b/drivers/ata/pata_it821x.c > @@ -564,7 +564,7 @@ static int it821x_check_atapi_dma(struct ata_queued_cmd *qc) > struct it821x_dev *itdev = ap->private_data; > > /* Only use dma for transfers to/from the media. */ > - if (qc->nbytes < 2048) > + if (atapi_cmd_type(qc->cdb[0]) == ATAPI_MISC) > return -EOPNOTSUPP; > > /* No ATAPI DMA in smart mode */ > > ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH #upstream-fixes] libata: use atapi_cmd_type() to determine cmd type instead of transfer size 2008-03-11 2:35 [PATCH #upstream-fixes] libata: use atapi_cmd_type() to determine cmd type instead of transfer size Tejun Heo 2008-03-11 12:50 ` Rafael J. Wysocki @ 2008-03-12 13:18 ` Alan Cox 2008-03-17 12:27 ` Jeff Garzik 2 siblings, 0 replies; 7+ messages in thread From: Alan Cox @ 2008-03-12 13:18 UTC (permalink / raw) To: Tejun Heo; +Cc: Jeff Garzik, IDE/ATA development list, Rafael J. Wysocki On Tue, 11 Mar 2008 11:35:00 +0900 Tejun Heo <htejun@gmail.com> wrote: > pata_ali and pata_it821x were using qc->nbytes to determine whether a > command is data transfer type or not. As now qc->nbytes can be > extended by padding and draining buffers, this tests are not useful > anymore. Use atapi_cmd_type() instead. NAK The it821x case really seems to be about bytes transferred not command type. ALi one looks fine ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH #upstream-fixes] libata: use atapi_cmd_type() to determine cmd type instead of transfer size 2008-03-11 2:35 [PATCH #upstream-fixes] libata: use atapi_cmd_type() to determine cmd type instead of transfer size Tejun Heo 2008-03-11 12:50 ` Rafael J. Wysocki 2008-03-12 13:18 ` Alan Cox @ 2008-03-17 12:27 ` Jeff Garzik 2008-03-18 8:47 ` [PATCH #upstream-fixes 1/2] libata: implement ata_qc_raw_nbytes() Tejun Heo 2 siblings, 1 reply; 7+ messages in thread From: Jeff Garzik @ 2008-03-17 12:27 UTC (permalink / raw) To: Tejun Heo; +Cc: IDE/ATA development list, Alan Cox, Rafael J. Wysocki Tejun Heo wrote: > pata_ali and pata_it821x were using qc->nbytes to determine whether a > command is data transfer type or not. As now qc->nbytes can be > extended by padding and draining buffers, this tests are not useful > anymore. Use atapi_cmd_type() instead. > > Signed-off-by: Tejun Heo <htejun@gmail.com> > Cc: Alan Cox <alan@lxorguk.ukuu.org.uk> > Cc: Rafael J. Wysocki <rjw@sisk.pl> > --- > drivers/ata/pata_ali.c | 2 +- > drivers/ata/pata_it821x.c | 2 +- > 2 files changed, 2 insertions(+), 2 deletions(-) > > diff --git a/drivers/ata/pata_ali.c b/drivers/ata/pata_ali.c > index 7e68edf..8786455 100644 > --- a/drivers/ata/pata_ali.c > +++ b/drivers/ata/pata_ali.c > @@ -295,7 +295,7 @@ static void ali_lock_sectors(struct ata_device *adev) > static int ali_check_atapi_dma(struct ata_queued_cmd *qc) > { > /* If its not a media command, its not worth it */ > - if (qc->nbytes < 2048) > + if (atapi_cmd_type(qc->cdb[0]) == ATAPI_MISC) > return -EOPNOTSUPP; > return 0; > } applied the pata_ali portion of this patch ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH #upstream-fixes 1/2] libata: implement ata_qc_raw_nbytes() 2008-03-17 12:27 ` Jeff Garzik @ 2008-03-18 8:47 ` Tejun Heo 2008-03-18 8:56 ` [PATCH #upstream-fixes 2/2] pata_it821x: use raw nbytes in check_atapi_dma Tejun Heo 2008-03-25 2:26 ` [PATCH #upstream-fixes 1/2] libata: implement ata_qc_raw_nbytes() Jeff Garzik 0 siblings, 2 replies; 7+ messages in thread From: Tejun Heo @ 2008-03-18 8:47 UTC (permalink / raw) To: Jeff Garzik; +Cc: IDE/ATA development list, Alan Cox, Rafael J. Wysocki Implement ata_qc_raw_nbytes() which determines the raw user-requested size of a PC command. Signed-off-by: Tejun Heo <htejun@gmail.com> --- drivers/ata/libata-scsi.c | 14 +++++++++++--- include/linux/libata.h | 8 +++++++- 2 files changed, 18 insertions(+), 4 deletions(-) Index: work/drivers/ata/libata-scsi.c =================================================================== --- work.orig/drivers/ata/libata-scsi.c +++ work/drivers/ata/libata-scsi.c @@ -527,6 +527,14 @@ static struct ata_queued_cmd *ata_scsi_q return qc; } +static void ata_qc_set_pc_nbytes(struct ata_queued_cmd *qc) +{ + struct scsi_cmnd *scmd = qc->scsicmd; + + qc->extrabytes = scmd->request->extra_len; + qc->nbytes = scsi_bufflen(scmd) + qc->extrabytes; +} + /** * ata_dump_status - user friendly display of error info * @id: id of the port in question @@ -2539,7 +2547,7 @@ static unsigned int atapi_xlat(struct at } qc->tf.command = ATA_CMD_PACKET; - qc->nbytes = scsi_bufflen(scmd) + scmd->request->extra_len; + ata_qc_set_pc_nbytes(qc); /* check whether ATAPI DMA is safe */ if (!using_pio && ata_check_atapi_dma(qc)) @@ -2550,7 +2558,7 @@ static unsigned int atapi_xlat(struct at * want to set it properly, and for DMA where it is * effectively meaningless. */ - nbytes = min(scmd->request->data_len, (unsigned int)63 * 1024); + nbytes = min(ata_qc_raw_nbytes(qc), (unsigned int)63 * 1024); /* Most ATAPI devices which honor transfer chunk size don't * behave according to the spec when odd chunk size which @@ -2876,7 +2884,7 @@ static unsigned int ata_scsi_pass_thru(s * TODO: find out if we need to do more here to * cover scatter/gather case. */ - qc->nbytes = scsi_bufflen(scmd) + scmd->request->extra_len; + ata_qc_set_pc_nbytes(qc); /* request result TF and be quiet about device error */ qc->flags |= ATA_QCFLAG_RESULT_TF | ATA_QCFLAG_QUIET; Index: work/include/linux/libata.h =================================================================== --- work.orig/include/linux/libata.h +++ work/include/linux/libata.h @@ -463,6 +463,7 @@ struct ata_queued_cmd { unsigned int sect_size; unsigned int nbytes; + unsigned int extrabytes; unsigned int curbytes; struct scatterlist *cursg; @@ -1336,6 +1337,11 @@ static inline struct ata_queued_cmd *ata return NULL; } +static inline unsigned int ata_qc_raw_nbytes(struct ata_queued_cmd *qc) +{ + return qc->nbytes - min(qc->extrabytes, qc->nbytes); +} + static inline void ata_tf_init(struct ata_device *dev, struct ata_taskfile *tf) { memset(tf, 0, sizeof(*tf)); @@ -1354,7 +1360,7 @@ static inline void ata_qc_reinit(struct qc->flags = 0; qc->cursg = NULL; qc->cursg_ofs = 0; - qc->nbytes = qc->curbytes = 0; + qc->nbytes = qc->extrabytes = qc->curbytes = 0; qc->n_elem = 0; qc->err_mask = 0; qc->sect_size = ATA_SECT_SIZE; ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH #upstream-fixes 2/2] pata_it821x: use raw nbytes in check_atapi_dma 2008-03-18 8:47 ` [PATCH #upstream-fixes 1/2] libata: implement ata_qc_raw_nbytes() Tejun Heo @ 2008-03-18 8:56 ` Tejun Heo 2008-03-25 2:26 ` [PATCH #upstream-fixes 1/2] libata: implement ata_qc_raw_nbytes() Jeff Garzik 1 sibling, 0 replies; 7+ messages in thread From: Tejun Heo @ 2008-03-18 8:56 UTC (permalink / raw) To: Jeff Garzik; +Cc: IDE/ATA development list, Alan Cox, Rafael J. Wysocki pata_it821x needs to look at raw request size in check_atapi_dma(). Signed-off-by: Tejun Heo <htejun@gmail.com> Cc: Alan Cox <alan@lxorguk.ukuu.org.uk> --- This should restore the original behavior. However, there's a catch. Alan, you said DMA behavior on pata_it821x genuinely depends on transfer size, right? Then, it can be one of the following two. 1. It depends on the size of the buffer handed to the controller, in which case qc->nbytes is the right value to look at. For pata_ali, this definitely wasn't the case as small DMA transfers failed even though large aligned buffer was supplied. 2. It depends on the size of the data the drive transfers in response of the command. In this case, checking raw or any size on host size is useless as the drive may transfer any number of bytes. In this case, we should use command type to determine whether DMA can be used or not as we can guarantee certain transfer sizes for certain commands. pata_ali fell into this category. All in all, I think discerning #1 from #2 is hair-splitting for not enough benefit (heh.. yeah, I'm going there again) and applying #1 for controllers which fall in #2 is dangerous while the other way is fine. I think it's better to just implement atapi_check_dma_rw_only() and use it for these controllers. Anyways, this patch restores the old behavior and should be fine for 2.6.25. Thanks. drivers/ata/pata_it821x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) Index: work/drivers/ata/pata_it821x.c =================================================================== --- work.orig/drivers/ata/pata_it821x.c +++ work/drivers/ata/pata_it821x.c @@ -564,7 +564,7 @@ static int it821x_check_atapi_dma(struct struct it821x_dev *itdev = ap->private_data; /* Only use dma for transfers to/from the media. */ - if (qc->nbytes < 2048) + if (ata_qc_raw_nbytes(qc) < 2048) return -EOPNOTSUPP; /* No ATAPI DMA in smart mode */ ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH #upstream-fixes 1/2] libata: implement ata_qc_raw_nbytes() 2008-03-18 8:47 ` [PATCH #upstream-fixes 1/2] libata: implement ata_qc_raw_nbytes() Tejun Heo 2008-03-18 8:56 ` [PATCH #upstream-fixes 2/2] pata_it821x: use raw nbytes in check_atapi_dma Tejun Heo @ 2008-03-25 2:26 ` Jeff Garzik 1 sibling, 0 replies; 7+ messages in thread From: Jeff Garzik @ 2008-03-25 2:26 UTC (permalink / raw) To: Tejun Heo; +Cc: IDE/ATA development list, Alan Cox, Rafael J. Wysocki Tejun Heo wrote: > Implement ata_qc_raw_nbytes() which determines the raw user-requested > size of a PC command. > > Signed-off-by: Tejun Heo <htejun@gmail.com> > --- > drivers/ata/libata-scsi.c | 14 +++++++++++--- > include/linux/libata.h | 8 +++++++- > 2 files changed, 18 insertions(+), 4 deletions(-) applied 1-2 ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2008-03-25 2:26 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2008-03-11 2:35 [PATCH #upstream-fixes] libata: use atapi_cmd_type() to determine cmd type instead of transfer size Tejun Heo 2008-03-11 12:50 ` Rafael J. Wysocki 2008-03-12 13:18 ` Alan Cox 2008-03-17 12:27 ` Jeff Garzik 2008-03-18 8:47 ` [PATCH #upstream-fixes 1/2] libata: implement ata_qc_raw_nbytes() Tejun Heo 2008-03-18 8:56 ` [PATCH #upstream-fixes 2/2] pata_it821x: use raw nbytes in check_atapi_dma Tejun Heo 2008-03-25 2:26 ` [PATCH #upstream-fixes 1/2] libata: implement ata_qc_raw_nbytes() Jeff Garzik
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).