diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/ata/pata_legacy.c | 13 | ||||
-rw-r--r-- | drivers/ata/pata_via.c | 74 | ||||
-rw-r--r-- | drivers/ata/sata_mv.c | 58 |
3 files changed, 122 insertions, 23 deletions
diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c index 6f985bed8cbb..f72c6c5b820f 100644 --- a/drivers/ata/pata_legacy.c +++ b/drivers/ata/pata_legacy.c | |||
@@ -285,10 +285,11 @@ static unsigned int pdc_data_xfer_vlb(struct ata_device *dev, | |||
285 | unsigned char *buf, unsigned int buflen, int rw) | 285 | unsigned char *buf, unsigned int buflen, int rw) |
286 | { | 286 | { |
287 | int slop = buflen & 3; | 287 | int slop = buflen & 3; |
288 | struct ata_port *ap = dev->link->ap; | ||
289 | |||
288 | /* 32bit I/O capable *and* we need to write a whole number of dwords */ | 290 | /* 32bit I/O capable *and* we need to write a whole number of dwords */ |
289 | if (ata_id_has_dword_io(dev->id) && (slop == 0 || slop == 3) | 291 | if (ata_id_has_dword_io(dev->id) && (slop == 0 || slop == 3) |
290 | && (ap->pflags & ATA_PFLAG_PIO32)) { | 292 | && (ap->pflags & ATA_PFLAG_PIO32)) { |
291 | struct ata_port *ap = dev->link->ap; | ||
292 | unsigned long flags; | 293 | unsigned long flags; |
293 | 294 | ||
294 | local_irq_save(flags); | 295 | local_irq_save(flags); |
@@ -866,7 +867,7 @@ static struct legacy_controller controllers[] = { | |||
866 | 0, 0, NULL }, | 867 | 0, 0, NULL }, |
867 | {"PDC20230", &pdc20230_port_ops, 0x7, | 868 | {"PDC20230", &pdc20230_port_ops, 0x7, |
868 | ATA_FLAG_NO_IORDY, | 869 | ATA_FLAG_NO_IORDY, |
869 | ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32_CHANGE, NULL }, | 870 | ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE, NULL }, |
870 | {"HT6560A", &ht6560a_port_ops, 0x07, | 871 | {"HT6560A", &ht6560a_port_ops, 0x07, |
871 | ATA_FLAG_NO_IORDY, 0, NULL }, | 872 | ATA_FLAG_NO_IORDY, 0, NULL }, |
872 | {"HT6560B", &ht6560b_port_ops, 0x1F, | 873 | {"HT6560B", &ht6560b_port_ops, 0x1F, |
@@ -877,13 +878,13 @@ static struct legacy_controller controllers[] = { | |||
877 | 0, 0, NULL }, | 878 | 0, 0, NULL }, |
878 | {"QDI6500", &qdi6500_port_ops, 0x07, | 879 | {"QDI6500", &qdi6500_port_ops, 0x07, |
879 | ATA_FLAG_NO_IORDY, | 880 | ATA_FLAG_NO_IORDY, |
880 | ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32_CHANGE, qdi_port }, | 881 | ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE, qdi_port }, |
881 | {"QDI6580", &qdi6580_port_ops, 0x1F, | 882 | {"QDI6580", &qdi6580_port_ops, 0x1F, |
882 | 0, ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32_CHANGE, qdi_port }, | 883 | 0, ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE, qdi_port }, |
883 | {"QDI6580DP", &qdi6580dp_port_ops, 0x1F, | 884 | {"QDI6580DP", &qdi6580dp_port_ops, 0x1F, |
884 | 0, ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32_CHANGE, qdi_port }, | 885 | 0, ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE, qdi_port }, |
885 | {"W83759A", &winbond_port_ops, 0x1F, | 886 | {"W83759A", &winbond_port_ops, 0x1F, |
886 | 0, ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32_CHANGE, | 887 | 0, ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE, |
887 | winbond_port } | 888 | winbond_port } |
888 | }; | 889 | }; |
889 | 890 | ||
diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c index b08e6e0f82b6..45657cacec43 100644 --- a/drivers/ata/pata_via.c +++ b/drivers/ata/pata_via.c | |||
@@ -62,7 +62,7 @@ | |||
62 | #include <linux/dmi.h> | 62 | #include <linux/dmi.h> |
63 | 63 | ||
64 | #define DRV_NAME "pata_via" | 64 | #define DRV_NAME "pata_via" |
65 | #define DRV_VERSION "0.3.3" | 65 | #define DRV_VERSION "0.3.4" |
66 | 66 | ||
67 | /* | 67 | /* |
68 | * The following comes directly from Vojtech Pavlik's ide/pci/via82cxxx | 68 | * The following comes directly from Vojtech Pavlik's ide/pci/via82cxxx |
@@ -136,6 +136,9 @@ static const struct via_isa_bridge { | |||
136 | { NULL } | 136 | { NULL } |
137 | }; | 137 | }; |
138 | 138 | ||
139 | struct via_port { | ||
140 | u8 cached_device; | ||
141 | }; | ||
139 | 142 | ||
140 | /* | 143 | /* |
141 | * Cable special cases | 144 | * Cable special cases |
@@ -346,14 +349,70 @@ static void via_set_dmamode(struct ata_port *ap, struct ata_device *adev) | |||
346 | */ | 349 | */ |
347 | static void via_tf_load(struct ata_port *ap, const struct ata_taskfile *tf) | 350 | static void via_tf_load(struct ata_port *ap, const struct ata_taskfile *tf) |
348 | { | 351 | { |
349 | struct ata_taskfile tmp_tf; | 352 | struct ata_ioports *ioaddr = &ap->ioaddr; |
353 | struct via_port *vp = ap->private_data; | ||
354 | unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR; | ||
355 | int newctl = 0; | ||
356 | |||
357 | if (tf->ctl != ap->last_ctl) { | ||
358 | iowrite8(tf->ctl, ioaddr->ctl_addr); | ||
359 | ap->last_ctl = tf->ctl; | ||
360 | ata_wait_idle(ap); | ||
361 | newctl = 1; | ||
362 | } | ||
363 | |||
364 | if (tf->flags & ATA_TFLAG_DEVICE) { | ||
365 | iowrite8(tf->device, ioaddr->device_addr); | ||
366 | vp->cached_device = tf->device; | ||
367 | } else if (newctl) | ||
368 | iowrite8(vp->cached_device, ioaddr->device_addr); | ||
369 | |||
370 | if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) { | ||
371 | WARN_ON_ONCE(!ioaddr->ctl_addr); | ||
372 | iowrite8(tf->hob_feature, ioaddr->feature_addr); | ||
373 | iowrite8(tf->hob_nsect, ioaddr->nsect_addr); | ||
374 | iowrite8(tf->hob_lbal, ioaddr->lbal_addr); | ||
375 | iowrite8(tf->hob_lbam, ioaddr->lbam_addr); | ||
376 | iowrite8(tf->hob_lbah, ioaddr->lbah_addr); | ||
377 | VPRINTK("hob: feat 0x%X nsect 0x%X, lba 0x%X 0x%X 0x%X\n", | ||
378 | tf->hob_feature, | ||
379 | tf->hob_nsect, | ||
380 | tf->hob_lbal, | ||
381 | tf->hob_lbam, | ||
382 | tf->hob_lbah); | ||
383 | } | ||
350 | 384 | ||
351 | if (ap->ctl != ap->last_ctl && !(tf->flags & ATA_TFLAG_DEVICE)) { | 385 | if (is_addr) { |
352 | tmp_tf = *tf; | 386 | iowrite8(tf->feature, ioaddr->feature_addr); |
353 | tmp_tf.flags |= ATA_TFLAG_DEVICE; | 387 | iowrite8(tf->nsect, ioaddr->nsect_addr); |
354 | tf = &tmp_tf; | 388 | iowrite8(tf->lbal, ioaddr->lbal_addr); |
389 | iowrite8(tf->lbam, ioaddr->lbam_addr); | ||
390 | iowrite8(tf->lbah, ioaddr->lbah_addr); | ||
391 | VPRINTK("feat 0x%X nsect 0x%X lba 0x%X 0x%X 0x%X\n", | ||
392 | tf->feature, | ||
393 | tf->nsect, | ||
394 | tf->lbal, | ||
395 | tf->lbam, | ||
396 | tf->lbah); | ||
355 | } | 397 | } |
356 | ata_sff_tf_load(ap, tf); | 398 | |
399 | ata_wait_idle(ap); | ||
400 | } | ||
401 | |||
402 | static int via_port_start(struct ata_port *ap) | ||
403 | { | ||
404 | struct via_port *vp; | ||
405 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); | ||
406 | |||
407 | int ret = ata_sff_port_start(ap); | ||
408 | if (ret < 0) | ||
409 | return ret; | ||
410 | |||
411 | vp = devm_kzalloc(&pdev->dev, sizeof(struct via_port), GFP_KERNEL); | ||
412 | if (vp == NULL) | ||
413 | return -ENOMEM; | ||
414 | ap->private_data = vp; | ||
415 | return 0; | ||
357 | } | 416 | } |
358 | 417 | ||
359 | static struct scsi_host_template via_sht = { | 418 | static struct scsi_host_template via_sht = { |
@@ -367,6 +426,7 @@ static struct ata_port_operations via_port_ops = { | |||
367 | .set_dmamode = via_set_dmamode, | 426 | .set_dmamode = via_set_dmamode, |
368 | .prereset = via_pre_reset, | 427 | .prereset = via_pre_reset, |
369 | .sff_tf_load = via_tf_load, | 428 | .sff_tf_load = via_tf_load, |
429 | .port_start = via_port_start, | ||
370 | }; | 430 | }; |
371 | 431 | ||
372 | static struct ata_port_operations via_port_ops_noirq = { | 432 | static struct ata_port_operations via_port_ops_noirq = { |
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 37ae5dc1070c..870dcfd82357 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c | |||
@@ -1881,6 +1881,39 @@ static u8 mv_bmdma_status(struct ata_port *ap) | |||
1881 | return status; | 1881 | return status; |
1882 | } | 1882 | } |
1883 | 1883 | ||
1884 | static void mv_rw_multi_errata_sata24(struct ata_queued_cmd *qc) | ||
1885 | { | ||
1886 | struct ata_taskfile *tf = &qc->tf; | ||
1887 | /* | ||
1888 | * Workaround for 88SX60x1 FEr SATA#24. | ||
1889 | * | ||
1890 | * Chip may corrupt WRITEs if multi_count >= 4kB. | ||
1891 | * Note that READs are unaffected. | ||
1892 | * | ||
1893 | * It's not clear if this errata really means "4K bytes", | ||
1894 | * or if it always happens for multi_count > 7 | ||
1895 | * regardless of device sector_size. | ||
1896 | * | ||
1897 | * So, for safety, any write with multi_count > 7 | ||
1898 | * gets converted here into a regular PIO write instead: | ||
1899 | */ | ||
1900 | if ((tf->flags & ATA_TFLAG_WRITE) && is_multi_taskfile(tf)) { | ||
1901 | if (qc->dev->multi_count > 7) { | ||
1902 | switch (tf->command) { | ||
1903 | case ATA_CMD_WRITE_MULTI: | ||
1904 | tf->command = ATA_CMD_PIO_WRITE; | ||
1905 | break; | ||
1906 | case ATA_CMD_WRITE_MULTI_FUA_EXT: | ||
1907 | tf->flags &= ~ATA_TFLAG_FUA; /* ugh */ | ||
1908 | /* fall through */ | ||
1909 | case ATA_CMD_WRITE_MULTI_EXT: | ||
1910 | tf->command = ATA_CMD_PIO_WRITE_EXT; | ||
1911 | break; | ||
1912 | } | ||
1913 | } | ||
1914 | } | ||
1915 | } | ||
1916 | |||
1884 | /** | 1917 | /** |
1885 | * mv_qc_prep - Host specific command preparation. | 1918 | * mv_qc_prep - Host specific command preparation. |
1886 | * @qc: queued command to prepare | 1919 | * @qc: queued command to prepare |
@@ -1898,17 +1931,24 @@ static void mv_qc_prep(struct ata_queued_cmd *qc) | |||
1898 | struct ata_port *ap = qc->ap; | 1931 | struct ata_port *ap = qc->ap; |
1899 | struct mv_port_priv *pp = ap->private_data; | 1932 | struct mv_port_priv *pp = ap->private_data; |
1900 | __le16 *cw; | 1933 | __le16 *cw; |
1901 | struct ata_taskfile *tf; | 1934 | struct ata_taskfile *tf = &qc->tf; |
1902 | u16 flags = 0; | 1935 | u16 flags = 0; |
1903 | unsigned in_index; | 1936 | unsigned in_index; |
1904 | 1937 | ||
1905 | if ((qc->tf.protocol != ATA_PROT_DMA) && | 1938 | switch (tf->protocol) { |
1906 | (qc->tf.protocol != ATA_PROT_NCQ)) | 1939 | case ATA_PROT_DMA: |
1940 | case ATA_PROT_NCQ: | ||
1941 | break; /* continue below */ | ||
1942 | case ATA_PROT_PIO: | ||
1943 | mv_rw_multi_errata_sata24(qc); | ||
1944 | return; | ||
1945 | default: | ||
1907 | return; | 1946 | return; |
1947 | } | ||
1908 | 1948 | ||
1909 | /* Fill in command request block | 1949 | /* Fill in command request block |
1910 | */ | 1950 | */ |
1911 | if (!(qc->tf.flags & ATA_TFLAG_WRITE)) | 1951 | if (!(tf->flags & ATA_TFLAG_WRITE)) |
1912 | flags |= CRQB_FLAG_READ; | 1952 | flags |= CRQB_FLAG_READ; |
1913 | WARN_ON(MV_MAX_Q_DEPTH <= qc->tag); | 1953 | WARN_ON(MV_MAX_Q_DEPTH <= qc->tag); |
1914 | flags |= qc->tag << CRQB_TAG_SHIFT; | 1954 | flags |= qc->tag << CRQB_TAG_SHIFT; |
@@ -1924,7 +1964,6 @@ static void mv_qc_prep(struct ata_queued_cmd *qc) | |||
1924 | pp->crqb[in_index].ctrl_flags = cpu_to_le16(flags); | 1964 | pp->crqb[in_index].ctrl_flags = cpu_to_le16(flags); |
1925 | 1965 | ||
1926 | cw = &pp->crqb[in_index].ata_cmd[0]; | 1966 | cw = &pp->crqb[in_index].ata_cmd[0]; |
1927 | tf = &qc->tf; | ||
1928 | 1967 | ||
1929 | /* Sadly, the CRQB cannot accomodate all registers--there are | 1968 | /* Sadly, the CRQB cannot accomodate all registers--there are |
1930 | * only 11 bytes...so we must pick and choose required | 1969 | * only 11 bytes...so we must pick and choose required |
@@ -1990,16 +2029,16 @@ static void mv_qc_prep_iie(struct ata_queued_cmd *qc) | |||
1990 | struct ata_port *ap = qc->ap; | 2029 | struct ata_port *ap = qc->ap; |
1991 | struct mv_port_priv *pp = ap->private_data; | 2030 | struct mv_port_priv *pp = ap->private_data; |
1992 | struct mv_crqb_iie *crqb; | 2031 | struct mv_crqb_iie *crqb; |
1993 | struct ata_taskfile *tf; | 2032 | struct ata_taskfile *tf = &qc->tf; |
1994 | unsigned in_index; | 2033 | unsigned in_index; |
1995 | u32 flags = 0; | 2034 | u32 flags = 0; |
1996 | 2035 | ||
1997 | if ((qc->tf.protocol != ATA_PROT_DMA) && | 2036 | if ((tf->protocol != ATA_PROT_DMA) && |
1998 | (qc->tf.protocol != ATA_PROT_NCQ)) | 2037 | (tf->protocol != ATA_PROT_NCQ)) |
1999 | return; | 2038 | return; |
2000 | 2039 | ||
2001 | /* Fill in Gen IIE command request block */ | 2040 | /* Fill in Gen IIE command request block */ |
2002 | if (!(qc->tf.flags & ATA_TFLAG_WRITE)) | 2041 | if (!(tf->flags & ATA_TFLAG_WRITE)) |
2003 | flags |= CRQB_FLAG_READ; | 2042 | flags |= CRQB_FLAG_READ; |
2004 | 2043 | ||
2005 | WARN_ON(MV_MAX_Q_DEPTH <= qc->tag); | 2044 | WARN_ON(MV_MAX_Q_DEPTH <= qc->tag); |
@@ -2015,7 +2054,6 @@ static void mv_qc_prep_iie(struct ata_queued_cmd *qc) | |||
2015 | crqb->addr_hi = cpu_to_le32((pp->sg_tbl_dma[qc->tag] >> 16) >> 16); | 2054 | crqb->addr_hi = cpu_to_le32((pp->sg_tbl_dma[qc->tag] >> 16) >> 16); |
2016 | crqb->flags = cpu_to_le32(flags); | 2055 | crqb->flags = cpu_to_le32(flags); |
2017 | 2056 | ||
2018 | tf = &qc->tf; | ||
2019 | crqb->ata_cmd[0] = cpu_to_le32( | 2057 | crqb->ata_cmd[0] = cpu_to_le32( |
2020 | (tf->command << 16) | | 2058 | (tf->command << 16) | |
2021 | (tf->feature << 24) | 2059 | (tf->feature << 24) |