7474static int svia_init_one (struct pci_dev * pdev , const struct pci_device_id * ent );
7575static u32 svia_scr_read (struct ata_port * ap , unsigned int sc_reg );
7676static void svia_scr_write (struct ata_port * ap , unsigned int sc_reg , u32 val );
77+ static void vt6420_error_handler (struct ata_port * ap );
7778
7879static const struct pci_device_id svia_pci_tbl [] = {
7980 { 0x1106 , 0x0591 , PCI_ANY_ID , PCI_ANY_ID , 0 , 0 , vt6420 },
@@ -108,7 +109,38 @@ static struct scsi_host_template svia_sht = {
108109 .bios_param = ata_std_bios_param ,
109110};
110111
111- static const struct ata_port_operations svia_sata_ops = {
112+ static 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+
143+ static const struct ata_port_operations vt6421_sata_ops = {
112144 .port_disable = ata_port_disable ,
113145
114146 .tf_load = ata_tf_load ,
@@ -142,13 +174,13 @@ static const struct ata_port_operations svia_sata_ops = {
142174 .host_stop = ata_host_stop ,
143175};
144176
145- static struct ata_port_info svia_port_info = {
177+ static struct ata_port_info vt6420_port_info = {
146178 .sht = & svia_sht ,
147179 .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY ,
148180 .pio_mask = 0x1f ,
149181 .mwdma_mask = 0x07 ,
150182 .udma_mask = 0x7f ,
151- .port_ops = & svia_sata_ops ,
183+ .port_ops = & vt6420_sata_ops ,
152184};
153185
154186MODULE_AUTHOR ("Jeff Garzik" );
@@ -171,6 +203,81 @@ static void svia_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
171203 outl (val , ap -> ioaddr .scr_addr + (4 * sc_reg ));
172204}
173205
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+ */
225+ static 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+
275+ static 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+
174281static const unsigned int svia_bar_sizes [] = {
175282 8 , 4 , 8 , 4 , 16 , 256
176283};
@@ -211,7 +318,7 @@ static void vt6421_init_addrs(struct ata_probe_ent *probe_ent,
211318static struct ata_probe_ent * vt6420_init_probe_ent (struct pci_dev * pdev )
212319{
213320 struct ata_probe_ent * probe_ent ;
214- struct ata_port_info * ppi = & svia_port_info ;
321+ struct ata_port_info * ppi = & vt6420_port_info ;
215322
216323 probe_ent = ata_pci_init_native_mode (pdev , & ppi , ATA_PORT_PRIMARY | ATA_PORT_SECONDARY );
217324 if (!probe_ent )
@@ -240,7 +347,7 @@ static struct ata_probe_ent *vt6421_init_probe_ent(struct pci_dev *pdev)
240347
241348 probe_ent -> sht = & svia_sht ;
242349 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 ;
244351 probe_ent -> n_ports = N_PORTS ;
245352 probe_ent -> irq = pdev -> irq ;
246353 probe_ent -> irq_flags = IRQF_SHARED ;
0 commit comments