aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/ata/ata_piix.c24
-rw-r--r--drivers/ata/sata_via.c117
2 files changed, 134 insertions, 7 deletions
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index 6846b5629ed2..0ca4c3b78dc5 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -390,7 +390,8 @@ static struct ata_port_info piix_port_info[] = {
390 /* ich5_sata */ 390 /* ich5_sata */
391 { 391 {
392 .sht = &piix_sht, 392 .sht = &piix_sht,
393 .host_flags = ATA_FLAG_SATA | PIIX_FLAG_CHECKINTR, 393 .host_flags = ATA_FLAG_SATA | PIIX_FLAG_CHECKINTR |
394 PIIX_FLAG_IGNORE_PCS,
394 .pio_mask = 0x1f, /* pio0-4 */ 395 .pio_mask = 0x1f, /* pio0-4 */
395 .mwdma_mask = 0x07, /* mwdma0-2 */ 396 .mwdma_mask = 0x07, /* mwdma0-2 */
396 .udma_mask = 0x7f, /* udma0-6 */ 397 .udma_mask = 0x7f, /* udma0-6 */
@@ -467,6 +468,11 @@ MODULE_LICENSE("GPL");
467MODULE_DEVICE_TABLE(pci, piix_pci_tbl); 468MODULE_DEVICE_TABLE(pci, piix_pci_tbl);
468MODULE_VERSION(DRV_VERSION); 469MODULE_VERSION(DRV_VERSION);
469 470
471static int force_pcs = 0;
472module_param(force_pcs, int, 0444);
473MODULE_PARM_DESC(force_pcs, "force honoring or ignoring PCS to work around "
474 "device mis-detection (0=default, 1=ignore PCS, 2=honor PCS)");
475
470/** 476/**
471 * piix_pata_cbl_detect - Probe host controller cable detect info 477 * piix_pata_cbl_detect - Probe host controller cable detect info
472 * @ap: Port for which cable detect info is desired 478 * @ap: Port for which cable detect info is desired
@@ -811,6 +817,7 @@ static int __devinit piix_check_450nx_errata(struct pci_dev *ata_dev)
811} 817}
812 818
813static void __devinit piix_init_pcs(struct pci_dev *pdev, 819static void __devinit piix_init_pcs(struct pci_dev *pdev,
820 struct ata_port_info *pinfo,
814 const struct piix_map_db *map_db) 821 const struct piix_map_db *map_db)
815{ 822{
816 u16 pcs, new_pcs; 823 u16 pcs, new_pcs;
@@ -824,6 +831,18 @@ static void __devinit piix_init_pcs(struct pci_dev *pdev,
824 pci_write_config_word(pdev, ICH5_PCS, new_pcs); 831 pci_write_config_word(pdev, ICH5_PCS, new_pcs);
825 msleep(150); 832 msleep(150);
826 } 833 }
834
835 if (force_pcs == 1) {
836 dev_printk(KERN_INFO, &pdev->dev,
837 "force ignoring PCS (0x%x)\n", new_pcs);
838 pinfo[0].host_flags |= PIIX_FLAG_IGNORE_PCS;
839 pinfo[1].host_flags |= PIIX_FLAG_IGNORE_PCS;
840 } else if (force_pcs == 2) {
841 dev_printk(KERN_INFO, &pdev->dev,
842 "force honoring PCS (0x%x)\n", new_pcs);
843 pinfo[0].host_flags &= ~PIIX_FLAG_IGNORE_PCS;
844 pinfo[1].host_flags &= ~PIIX_FLAG_IGNORE_PCS;
845 }
827} 846}
828 847
829static void __devinit piix_init_sata_map(struct pci_dev *pdev, 848static void __devinit piix_init_sata_map(struct pci_dev *pdev,
@@ -932,7 +951,8 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
932 if (host_flags & ATA_FLAG_SATA) { 951 if (host_flags & ATA_FLAG_SATA) {
933 piix_init_sata_map(pdev, port_info, 952 piix_init_sata_map(pdev, port_info,
934 piix_map_db_table[ent->driver_data]); 953 piix_map_db_table[ent->driver_data]);
935 piix_init_pcs(pdev, piix_map_db_table[ent->driver_data]); 954 piix_init_pcs(pdev, port_info,
955 piix_map_db_table[ent->driver_data]);
936 } 956 }
937 957
938 /* On ICH5, some BIOSen disable the interrupt using the 958 /* On ICH5, some BIOSen disable the interrupt using the
diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c
index 6529189a2880..a0699a1728d4 100644
--- a/drivers/ata/sata_via.c
+++ b/drivers/ata/sata_via.c
@@ -74,6 +74,7 @@ enum {
74static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); 74static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
75static u32 svia_scr_read (struct ata_port *ap, unsigned int sc_reg); 75static u32 svia_scr_read (struct ata_port *ap, unsigned int sc_reg);
76static void svia_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); 76static void svia_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
77static void vt6420_error_handler(struct ata_port *ap);
77 78
78static const struct pci_device_id svia_pci_tbl[] = { 79static const struct pci_device_id svia_pci_tbl[] = {
79 { 0x1106, 0x0591, PCI_ANY_ID, PCI_ANY_ID, 0, 0, vt6420 }, 80 { 0x1106, 0x0591, PCI_ANY_ID, PCI_ANY_ID, 0, 0, vt6420 },
@@ -108,7 +109,38 @@ static struct scsi_host_template svia_sht = {
108 .bios_param = ata_std_bios_param, 109 .bios_param = ata_std_bios_param,
109}; 110};
110 111
111static const struct ata_port_operations svia_sata_ops = { 112static const struct ata_port_operations vt6420_sata_ops = {
113 .port_disable = ata_port_disable,
114
115 .tf_load = ata_tf_load,
116 .tf_read = ata_tf_read,
117 .check_status = ata_check_status,
118 .exec_command = ata_exec_command,
119 .dev_select = ata_std_dev_select,
120
121 .bmdma_setup = ata_bmdma_setup,
122 .bmdma_start = ata_bmdma_start,
123 .bmdma_stop = ata_bmdma_stop,
124 .bmdma_status = ata_bmdma_status,
125
126 .qc_prep = ata_qc_prep,
127 .qc_issue = ata_qc_issue_prot,
128 .data_xfer = ata_pio_data_xfer,
129
130 .freeze = ata_bmdma_freeze,
131 .thaw = ata_bmdma_thaw,
132 .error_handler = vt6420_error_handler,
133 .post_internal_cmd = ata_bmdma_post_internal_cmd,
134
135 .irq_handler = ata_interrupt,
136 .irq_clear = ata_bmdma_irq_clear,
137
138 .port_start = ata_port_start,
139 .port_stop = ata_port_stop,
140 .host_stop = ata_host_stop,
141};
142
143static const struct ata_port_operations vt6421_sata_ops = {
112 .port_disable = ata_port_disable, 144 .port_disable = ata_port_disable,
113 145
114 .tf_load = ata_tf_load, 146 .tf_load = ata_tf_load,
@@ -142,13 +174,13 @@ static const struct ata_port_operations svia_sata_ops = {
142 .host_stop = ata_host_stop, 174 .host_stop = ata_host_stop,
143}; 175};
144 176
145static struct ata_port_info svia_port_info = { 177static struct ata_port_info vt6420_port_info = {
146 .sht = &svia_sht, 178 .sht = &svia_sht,
147 .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY, 179 .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
148 .pio_mask = 0x1f, 180 .pio_mask = 0x1f,
149 .mwdma_mask = 0x07, 181 .mwdma_mask = 0x07,
150 .udma_mask = 0x7f, 182 .udma_mask = 0x7f,
151 .port_ops = &svia_sata_ops, 183 .port_ops = &vt6420_sata_ops,
152}; 184};
153 185
154MODULE_AUTHOR("Jeff Garzik"); 186MODULE_AUTHOR("Jeff Garzik");
@@ -171,6 +203,81 @@ static void svia_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
171 outl(val, ap->ioaddr.scr_addr + (4 * sc_reg)); 203 outl(val, ap->ioaddr.scr_addr + (4 * sc_reg));
172} 204}
173 205
206/**
207 * vt6420_prereset - prereset for vt6420
208 * @ap: target ATA port
209 *
210 * SCR registers on vt6420 are pieces of shit and may hang the
211 * whole machine completely if accessed with the wrong timing.
212 * To avoid such catastrophe, vt6420 doesn't provide generic SCR
213 * access operations, but uses SStatus and SControl only during
214 * boot probing in controlled way.
215 *
216 * As the old (pre EH update) probing code is proven to work, we
217 * strictly follow the access pattern.
218 *
219 * LOCKING:
220 * Kernel thread context (may sleep)
221 *
222 * RETURNS:
223 * 0 on success, -errno otherwise.
224 */
225static int vt6420_prereset(struct ata_port *ap)
226{
227 struct ata_eh_context *ehc = &ap->eh_context;
228 unsigned long timeout = jiffies + (HZ * 5);
229 u32 sstatus, scontrol;
230 int online;
231
232 /* don't do any SCR stuff if we're not loading */
233 if (!ATA_PFLAG_LOADING)
234 goto skip_scr;
235
236 /* Resume phy. This is the old resume sequence from
237 * __sata_phy_reset().
238 */
239 svia_scr_write(ap, SCR_CONTROL, 0x300);
240 svia_scr_read(ap, SCR_CONTROL); /* flush */
241
242 /* wait for phy to become ready, if necessary */
243 do {
244 msleep(200);
245 if ((svia_scr_read(ap, SCR_STATUS) & 0xf) != 1)
246 break;
247 } while (time_before(jiffies, timeout));
248
249 /* open code sata_print_link_status() */
250 sstatus = svia_scr_read(ap, SCR_STATUS);
251 scontrol = svia_scr_read(ap, SCR_CONTROL);
252
253 online = (sstatus & 0xf) == 0x3;
254
255 ata_port_printk(ap, KERN_INFO,
256 "SATA link %s 1.5 Gbps (SStatus %X SControl %X)\n",
257 online ? "up" : "down", sstatus, scontrol);
258
259 /* SStatus is read one more time */
260 svia_scr_read(ap, SCR_STATUS);
261
262 if (!online) {
263 /* tell EH to bail */
264 ehc->i.action &= ~ATA_EH_RESET_MASK;
265 return 0;
266 }
267
268 skip_scr:
269 /* wait for !BSY */
270 ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);
271
272 return 0;
273}
274
275static void vt6420_error_handler(struct ata_port *ap)
276{
277 return ata_bmdma_drive_eh(ap, vt6420_prereset, ata_std_softreset,
278 NULL, ata_std_postreset);
279}
280
174static const unsigned int svia_bar_sizes[] = { 281static const unsigned int svia_bar_sizes[] = {
175 8, 4, 8, 4, 16, 256 282 8, 4, 8, 4, 16, 256
176}; 283};
@@ -211,7 +318,7 @@ static void vt6421_init_addrs(struct ata_probe_ent *probe_ent,
211static struct ata_probe_ent *vt6420_init_probe_ent(struct pci_dev *pdev) 318static struct ata_probe_ent *vt6420_init_probe_ent(struct pci_dev *pdev)
212{ 319{
213 struct ata_probe_ent *probe_ent; 320 struct ata_probe_ent *probe_ent;
214 struct ata_port_info *ppi = &svia_port_info; 321 struct ata_port_info *ppi = &vt6420_port_info;
215 322
216 probe_ent = ata_pci_init_native_mode(pdev, &ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY); 323 probe_ent = ata_pci_init_native_mode(pdev, &ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
217 if (!probe_ent) 324 if (!probe_ent)
@@ -240,7 +347,7 @@ static struct ata_probe_ent *vt6421_init_probe_ent(struct pci_dev *pdev)
240 347
241 probe_ent->sht = &svia_sht; 348 probe_ent->sht = &svia_sht;
242 probe_ent->host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY; 349 probe_ent->host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY;
243 probe_ent->port_ops = &svia_sata_ops; 350 probe_ent->port_ops = &vt6421_sata_ops;
244 probe_ent->n_ports = N_PORTS; 351 probe_ent->n_ports = N_PORTS;
245 probe_ent->irq = pdev->irq; 352 probe_ent->irq = pdev->irq;
246 probe_ent->irq_flags = IRQF_SHARED; 353 probe_ent->irq_flags = IRQF_SHARED;