aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Cox <alan@lxorguk.ukuu.org.uk>2009-04-09 12:31:17 -0400
committerJeff Garzik <jgarzik@redhat.com>2009-04-16 15:28:23 -0400
commite3cf95dd6d352954b663d2934110d6e30af2406d (patch)
treef3245e91c30e0c1e12a169af637373a8b5ff670a
parent62afe5d744047df8ff15a369f4c1ebad71c937d4 (diff)
ata: Report 16/32bit PIO as best we can
The legacy old IDE ioctl API for this is a bit primitive so we try and map stuff sensibly onto it. - Set PIO over DMA devices to report 32bit - Add ability to change the PIO32 settings if the controller permits it - Add that functionality into the sff drivers - Add that functionality into the VLB legacy driver - Turn on the 32bit PIO on the ninja32 and add support there Signed-off-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
-rw-r--r--drivers/ata/libata-scsi.c30
-rw-r--r--drivers/ata/libata-sff.c27
-rw-r--r--drivers/ata/pata_legacy.c33
-rw-r--r--drivers/ata/pata_ninja32.c4
-rw-r--r--include/linux/libata.h8
5 files changed, 84 insertions, 18 deletions
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index b9747fa59e54..2733b0c90b75 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -647,23 +647,45 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg)
647 return rc; 647 return rc;
648} 648}
649 649
650static int ata_ioc32(struct ata_port *ap)
651{
652 if (ap->flags & ATA_FLAG_PIO_DMA)
653 return 1;
654 if (ap->pflags & ATA_PFLAG_PIO32)
655 return 1;
656 return 0;
657}
658
650int ata_sas_scsi_ioctl(struct ata_port *ap, struct scsi_device *scsidev, 659int ata_sas_scsi_ioctl(struct ata_port *ap, struct scsi_device *scsidev,
651 int cmd, void __user *arg) 660 int cmd, void __user *arg)
652{ 661{
653 int val = -EINVAL, rc = -EINVAL; 662 int val = -EINVAL, rc = -EINVAL;
663 unsigned long flags;
654 664
655 switch (cmd) { 665 switch (cmd) {
656 case ATA_IOC_GET_IO32: 666 case ATA_IOC_GET_IO32:
657 val = 0; 667 spin_lock_irqsave(ap->lock, flags);
668 val = ata_ioc32(ap);
669 spin_unlock_irqrestore(ap->lock, flags);
658 if (copy_to_user(arg, &val, 1)) 670 if (copy_to_user(arg, &val, 1))
659 return -EFAULT; 671 return -EFAULT;
660 return 0; 672 return 0;
661 673
662 case ATA_IOC_SET_IO32: 674 case ATA_IOC_SET_IO32:
663 val = (unsigned long) arg; 675 val = (unsigned long) arg;
664 if (val != 0) 676 rc = 0;
665 return -EINVAL; 677 spin_lock_irqsave(ap->lock, flags);
666 return 0; 678 if (ap->pflags & ATA_PFLAG_PIO32CHANGE) {
679 if (val)
680 ap->pflags |= ATA_PFLAG_PIO32;
681 else
682 ap->pflags &= ~ATA_PFLAG_PIO32;
683 } else {
684 if (val != ata_ioc32(ap))
685 rc = -EINVAL;
686 }
687 spin_unlock_irqrestore(ap->lock, flags);
688 return rc;
667 689
668 case HDIO_GET_IDENTITY: 690 case HDIO_GET_IDENTITY:
669 return ata_get_identity(ap, scsidev, arg); 691 return ata_get_identity(ap, scsidev, arg);
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index 8332e97a9de3..bb18415d3d63 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -87,6 +87,7 @@ const struct ata_port_operations ata_bmdma32_port_ops = {
87 .inherits = &ata_bmdma_port_ops, 87 .inherits = &ata_bmdma_port_ops,
88 88
89 .sff_data_xfer = ata_sff_data_xfer32, 89 .sff_data_xfer = ata_sff_data_xfer32,
90 .port_start = ata_sff_port_start32,
90}; 91};
91EXPORT_SYMBOL_GPL(ata_bmdma32_port_ops); 92EXPORT_SYMBOL_GPL(ata_bmdma32_port_ops);
92 93
@@ -769,6 +770,9 @@ unsigned int ata_sff_data_xfer32(struct ata_device *dev, unsigned char *buf,
769 void __iomem *data_addr = ap->ioaddr.data_addr; 770 void __iomem *data_addr = ap->ioaddr.data_addr;
770 unsigned int words = buflen >> 2; 771 unsigned int words = buflen >> 2;
771 int slop = buflen & 3; 772 int slop = buflen & 3;
773
774 if (!(ap->pflags & ATA_PFLAG_PIO32))
775 return ata_sff_data_xfer(dev, buf, buflen, rw);
772 776
773 /* Transfer multiple of 4 bytes */ 777 /* Transfer multiple of 4 bytes */
774 if (rw == READ) 778 if (rw == READ)
@@ -2402,6 +2406,29 @@ int ata_sff_port_start(struct ata_port *ap)
2402EXPORT_SYMBOL_GPL(ata_sff_port_start); 2406EXPORT_SYMBOL_GPL(ata_sff_port_start);
2403 2407
2404/** 2408/**
2409 * ata_sff_port_start32 - Set port up for dma.
2410 * @ap: Port to initialize
2411 *
2412 * Called just after data structures for each port are
2413 * initialized. Allocates space for PRD table if the device
2414 * is DMA capable SFF.
2415 *
2416 * May be used as the port_start() entry in ata_port_operations for
2417 * devices that are capable of 32bit PIO.
2418 *
2419 * LOCKING:
2420 * Inherited from caller.
2421 */
2422int ata_sff_port_start32(struct ata_port *ap)
2423{
2424 ap->pflags |= ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE;
2425 if (ap->ioaddr.bmdma_addr)
2426 return ata_port_start(ap);
2427 return 0;
2428}
2429EXPORT_SYMBOL_GPL(ata_sff_port_start32);
2430
2431/**
2405 * ata_sff_std_ports - initialize ioaddr with standard port offsets. 2432 * ata_sff_std_ports - initialize ioaddr with standard port offsets.
2406 * @ioaddr: IO address structure to be initialized 2433 * @ioaddr: IO address structure to be initialized
2407 * 2434 *
diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c
index 0c6dde80417b..6f985bed8cbb 100644
--- a/drivers/ata/pata_legacy.c
+++ b/drivers/ata/pata_legacy.c
@@ -108,6 +108,7 @@ struct legacy_controller {
108 struct ata_port_operations *ops; 108 struct ata_port_operations *ops;
109 unsigned int pio_mask; 109 unsigned int pio_mask;
110 unsigned int flags; 110 unsigned int flags;
111 unsigned int pflags;
111 int (*setup)(struct platform_device *, struct legacy_probe *probe, 112 int (*setup)(struct platform_device *, struct legacy_probe *probe,
112 struct legacy_data *data); 113 struct legacy_data *data);
113}; 114};
@@ -285,7 +286,8 @@ static unsigned int pdc_data_xfer_vlb(struct ata_device *dev,
285{ 286{
286 int slop = buflen & 3; 287 int slop = buflen & 3;
287 /* 32bit I/O capable *and* we need to write a whole number of dwords */ 288 /* 32bit I/O capable *and* we need to write a whole number of dwords */
288 if (ata_id_has_dword_io(dev->id) && (slop == 0 || slop == 3)) { 289 if (ata_id_has_dword_io(dev->id) && (slop == 0 || slop == 3)
290 && (ap->pflags & ATA_PFLAG_PIO32)) {
289 struct ata_port *ap = dev->link->ap; 291 struct ata_port *ap = dev->link->ap;
290 unsigned long flags; 292 unsigned long flags;
291 293
@@ -736,7 +738,8 @@ static unsigned int vlb32_data_xfer(struct ata_device *adev, unsigned char *buf,
736 struct ata_port *ap = adev->link->ap; 738 struct ata_port *ap = adev->link->ap;
737 int slop = buflen & 3; 739 int slop = buflen & 3;
738 740
739 if (ata_id_has_dword_io(adev->id) && (slop == 0 || slop == 3)) { 741 if (ata_id_has_dword_io(adev->id) && (slop == 0 || slop == 3)
742 && (ap->pflags & ATA_PFLAG_PIO32)) {
740 if (rw == WRITE) 743 if (rw == WRITE)
741 iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2); 744 iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2);
742 else 745 else
@@ -858,27 +861,30 @@ static struct ata_port_operations winbond_port_ops = {
858 861
859static struct legacy_controller controllers[] = { 862static struct legacy_controller controllers[] = {
860 {"BIOS", &legacy_port_ops, 0x1F, 863 {"BIOS", &legacy_port_ops, 0x1F,
861 ATA_FLAG_NO_IORDY, NULL }, 864 ATA_FLAG_NO_IORDY, 0, NULL },
862 {"Snooping", &simple_port_ops, 0x1F, 865 {"Snooping", &simple_port_ops, 0x1F,
863 0 , NULL }, 866 0, 0, NULL },
864 {"PDC20230", &pdc20230_port_ops, 0x7, 867 {"PDC20230", &pdc20230_port_ops, 0x7,
865 ATA_FLAG_NO_IORDY, NULL }, 868 ATA_FLAG_NO_IORDY,
869 ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32_CHANGE, NULL },
866 {"HT6560A", &ht6560a_port_ops, 0x07, 870 {"HT6560A", &ht6560a_port_ops, 0x07,
867 ATA_FLAG_NO_IORDY, NULL }, 871 ATA_FLAG_NO_IORDY, 0, NULL },
868 {"HT6560B", &ht6560b_port_ops, 0x1F, 872 {"HT6560B", &ht6560b_port_ops, 0x1F,
869 ATA_FLAG_NO_IORDY, NULL }, 873 ATA_FLAG_NO_IORDY, 0, NULL },
870 {"OPTI82C611A", &opti82c611a_port_ops, 0x0F, 874 {"OPTI82C611A", &opti82c611a_port_ops, 0x0F,
871 0 , NULL }, 875 0, 0, NULL },
872 {"OPTI82C46X", &opti82c46x_port_ops, 0x0F, 876 {"OPTI82C46X", &opti82c46x_port_ops, 0x0F,
873 0 , NULL }, 877 0, 0, NULL },
874 {"QDI6500", &qdi6500_port_ops, 0x07, 878 {"QDI6500", &qdi6500_port_ops, 0x07,
875 ATA_FLAG_NO_IORDY, qdi_port }, 879 ATA_FLAG_NO_IORDY,
880 ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32_CHANGE, qdi_port },
876 {"QDI6580", &qdi6580_port_ops, 0x1F, 881 {"QDI6580", &qdi6580_port_ops, 0x1F,
877 0 , qdi_port }, 882 0, ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32_CHANGE, qdi_port },
878 {"QDI6580DP", &qdi6580dp_port_ops, 0x1F, 883 {"QDI6580DP", &qdi6580dp_port_ops, 0x1F,
879 0 , qdi_port }, 884 0, ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32_CHANGE, qdi_port },
880 {"W83759A", &winbond_port_ops, 0x1F, 885 {"W83759A", &winbond_port_ops, 0x1F,
881 0 , winbond_port } 886 0, ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32_CHANGE,
887 winbond_port }
882}; 888};
883 889
884/** 890/**
@@ -1008,6 +1014,7 @@ static __init int legacy_init_one(struct legacy_probe *probe)
1008 ap->ops = ops; 1014 ap->ops = ops;
1009 ap->pio_mask = pio_modes; 1015 ap->pio_mask = pio_modes;
1010 ap->flags |= ATA_FLAG_SLAVE_POSS | iordy; 1016 ap->flags |= ATA_FLAG_SLAVE_POSS | iordy;
1017 ap->pflags |= controller->pflags;
1011 ap->ioaddr.cmd_addr = io_addr; 1018 ap->ioaddr.cmd_addr = io_addr;
1012 ap->ioaddr.altstatus_addr = ctrl_addr; 1019 ap->ioaddr.altstatus_addr = ctrl_addr;
1013 ap->ioaddr.ctl_addr = ctrl_addr; 1020 ap->ioaddr.ctl_addr = ctrl_addr;
diff --git a/drivers/ata/pata_ninja32.c b/drivers/ata/pata_ninja32.c
index 0fb6b1b1e634..dd53a66b19e3 100644
--- a/drivers/ata/pata_ninja32.c
+++ b/drivers/ata/pata_ninja32.c
@@ -44,7 +44,7 @@
44#include <linux/libata.h> 44#include <linux/libata.h>
45 45
46#define DRV_NAME "pata_ninja32" 46#define DRV_NAME "pata_ninja32"
47#define DRV_VERSION "0.1.3" 47#define DRV_VERSION "0.1.5"
48 48
49 49
50/** 50/**
@@ -86,6 +86,7 @@ static struct ata_port_operations ninja32_port_ops = {
86 .sff_dev_select = ninja32_dev_select, 86 .sff_dev_select = ninja32_dev_select,
87 .cable_detect = ata_cable_40wire, 87 .cable_detect = ata_cable_40wire,
88 .set_piomode = ninja32_set_piomode, 88 .set_piomode = ninja32_set_piomode,
89 .sff_data_xfer = ata_sff_data_xfer32
89}; 90};
90 91
91static void ninja32_program(void __iomem *base) 92static void ninja32_program(void __iomem *base)
@@ -144,6 +145,7 @@ static int ninja32_init_one(struct pci_dev *dev, const struct pci_device_id *id)
144 ap->ioaddr.altstatus_addr = base + 0x1E; 145 ap->ioaddr.altstatus_addr = base + 0x1E;
145 ap->ioaddr.bmdma_addr = base; 146 ap->ioaddr.bmdma_addr = base;
146 ata_sff_std_ports(&ap->ioaddr); 147 ata_sff_std_ports(&ap->ioaddr);
148 ap->pflags = ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE;
147 149
148 ninja32_program(base); 150 ninja32_program(base);
149 /* FIXME: Should we disable them at remove ? */ 151 /* FIXME: Should we disable them at remove ? */
diff --git a/include/linux/libata.h b/include/linux/libata.h
index b450a2628855..3d501db36a26 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -209,6 +209,7 @@ enum {
209 209
210 /* bits 24:31 of ap->flags are reserved for LLD specific flags */ 210 /* bits 24:31 of ap->flags are reserved for LLD specific flags */
211 211
212
212 /* struct ata_port pflags */ 213 /* struct ata_port pflags */
213 ATA_PFLAG_EH_PENDING = (1 << 0), /* EH pending */ 214 ATA_PFLAG_EH_PENDING = (1 << 0), /* EH pending */
214 ATA_PFLAG_EH_IN_PROGRESS = (1 << 1), /* EH in progress */ 215 ATA_PFLAG_EH_IN_PROGRESS = (1 << 1), /* EH in progress */
@@ -225,6 +226,9 @@ enum {
225 ATA_PFLAG_PM_PENDING = (1 << 18), /* PM operation pending */ 226 ATA_PFLAG_PM_PENDING = (1 << 18), /* PM operation pending */
226 ATA_PFLAG_INIT_GTM_VALID = (1 << 19), /* initial gtm data valid */ 227 ATA_PFLAG_INIT_GTM_VALID = (1 << 19), /* initial gtm data valid */
227 228
229 ATA_PFLAG_PIO32 = (1 << 20), /* 32bit PIO */
230 ATA_PFLAG_PIO32CHANGE = (1 << 21), /* 32bit PIO can be turned on/off */
231
228 /* struct ata_queued_cmd flags */ 232 /* struct ata_queued_cmd flags */
229 ATA_QCFLAG_ACTIVE = (1 << 0), /* cmd not yet ack'd to scsi lyer */ 233 ATA_QCFLAG_ACTIVE = (1 << 0), /* cmd not yet ack'd to scsi lyer */
230 ATA_QCFLAG_DMAMAP = (1 << 1), /* SG table is DMA mapped */ 234 ATA_QCFLAG_DMAMAP = (1 << 1), /* SG table is DMA mapped */
@@ -689,7 +693,10 @@ struct ata_port {
689 struct Scsi_Host *scsi_host; /* our co-allocated scsi host */ 693 struct Scsi_Host *scsi_host; /* our co-allocated scsi host */
690 struct ata_port_operations *ops; 694 struct ata_port_operations *ops;
691 spinlock_t *lock; 695 spinlock_t *lock;
696 /* Flags owned by the EH context. Only EH should touch these once the
697 port is active */
692 unsigned long flags; /* ATA_FLAG_xxx */ 698 unsigned long flags; /* ATA_FLAG_xxx */
699 /* Flags that change dynamically, protected by ap->lock */
693 unsigned int pflags; /* ATA_PFLAG_xxx */ 700 unsigned int pflags; /* ATA_PFLAG_xxx */
694 unsigned int print_id; /* user visible unique port ID */ 701 unsigned int print_id; /* user visible unique port ID */
695 unsigned int port_no; /* 0 based port no. inside the host */ 702 unsigned int port_no; /* 0 based port no. inside the host */
@@ -1595,6 +1602,7 @@ extern void ata_sff_drain_fifo(struct ata_queued_cmd *qc);
1595extern void ata_sff_error_handler(struct ata_port *ap); 1602extern void ata_sff_error_handler(struct ata_port *ap);
1596extern void ata_sff_post_internal_cmd(struct ata_queued_cmd *qc); 1603extern void ata_sff_post_internal_cmd(struct ata_queued_cmd *qc);
1597extern int ata_sff_port_start(struct ata_port *ap); 1604extern int ata_sff_port_start(struct ata_port *ap);
1605extern int ata_sff_port_start32(struct ata_port *ap);
1598extern void ata_sff_std_ports(struct ata_ioports *ioaddr); 1606extern void ata_sff_std_ports(struct ata_ioports *ioaddr);
1599extern unsigned long ata_bmdma_mode_filter(struct ata_device *dev, 1607extern unsigned long ata_bmdma_mode_filter(struct ata_device *dev,
1600 unsigned long xfer_mask); 1608 unsigned long xfer_mask);