aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2007-11-27 05:28:53 -0500
committerJeff Garzik <jeff@garzik.org>2008-01-23 05:24:10 -0500
commit405e66b38797875e80669eaf72d313dbb76533c3 (patch)
treea069f0bb4ae1e81a58bc8f8965a2443d25186f0d
parentf20ded38aa54b92dd0af32578b8916d0aa2d9e05 (diff)
libata: implement protocol tests
Implement protocol tests - ata_is_atapi(), ata_is_nodata(), ata_is_pio(), ata_is_dma(), ata_is_ncq() and ata_is_data() and use them to replace is_atapi_taskfile() and hard coded protocol tests. Signed-off-by: Tejun Heo <htejun@gmail.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rw-r--r--drivers/ata/ahci.c2
-rw-r--r--drivers/ata/libata-core.c36
-rw-r--r--drivers/ata/sata_fsl.c2
-rw-r--r--drivers/ata/sata_sil.c10
-rw-r--r--drivers/ata/sata_sil24.c24
-rw-r--r--drivers/scsi/libsas/sas_ata.c2
-rw-r--r--include/linux/ata.h71
7 files changed, 82 insertions, 65 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index ef5e6b6e6e69..5eee91c73c90 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -1511,7 +1511,7 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc)
1511{ 1511{
1512 struct ata_port *ap = qc->ap; 1512 struct ata_port *ap = qc->ap;
1513 struct ahci_port_priv *pp = ap->private_data; 1513 struct ahci_port_priv *pp = ap->private_data;
1514 int is_atapi = is_atapi_taskfile(&qc->tf); 1514 int is_atapi = ata_is_atapi(qc->tf.protocol);
1515 void *cmd_tbl; 1515 void *cmd_tbl;
1516 u32 opts; 1516 u32 opts;
1517 const u32 cmd_fis_len = 5; /* five dwords */ 1517 const u32 cmd_fis_len = 5; /* five dwords */
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index bb9e025522ba..8c7af2c8e8d4 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -5358,7 +5358,7 @@ static inline int ata_hsm_ok_in_wq(struct ata_port *ap, struct ata_queued_cmd *q
5358 (qc->tf.flags & ATA_TFLAG_WRITE)) 5358 (qc->tf.flags & ATA_TFLAG_WRITE))
5359 return 1; 5359 return 1;
5360 5360
5361 if (is_atapi_taskfile(&qc->tf) && 5361 if (ata_is_atapi(qc->tf.protocol) &&
5362 !(qc->dev->flags & ATA_DFLAG_CDB_INTR)) 5362 !(qc->dev->flags & ATA_DFLAG_CDB_INTR))
5363 return 1; 5363 return 1;
5364 } 5364 }
@@ -5955,30 +5955,6 @@ int ata_qc_complete_multiple(struct ata_port *ap, u32 qc_active,
5955 return nr_done; 5955 return nr_done;
5956} 5956}
5957 5957
5958static inline int ata_should_dma_map(struct ata_queued_cmd *qc)
5959{
5960 struct ata_port *ap = qc->ap;
5961
5962 switch (qc->tf.protocol) {
5963 case ATA_PROT_NCQ:
5964 case ATA_PROT_DMA:
5965 case ATA_PROT_ATAPI_DMA:
5966 return 1;
5967
5968 case ATA_PROT_ATAPI:
5969 case ATA_PROT_PIO:
5970 if (ap->flags & ATA_FLAG_PIO_DMA)
5971 return 1;
5972
5973 /* fall through */
5974
5975 default:
5976 return 0;
5977 }
5978
5979 /* never reached */
5980}
5981
5982/** 5958/**
5983 * ata_qc_issue - issue taskfile to device 5959 * ata_qc_issue - issue taskfile to device
5984 * @qc: command to issue to device 5960 * @qc: command to issue to device
@@ -5995,6 +5971,7 @@ void ata_qc_issue(struct ata_queued_cmd *qc)
5995{ 5971{
5996 struct ata_port *ap = qc->ap; 5972 struct ata_port *ap = qc->ap;
5997 struct ata_link *link = qc->dev->link; 5973 struct ata_link *link = qc->dev->link;
5974 u8 prot = qc->tf.protocol;
5998 5975
5999 /* Make sure only one non-NCQ command is outstanding. The 5976 /* Make sure only one non-NCQ command is outstanding. The
6000 * check is skipped for old EH because it reuses active qc to 5977 * check is skipped for old EH because it reuses active qc to
@@ -6002,7 +5979,7 @@ void ata_qc_issue(struct ata_queued_cmd *qc)
6002 */ 5979 */
6003 WARN_ON(ap->ops->error_handler && ata_tag_valid(link->active_tag)); 5980 WARN_ON(ap->ops->error_handler && ata_tag_valid(link->active_tag));
6004 5981
6005 if (qc->tf.protocol == ATA_PROT_NCQ) { 5982 if (prot == ATA_PROT_NCQ) {
6006 WARN_ON(link->sactive & (1 << qc->tag)); 5983 WARN_ON(link->sactive & (1 << qc->tag));
6007 5984
6008 if (!link->sactive) 5985 if (!link->sactive)
@@ -6018,7 +5995,8 @@ void ata_qc_issue(struct ata_queued_cmd *qc)
6018 qc->flags |= ATA_QCFLAG_ACTIVE; 5995 qc->flags |= ATA_QCFLAG_ACTIVE;
6019 ap->qc_active |= 1 << qc->tag; 5996 ap->qc_active |= 1 << qc->tag;
6020 5997
6021 if (ata_should_dma_map(qc)) { 5998 if (ata_is_dma(prot) || (ata_is_pio(prot) &&
5999 (ap->flags & ATA_FLAG_PIO_DMA))) {
6022 if (qc->flags & ATA_QCFLAG_SG) { 6000 if (qc->flags & ATA_QCFLAG_SG) {
6023 if (ata_sg_setup(qc)) 6001 if (ata_sg_setup(qc))
6024 goto sg_err; 6002 goto sg_err;
@@ -6217,8 +6195,8 @@ inline unsigned int ata_host_intr(struct ata_port *ap,
6217 */ 6195 */
6218 6196
6219 /* Check the ATA_DFLAG_CDB_INTR flag is enough here. 6197 /* Check the ATA_DFLAG_CDB_INTR flag is enough here.
6220 * The flag was turned on only for atapi devices. 6198 * The flag was turned on only for atapi devices. No
6221 * No need to check is_atapi_taskfile(&qc->tf) again. 6199 * need to check ata_is_atapi(qc->tf.protocol) again.
6222 */ 6200 */
6223 if (!(qc->dev->flags & ATA_DFLAG_CDB_INTR)) 6201 if (!(qc->dev->flags & ATA_DFLAG_CDB_INTR))
6224 goto idle_irq; 6202 goto idle_irq;
diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c
index d015b4adcfe0..a3c33f165427 100644
--- a/drivers/ata/sata_fsl.c
+++ b/drivers/ata/sata_fsl.c
@@ -417,7 +417,7 @@ static void sata_fsl_qc_prep(struct ata_queued_cmd *qc)
417 } 417 }
418 418
419 /* setup "ACMD - atapi command" in cmd. desc. if this is ATAPI cmd */ 419 /* setup "ACMD - atapi command" in cmd. desc. if this is ATAPI cmd */
420 if (is_atapi_taskfile(&qc->tf)) { 420 if (ata_is_atapi(qc->tf.protocol)) {
421 desc_info |= ATAPI_CMD; 421 desc_info |= ATAPI_CMD;
422 memset((void *)&cd->acmd, 0, 32); 422 memset((void *)&cd->acmd, 0, 32);
423 memcpy((void *)&cd->acmd, qc->cdb, qc->dev->cdb_len); 423 memcpy((void *)&cd->acmd, qc->cdb, qc->dev->cdb_len);
diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c
index f5119bf40c24..0b8191b52f97 100644
--- a/drivers/ata/sata_sil.c
+++ b/drivers/ata/sata_sil.c
@@ -416,15 +416,14 @@ static void sil_host_intr(struct ata_port *ap, u32 bmdma2)
416 */ 416 */
417 417
418 /* Check the ATA_DFLAG_CDB_INTR flag is enough here. 418 /* Check the ATA_DFLAG_CDB_INTR flag is enough here.
419 * The flag was turned on only for atapi devices. 419 * The flag was turned on only for atapi devices. No
420 * No need to check is_atapi_taskfile(&qc->tf) again. 420 * need to check ata_is_atapi(qc->tf.protocol) again.
421 */ 421 */
422 if (!(qc->dev->flags & ATA_DFLAG_CDB_INTR)) 422 if (!(qc->dev->flags & ATA_DFLAG_CDB_INTR))
423 goto err_hsm; 423 goto err_hsm;
424 break; 424 break;
425 case HSM_ST_LAST: 425 case HSM_ST_LAST:
426 if (qc->tf.protocol == ATA_PROT_DMA || 426 if (ata_is_dma(qc->tf.protocol)) {
427 qc->tf.protocol == ATA_PROT_ATAPI_DMA) {
428 /* clear DMA-Start bit */ 427 /* clear DMA-Start bit */
429 ap->ops->bmdma_stop(qc); 428 ap->ops->bmdma_stop(qc);
430 429
@@ -451,8 +450,7 @@ static void sil_host_intr(struct ata_port *ap, u32 bmdma2)
451 /* kick HSM in the ass */ 450 /* kick HSM in the ass */
452 ata_hsm_move(ap, qc, status, 0); 451 ata_hsm_move(ap, qc, status, 0);
453 452
454 if (unlikely(qc->err_mask) && (qc->tf.protocol == ATA_PROT_DMA || 453 if (unlikely(qc->err_mask) && ata_is_dma(qc->tf.protocol))
455 qc->tf.protocol == ATA_PROT_ATAPI_DMA))
456 ata_ehi_push_desc(ehi, "BMDMA2 stat 0x%x", bmdma2); 454 ata_ehi_push_desc(ehi, "BMDMA2 stat 0x%x", bmdma2);
457 455
458 return; 456 return;
diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c
index 864c1c1b8511..fdd3ceac329b 100644
--- a/drivers/ata/sata_sil24.c
+++ b/drivers/ata/sata_sil24.c
@@ -852,9 +852,7 @@ static int sil24_qc_defer(struct ata_queued_cmd *qc)
852 * set. 852 * set.
853 * 853 *
854 */ 854 */
855 int is_excl = (prot == ATA_PROT_ATAPI || 855 int is_excl = (ata_is_atapi(prot) ||
856 prot == ATA_PROT_ATAPI_NODATA ||
857 prot == ATA_PROT_ATAPI_DMA ||
858 (qc->flags & ATA_QCFLAG_RESULT_TF)); 856 (qc->flags & ATA_QCFLAG_RESULT_TF));
859 857
860 if (unlikely(ap->excl_link)) { 858 if (unlikely(ap->excl_link)) {
@@ -885,35 +883,21 @@ static void sil24_qc_prep(struct ata_queued_cmd *qc)
885 883
886 cb = &pp->cmd_block[sil24_tag(qc->tag)]; 884 cb = &pp->cmd_block[sil24_tag(qc->tag)];
887 885
888 switch (qc->tf.protocol) { 886 if (!ata_is_atapi(qc->tf.protocol)) {
889 case ATA_PROT_PIO:
890 case ATA_PROT_DMA:
891 case ATA_PROT_NCQ:
892 case ATA_PROT_NODATA:
893 prb = &cb->ata.prb; 887 prb = &cb->ata.prb;
894 sge = cb->ata.sge; 888 sge = cb->ata.sge;
895 break; 889 } else {
896
897 case ATA_PROT_ATAPI:
898 case ATA_PROT_ATAPI_DMA:
899 case ATA_PROT_ATAPI_NODATA:
900 prb = &cb->atapi.prb; 890 prb = &cb->atapi.prb;
901 sge = cb->atapi.sge; 891 sge = cb->atapi.sge;
902 memset(cb->atapi.cdb, 0, 32); 892 memset(cb->atapi.cdb, 0, 32);
903 memcpy(cb->atapi.cdb, qc->cdb, qc->dev->cdb_len); 893 memcpy(cb->atapi.cdb, qc->cdb, qc->dev->cdb_len);
904 894
905 if (qc->tf.protocol != ATA_PROT_ATAPI_NODATA) { 895 if (ata_is_data(qc->tf.protocol)) {
906 if (qc->tf.flags & ATA_TFLAG_WRITE) 896 if (qc->tf.flags & ATA_TFLAG_WRITE)
907 ctrl = PRB_CTRL_PACKET_WRITE; 897 ctrl = PRB_CTRL_PACKET_WRITE;
908 else 898 else
909 ctrl = PRB_CTRL_PACKET_READ; 899 ctrl = PRB_CTRL_PACKET_READ;
910 } 900 }
911 break;
912
913 default:
914 prb = NULL; /* shut up, gcc */
915 sge = NULL;
916 BUG();
917 } 901 }
918 902
919 prb->ctrl = cpu_to_le16(ctrl); 903 prb->ctrl = cpu_to_le16(ctrl);
diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c
index 0829b55c64d2..831294de1d8d 100644
--- a/drivers/scsi/libsas/sas_ata.c
+++ b/drivers/scsi/libsas/sas_ata.c
@@ -176,7 +176,7 @@ static unsigned int sas_ata_qc_issue(struct ata_queued_cmd *qc)
176 176
177 ata_tf_to_fis(&qc->tf, 1, 0, (u8*)&task->ata_task.fis); 177 ata_tf_to_fis(&qc->tf, 1, 0, (u8*)&task->ata_task.fis);
178 task->uldd_task = qc; 178 task->uldd_task = qc;
179 if (is_atapi_taskfile(&qc->tf)) { 179 if (ata_is_atapi(qc->tf.protocol)) {
180 memcpy(task->ata_task.atapi_packet, qc->cdb, qc->dev->cdb_len); 180 memcpy(task->ata_task.atapi_packet, qc->cdb, qc->dev->cdb_len);
181 task->total_xfer_len = qc->nbytes + qc->pad_len; 181 task->total_xfer_len = qc->nbytes + qc->pad_len;
182 task->num_scatter = qc->pad_len ? qc->n_elem + 1 : qc->n_elem; 182 task->num_scatter = qc->pad_len ? qc->n_elem + 1 : qc->n_elem;
diff --git a/include/linux/ata.h b/include/linux/ata.h
index 3fbe6d7784ab..43fecf62773a 100644
--- a/include/linux/ata.h
+++ b/include/linux/ata.h
@@ -324,6 +324,13 @@ enum {
324 ATA_TFLAG_LBA = (1 << 4), /* enable LBA */ 324 ATA_TFLAG_LBA = (1 << 4), /* enable LBA */
325 ATA_TFLAG_FUA = (1 << 5), /* enable FUA */ 325 ATA_TFLAG_FUA = (1 << 5), /* enable FUA */
326 ATA_TFLAG_POLLING = (1 << 6), /* set nIEN to 1 and use polling */ 326 ATA_TFLAG_POLLING = (1 << 6), /* set nIEN to 1 and use polling */
327
328 /* protocol flags */
329 ATA_PROT_FLAG_PIO = (1 << 0), /* is PIO */
330 ATA_PROT_FLAG_DMA = (1 << 1), /* is DMA */
331 ATA_PROT_FLAG_DATA = ATA_PROT_FLAG_PIO | ATA_PROT_FLAG_DMA,
332 ATA_PROT_FLAG_NCQ = (1 << 2), /* is NCQ */
333 ATA_PROT_FLAG_ATAPI = (1 << 3), /* is ATAPI */
327}; 334};
328 335
329enum ata_tf_protocols { 336enum ata_tf_protocols {
@@ -373,6 +380,63 @@ struct ata_taskfile {
373 u8 command; /* IO operation */ 380 u8 command; /* IO operation */
374}; 381};
375 382
383/*
384 * protocol tests
385 */
386static inline unsigned int ata_prot_flags(u8 prot)
387{
388 switch (prot) {
389 case ATA_PROT_NODATA:
390 return 0;
391 case ATA_PROT_PIO:
392 return ATA_PROT_FLAG_PIO;
393 case ATA_PROT_DMA:
394 return ATA_PROT_FLAG_DMA;
395 case ATA_PROT_NCQ:
396 return ATA_PROT_FLAG_DMA | ATA_PROT_FLAG_NCQ;
397 case ATA_PROT_ATAPI_NODATA:
398 return ATA_PROT_FLAG_ATAPI;
399 case ATA_PROT_ATAPI:
400 return ATA_PROT_FLAG_ATAPI | ATA_PROT_FLAG_PIO;
401 case ATA_PROT_ATAPI_DMA:
402 return ATA_PROT_FLAG_ATAPI | ATA_PROT_FLAG_DMA;
403 }
404 return 0;
405}
406
407static inline int ata_is_atapi(u8 prot)
408{
409 return ata_prot_flags(prot) & ATA_PROT_FLAG_ATAPI;
410}
411
412static inline int ata_is_nodata(u8 prot)
413{
414 return !(ata_prot_flags(prot) & ATA_PROT_FLAG_DATA);
415}
416
417static inline int ata_is_pio(u8 prot)
418{
419 return ata_prot_flags(prot) & ATA_PROT_FLAG_PIO;
420}
421
422static inline int ata_is_dma(u8 prot)
423{
424 return ata_prot_flags(prot) & ATA_PROT_FLAG_DMA;
425}
426
427static inline int ata_is_ncq(u8 prot)
428{
429 return ata_prot_flags(prot) & ATA_PROT_FLAG_NCQ;
430}
431
432static inline int ata_is_data(u8 prot)
433{
434 return ata_prot_flags(prot) & ATA_PROT_FLAG_DATA;
435}
436
437/*
438 * id tests
439 */
376#define ata_id_is_ata(id) (((id)[0] & (1 << 15)) == 0) 440#define ata_id_is_ata(id) (((id)[0] & (1 << 15)) == 0)
377#define ata_id_has_lba(id) ((id)[49] & (1 << 9)) 441#define ata_id_has_lba(id) ((id)[49] & (1 << 9))
378#define ata_id_has_dma(id) ((id)[49] & (1 << 8)) 442#define ata_id_has_dma(id) ((id)[49] & (1 << 8))
@@ -594,13 +658,6 @@ static inline int atapi_command_packet_set(const u16 *dev_id)
594 return (dev_id[0] >> 8) & 0x1f; 658 return (dev_id[0] >> 8) & 0x1f;
595} 659}
596 660
597static inline int is_atapi_taskfile(const struct ata_taskfile *tf)
598{
599 return (tf->protocol == ATA_PROT_ATAPI) ||
600 (tf->protocol == ATA_PROT_ATAPI_NODATA) ||
601 (tf->protocol == ATA_PROT_ATAPI_DMA);
602}
603
604static inline int is_multi_taskfile(struct ata_taskfile *tf) 661static inline int is_multi_taskfile(struct ata_taskfile *tf)
605{ 662{
606 return (tf->command == ATA_CMD_READ_MULTI) || 663 return (tf->command == ATA_CMD_READ_MULTI) ||