diff options
-rw-r--r-- | Documentation/DocBook/libata.tmpl | 47 | ||||
-rw-r--r-- | drivers/scsi/libata-core.c | 31 | ||||
-rw-r--r-- | include/linux/libata.h | 4 |
3 files changed, 76 insertions, 6 deletions
diff --git a/Documentation/DocBook/libata.tmpl b/Documentation/DocBook/libata.tmpl index d260d92089ad..5bcbb6ee3bc0 100644 --- a/Documentation/DocBook/libata.tmpl +++ b/Documentation/DocBook/libata.tmpl | |||
@@ -120,14 +120,27 @@ void (*dev_config) (struct ata_port *, struct ata_device *); | |||
120 | <programlisting> | 120 | <programlisting> |
121 | void (*set_piomode) (struct ata_port *, struct ata_device *); | 121 | void (*set_piomode) (struct ata_port *, struct ata_device *); |
122 | void (*set_dmamode) (struct ata_port *, struct ata_device *); | 122 | void (*set_dmamode) (struct ata_port *, struct ata_device *); |
123 | void (*post_set_mode) (struct ata_port *ap); | 123 | void (*post_set_mode) (struct ata_port *); |
124 | unsigned int (*mode_filter) (struct ata_port *, struct ata_device *, unsigned int); | ||
124 | </programlisting> | 125 | </programlisting> |
125 | 126 | ||
126 | <para> | 127 | <para> |
127 | Hooks called prior to the issue of SET FEATURES - XFER MODE | 128 | Hooks called prior to the issue of SET FEATURES - XFER MODE |
128 | command. dev->pio_mode is guaranteed to be valid when | 129 | command. The optional ->mode_filter() hook is called when libata |
129 | ->set_piomode() is called, and dev->dma_mode is guaranteed to be | 130 | has built a mask of the possible modes. This is passed to the |
130 | valid when ->set_dmamode() is called. ->post_set_mode() is | 131 | ->mode_filter() function which should return a mask of valid modes |
132 | after filtering those unsuitable due to hardware limits. It is not | ||
133 | valid to use this interface to add modes. | ||
134 | </para> | ||
135 | <para> | ||
136 | dev->pio_mode and dev->dma_mode are guaranteed to be valid when | ||
137 | ->set_piomode() and when ->set_dmamode() is called. The timings for | ||
138 | any other drive sharing the cable will also be valid at this point. | ||
139 | That is the library records the decisions for the modes of each | ||
140 | drive on a channel before it attempts to set any of them. | ||
141 | </para> | ||
142 | <para> | ||
143 | ->post_set_mode() is | ||
131 | called unconditionally, after the SET FEATURES - XFER MODE | 144 | called unconditionally, after the SET FEATURES - XFER MODE |
132 | command completes successfully. | 145 | command completes successfully. |
133 | </para> | 146 | </para> |
@@ -230,6 +243,32 @@ void (*dev_select)(struct ata_port *ap, unsigned int device); | |||
230 | 243 | ||
231 | </sect2> | 244 | </sect2> |
232 | 245 | ||
246 | <sect2><title>Private tuning method</title> | ||
247 | <programlisting> | ||
248 | void (*set_mode) (struct ata_port *ap); | ||
249 | </programlisting> | ||
250 | |||
251 | <para> | ||
252 | By default libata performs drive and controller tuning in | ||
253 | accordance with the ATA timing rules and also applies blacklists | ||
254 | and cable limits. Some controllers need special handling and have | ||
255 | custom tuning rules, typically raid controllers that use ATA | ||
256 | commands but do not actually do drive timing. | ||
257 | </para> | ||
258 | |||
259 | <warning> | ||
260 | <para> | ||
261 | This hook should not be used to replace the standard controller | ||
262 | tuning logic when a controller has quirks. Replacing the default | ||
263 | tuning logic in that case would bypass handling for drive and | ||
264 | bridge quirks that may be important to data reliability. If a | ||
265 | controller needs to filter the mode selection it should use the | ||
266 | mode_filter hook instead. | ||
267 | </para> | ||
268 | </warning> | ||
269 | |||
270 | </sect2> | ||
271 | |||
233 | <sect2><title>Reset ATA bus</title> | 272 | <sect2><title>Reset ATA bus</title> |
234 | <programlisting> | 273 | <programlisting> |
235 | void (*phy_reset) (struct ata_port *ap); | 274 | void (*phy_reset) (struct ata_port *ap); |
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index 41659448a204..b1ddf40533b5 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c | |||
@@ -1818,7 +1818,7 @@ static void ata_host_set_dma(struct ata_port *ap) | |||
1818 | */ | 1818 | */ |
1819 | static void ata_set_mode(struct ata_port *ap) | 1819 | static void ata_set_mode(struct ata_port *ap) |
1820 | { | 1820 | { |
1821 | int i, rc; | 1821 | int i, rc, used_dma = 0; |
1822 | 1822 | ||
1823 | /* step 1: calculate xfer_mask */ | 1823 | /* step 1: calculate xfer_mask */ |
1824 | for (i = 0; i < ATA_MAX_DEVICES; i++) { | 1824 | for (i = 0; i < ATA_MAX_DEVICES; i++) { |
@@ -1836,6 +1836,9 @@ static void ata_set_mode(struct ata_port *ap) | |||
1836 | dma_mask = ata_pack_xfermask(0, dev->mwdma_mask, dev->udma_mask); | 1836 | dma_mask = ata_pack_xfermask(0, dev->mwdma_mask, dev->udma_mask); |
1837 | dev->pio_mode = ata_xfer_mask2mode(pio_mask); | 1837 | dev->pio_mode = ata_xfer_mask2mode(pio_mask); |
1838 | dev->dma_mode = ata_xfer_mask2mode(dma_mask); | 1838 | dev->dma_mode = ata_xfer_mask2mode(dma_mask); |
1839 | |||
1840 | if (dev->dma_mode) | ||
1841 | used_dma = 1; | ||
1839 | } | 1842 | } |
1840 | 1843 | ||
1841 | /* step 2: always set host PIO timings */ | 1844 | /* step 2: always set host PIO timings */ |
@@ -1857,6 +1860,17 @@ static void ata_set_mode(struct ata_port *ap) | |||
1857 | goto err_out; | 1860 | goto err_out; |
1858 | } | 1861 | } |
1859 | 1862 | ||
1863 | /* | ||
1864 | * Record simplex status. If we selected DMA then the other | ||
1865 | * host channels are not permitted to do so. | ||
1866 | */ | ||
1867 | |||
1868 | if (used_dma && (ap->host_set->flags & ATA_HOST_SIMPLEX)) | ||
1869 | ap->host_set->simplex_claimed = 1; | ||
1870 | |||
1871 | /* | ||
1872 | * Chip specific finalisation | ||
1873 | */ | ||
1860 | if (ap->ops->post_set_mode) | 1874 | if (ap->ops->post_set_mode) |
1861 | ap->ops->post_set_mode(ap); | 1875 | ap->ops->post_set_mode(ap); |
1862 | 1876 | ||
@@ -2646,13 +2660,14 @@ static int ata_dma_blacklisted(const struct ata_device *dev) | |||
2646 | */ | 2660 | */ |
2647 | static void ata_dev_xfermask(struct ata_port *ap, struct ata_device *dev) | 2661 | static void ata_dev_xfermask(struct ata_port *ap, struct ata_device *dev) |
2648 | { | 2662 | { |
2663 | struct ata_host_set *hs = ap->host_set; | ||
2649 | unsigned long xfer_mask; | 2664 | unsigned long xfer_mask; |
2650 | int i; | 2665 | int i; |
2651 | 2666 | ||
2652 | xfer_mask = ata_pack_xfermask(ap->pio_mask, ap->mwdma_mask, | 2667 | xfer_mask = ata_pack_xfermask(ap->pio_mask, ap->mwdma_mask, |
2653 | ap->udma_mask); | 2668 | ap->udma_mask); |
2654 | 2669 | ||
2655 | /* use port-wide xfermask for now */ | 2670 | /* FIXME: Use port-wide xfermask for now */ |
2656 | for (i = 0; i < ATA_MAX_DEVICES; i++) { | 2671 | for (i = 0; i < ATA_MAX_DEVICES; i++) { |
2657 | struct ata_device *d = &ap->device[i]; | 2672 | struct ata_device *d = &ap->device[i]; |
2658 | if (!ata_dev_present(d)) | 2673 | if (!ata_dev_present(d)) |
@@ -2662,12 +2677,23 @@ static void ata_dev_xfermask(struct ata_port *ap, struct ata_device *dev) | |||
2662 | xfer_mask &= ata_id_xfermask(d->id); | 2677 | xfer_mask &= ata_id_xfermask(d->id); |
2663 | if (ata_dma_blacklisted(d)) | 2678 | if (ata_dma_blacklisted(d)) |
2664 | xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA); | 2679 | xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA); |
2680 | /* Apply cable rule here. Don't apply it early because when | ||
2681 | we handle hot plug the cable type can itself change */ | ||
2682 | if (ap->cbl == ATA_CBL_PATA40) | ||
2683 | xfer_mask &= ~(0xF8 << ATA_SHIFT_UDMA); | ||
2665 | } | 2684 | } |
2666 | 2685 | ||
2667 | if (ata_dma_blacklisted(dev)) | 2686 | if (ata_dma_blacklisted(dev)) |
2668 | printk(KERN_WARNING "ata%u: dev %u is on DMA blacklist, " | 2687 | printk(KERN_WARNING "ata%u: dev %u is on DMA blacklist, " |
2669 | "disabling DMA\n", ap->id, dev->devno); | 2688 | "disabling DMA\n", ap->id, dev->devno); |
2670 | 2689 | ||
2690 | if (hs->flags & ATA_HOST_SIMPLEX) { | ||
2691 | if (hs->simplex_claimed) | ||
2692 | xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA); | ||
2693 | } | ||
2694 | if (ap->ops->mode_filter) | ||
2695 | xfer_mask = ap->ops->mode_filter(ap, dev, xfer_mask); | ||
2696 | |||
2671 | ata_unpack_xfermask(xfer_mask, &dev->pio_mask, &dev->mwdma_mask, | 2697 | ata_unpack_xfermask(xfer_mask, &dev->pio_mask, &dev->mwdma_mask, |
2672 | &dev->udma_mask); | 2698 | &dev->udma_mask); |
2673 | } | 2699 | } |
@@ -4531,6 +4557,7 @@ int ata_device_add(const struct ata_probe_ent *ent) | |||
4531 | host_set->mmio_base = ent->mmio_base; | 4557 | host_set->mmio_base = ent->mmio_base; |
4532 | host_set->private_data = ent->private_data; | 4558 | host_set->private_data = ent->private_data; |
4533 | host_set->ops = ent->port_ops; | 4559 | host_set->ops = ent->port_ops; |
4560 | host_set->flags = ent->host_set_flags; | ||
4534 | 4561 | ||
4535 | /* register each port bound to this device */ | 4562 | /* register each port bound to this device */ |
4536 | for (i = 0; i < ent->n_ports; i++) { | 4563 | for (i = 0; i < ent->n_ports; i++) { |
diff --git a/include/linux/libata.h b/include/linux/libata.h index 6a9316cbb70b..0d61357604d5 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h | |||
@@ -294,6 +294,9 @@ struct ata_host_set { | |||
294 | unsigned int n_ports; | 294 | unsigned int n_ports; |
295 | void *private_data; | 295 | void *private_data; |
296 | const struct ata_port_operations *ops; | 296 | const struct ata_port_operations *ops; |
297 | unsigned long flags; | ||
298 | int simplex_claimed; /* Keep seperate in case we | ||
299 | ever need to do this locked */ | ||
297 | struct ata_port * ports[0]; | 300 | struct ata_port * ports[0]; |
298 | }; | 301 | }; |
299 | 302 | ||
@@ -423,6 +426,7 @@ struct ata_port_operations { | |||
423 | 426 | ||
424 | void (*set_piomode) (struct ata_port *, struct ata_device *); | 427 | void (*set_piomode) (struct ata_port *, struct ata_device *); |
425 | void (*set_dmamode) (struct ata_port *, struct ata_device *); | 428 | void (*set_dmamode) (struct ata_port *, struct ata_device *); |
429 | unsigned long (*mode_filter) (const struct ata_port *, struct ata_device *, unsigned long); | ||
426 | 430 | ||
427 | void (*tf_load) (struct ata_port *ap, const struct ata_taskfile *tf); | 431 | void (*tf_load) (struct ata_port *ap, const struct ata_taskfile *tf); |
428 | void (*tf_read) (struct ata_port *ap, struct ata_taskfile *tf); | 432 | void (*tf_read) (struct ata_port *ap, struct ata_taskfile *tf); |