aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/ata/libata-core.c2
-rw-r--r--drivers/ata/libata-eh.c26
-rw-r--r--drivers/ata/libata-sff.c11
-rw-r--r--drivers/ata/sata_via.c35
-rw-r--r--include/linux/libata.h3
5 files changed, 64 insertions, 13 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 1ee9499bd343..bbb3cae57492 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -5373,6 +5373,8 @@ struct ata_port *ata_port_alloc(struct ata_host *host)
5373 5373
5374#ifdef CONFIG_ATA_SFF 5374#ifdef CONFIG_ATA_SFF
5375 INIT_DELAYED_WORK(&ap->port_task, ata_pio_task); 5375 INIT_DELAYED_WORK(&ap->port_task, ata_pio_task);
5376#else
5377 INIT_DELAYED_WORK(&ap->port_task, NULL);
5376#endif 5378#endif
5377 INIT_DELAYED_WORK(&ap->hotplug_task, ata_scsi_hotplug); 5379 INIT_DELAYED_WORK(&ap->hotplug_task, ata_scsi_hotplug);
5378 INIT_WORK(&ap->scsi_rescan_task, ata_scsi_dev_rescan); 5380 INIT_WORK(&ap->scsi_rescan_task, ata_scsi_dev_rescan);
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index a93247cc395a..5d687d7cffae 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -1206,7 +1206,10 @@ void ata_eh_about_to_do(struct ata_link *link, struct ata_device *dev,
1206 1206
1207 ata_eh_clear_action(link, dev, ehi, action); 1207 ata_eh_clear_action(link, dev, ehi, action);
1208 1208
1209 if (!(ehc->i.flags & ATA_EHI_QUIET)) 1209 /* About to take EH action, set RECOVERED. Ignore actions on
1210 * slave links as master will do them again.
1211 */
1212 if (!(ehc->i.flags & ATA_EHI_QUIET) && link != ap->slave_link)
1210 ap->pflags |= ATA_PFLAG_RECOVERED; 1213 ap->pflags |= ATA_PFLAG_RECOVERED;
1211 1214
1212 spin_unlock_irqrestore(ap->lock, flags); 1215 spin_unlock_irqrestore(ap->lock, flags);
@@ -2010,8 +2013,13 @@ void ata_eh_autopsy(struct ata_port *ap)
2010 struct ata_eh_context *mehc = &ap->link.eh_context; 2013 struct ata_eh_context *mehc = &ap->link.eh_context;
2011 struct ata_eh_context *sehc = &ap->slave_link->eh_context; 2014 struct ata_eh_context *sehc = &ap->slave_link->eh_context;
2012 2015
2016 /* transfer control flags from master to slave */
2017 sehc->i.flags |= mehc->i.flags & ATA_EHI_TO_SLAVE_MASK;
2018
2019 /* perform autopsy on the slave link */
2013 ata_eh_link_autopsy(ap->slave_link); 2020 ata_eh_link_autopsy(ap->slave_link);
2014 2021
2022 /* transfer actions from slave to master and clear slave */
2015 ata_eh_about_to_do(ap->slave_link, NULL, ATA_EH_ALL_ACTIONS); 2023 ata_eh_about_to_do(ap->slave_link, NULL, ATA_EH_ALL_ACTIONS);
2016 mehc->i.action |= sehc->i.action; 2024 mehc->i.action |= sehc->i.action;
2017 mehc->i.dev_action[1] |= sehc->i.dev_action[1]; 2025 mehc->i.dev_action[1] |= sehc->i.dev_action[1];
@@ -2447,14 +2455,14 @@ int ata_eh_reset(struct ata_link *link, int classify,
2447 dev->pio_mode = XFER_PIO_0; 2455 dev->pio_mode = XFER_PIO_0;
2448 dev->flags &= ~ATA_DFLAG_SLEEPING; 2456 dev->flags &= ~ATA_DFLAG_SLEEPING;
2449 2457
2450 if (ata_phys_link_offline(ata_dev_phys_link(dev))) 2458 if (!ata_phys_link_offline(ata_dev_phys_link(dev))) {
2451 continue; 2459 /* apply class override */
2452 2460 if (lflags & ATA_LFLAG_ASSUME_ATA)
2453 /* apply class override */ 2461 classes[dev->devno] = ATA_DEV_ATA;
2454 if (lflags & ATA_LFLAG_ASSUME_ATA) 2462 else if (lflags & ATA_LFLAG_ASSUME_SEMB)
2455 classes[dev->devno] = ATA_DEV_ATA; 2463 classes[dev->devno] = ATA_DEV_SEMB_UNSUP;
2456 else if (lflags & ATA_LFLAG_ASSUME_SEMB) 2464 } else
2457 classes[dev->devno] = ATA_DEV_SEMB_UNSUP; /* not yet */ 2465 classes[dev->devno] = ATA_DEV_NONE;
2458 } 2466 }
2459 2467
2460 /* record current link speed */ 2468 /* record current link speed */
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index 2a4c516894f0..4b4739486327 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -2153,8 +2153,17 @@ void ata_sff_error_handler(struct ata_port *ap)
2153 */ 2153 */
2154void ata_sff_post_internal_cmd(struct ata_queued_cmd *qc) 2154void ata_sff_post_internal_cmd(struct ata_queued_cmd *qc)
2155{ 2155{
2156 if (qc->ap->ioaddr.bmdma_addr) 2156 struct ata_port *ap = qc->ap;
2157 unsigned long flags;
2158
2159 spin_lock_irqsave(ap->lock, flags);
2160
2161 ap->hsm_task_state = HSM_ST_IDLE;
2162
2163 if (ap->ioaddr.bmdma_addr)
2157 ata_bmdma_stop(qc); 2164 ata_bmdma_stop(qc);
2165
2166 spin_unlock_irqrestore(ap->lock, flags);
2158} 2167}
2159 2168
2160/** 2169/**
diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c
index 1cfa74535d91..5b72e734300a 100644
--- a/drivers/ata/sata_via.c
+++ b/drivers/ata/sata_via.c
@@ -70,6 +70,7 @@ enum {
70static int svia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); 70static int svia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
71static int svia_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val); 71static int svia_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val);
72static int svia_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val); 72static int svia_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val);
73static void svia_tf_load(struct ata_port *ap, const struct ata_taskfile *tf);
73static void svia_noop_freeze(struct ata_port *ap); 74static void svia_noop_freeze(struct ata_port *ap);
74static int vt6420_prereset(struct ata_link *link, unsigned long deadline); 75static int vt6420_prereset(struct ata_link *link, unsigned long deadline);
75static int vt6421_pata_cable_detect(struct ata_port *ap); 76static int vt6421_pata_cable_detect(struct ata_port *ap);
@@ -103,21 +104,26 @@ static struct scsi_host_template svia_sht = {
103 ATA_BMDMA_SHT(DRV_NAME), 104 ATA_BMDMA_SHT(DRV_NAME),
104}; 105};
105 106
106static struct ata_port_operations vt6420_sata_ops = { 107static struct ata_port_operations svia_base_ops = {
107 .inherits = &ata_bmdma_port_ops, 108 .inherits = &ata_bmdma_port_ops,
109 .sff_tf_load = svia_tf_load,
110};
111
112static struct ata_port_operations vt6420_sata_ops = {
113 .inherits = &svia_base_ops,
108 .freeze = svia_noop_freeze, 114 .freeze = svia_noop_freeze,
109 .prereset = vt6420_prereset, 115 .prereset = vt6420_prereset,
110}; 116};
111 117
112static struct ata_port_operations vt6421_pata_ops = { 118static struct ata_port_operations vt6421_pata_ops = {
113 .inherits = &ata_bmdma_port_ops, 119 .inherits = &svia_base_ops,
114 .cable_detect = vt6421_pata_cable_detect, 120 .cable_detect = vt6421_pata_cable_detect,
115 .set_piomode = vt6421_set_pio_mode, 121 .set_piomode = vt6421_set_pio_mode,
116 .set_dmamode = vt6421_set_dma_mode, 122 .set_dmamode = vt6421_set_dma_mode,
117}; 123};
118 124
119static struct ata_port_operations vt6421_sata_ops = { 125static struct ata_port_operations vt6421_sata_ops = {
120 .inherits = &ata_bmdma_port_ops, 126 .inherits = &svia_base_ops,
121 .scr_read = svia_scr_read, 127 .scr_read = svia_scr_read,
122 .scr_write = svia_scr_write, 128 .scr_write = svia_scr_write,
123}; 129};
@@ -168,6 +174,29 @@ static int svia_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val)
168 return 0; 174 return 0;
169} 175}
170 176
177/**
178 * svia_tf_load - send taskfile registers to host controller
179 * @ap: Port to which output is sent
180 * @tf: ATA taskfile register set
181 *
182 * Outputs ATA taskfile to standard ATA host controller.
183 *
184 * This is to fix the internal bug of via chipsets, which will
185 * reset the device register after changing the IEN bit on ctl
186 * register.
187 */
188static void svia_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
189{
190 struct ata_taskfile ttf;
191
192 if (tf->ctl != ap->last_ctl) {
193 ttf = *tf;
194 ttf.flags |= ATA_TFLAG_DEVICE;
195 tf = &ttf;
196 }
197 ata_sff_tf_load(ap, tf);
198}
199
171static void svia_noop_freeze(struct ata_port *ap) 200static void svia_noop_freeze(struct ata_port *ap)
172{ 201{
173 /* Some VIA controllers choke if ATA_NIEN is manipulated in 202 /* Some VIA controllers choke if ATA_NIEN is manipulated in
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 947cf84e555d..c261aa0584b1 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -340,6 +340,9 @@ enum {
340 340
341 ATA_EHI_DID_RESET = ATA_EHI_DID_SOFTRESET | ATA_EHI_DID_HARDRESET, 341 ATA_EHI_DID_RESET = ATA_EHI_DID_SOFTRESET | ATA_EHI_DID_HARDRESET,
342 342
343 /* mask of flags to transfer *to* the slave link */
344 ATA_EHI_TO_SLAVE_MASK = ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET,
345
343 /* max tries if error condition is still set after ->error_handler */ 346 /* max tries if error condition is still set after ->error_handler */
344 ATA_EH_MAX_TRIES = 5, 347 ATA_EH_MAX_TRIES = 5,
345 348