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 , 0x3149 , PCI_ANY_ID , PCI_ANY_ID , 0 , 0 , vt6420 },
@@ -107,7 +108,38 @@ static struct scsi_host_template svia_sht = {
107108 .bios_param = ata_std_bios_param ,
108109};
109110
110- static const struct ata_port_operations svia_sata_ops = {
111+ static const struct ata_port_operations vt6420_sata_ops = {
112+ .port_disable = ata_port_disable ,
113+
114+ .tf_load = ata_tf_load ,
115+ .tf_read = ata_tf_read ,
116+ .check_status = ata_check_status ,
117+ .exec_command = ata_exec_command ,
118+ .dev_select = ata_std_dev_select ,
119+
120+ .bmdma_setup = ata_bmdma_setup ,
121+ .bmdma_start = ata_bmdma_start ,
122+ .bmdma_stop = ata_bmdma_stop ,
123+ .bmdma_status = ata_bmdma_status ,
124+
125+ .qc_prep = ata_qc_prep ,
126+ .qc_issue = ata_qc_issue_prot ,
127+ .data_xfer = ata_pio_data_xfer ,
128+
129+ .freeze = ata_bmdma_freeze ,
130+ .thaw = ata_bmdma_thaw ,
131+ .error_handler = vt6420_error_handler ,
132+ .post_internal_cmd = ata_bmdma_post_internal_cmd ,
133+
134+ .irq_handler = ata_interrupt ,
135+ .irq_clear = ata_bmdma_irq_clear ,
136+
137+ .port_start = ata_port_start ,
138+ .port_stop = ata_port_stop ,
139+ .host_stop = ata_host_stop ,
140+ };
141+
142+ static const struct ata_port_operations vt6421_sata_ops = {
111143 .port_disable = ata_port_disable ,
112144
113145 .tf_load = ata_tf_load ,
@@ -141,13 +173,13 @@ static const struct ata_port_operations svia_sata_ops = {
141173 .host_stop = ata_host_stop ,
142174};
143175
144- static struct ata_port_info svia_port_info = {
176+ static struct ata_port_info vt6420_port_info = {
145177 .sht = & svia_sht ,
146178 .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY ,
147179 .pio_mask = 0x1f ,
148180 .mwdma_mask = 0x07 ,
149181 .udma_mask = 0x7f ,
150- .port_ops = & svia_sata_ops ,
182+ .port_ops = & vt6420_sata_ops ,
151183};
152184
153185MODULE_AUTHOR ("Jeff Garzik" );
@@ -170,6 +202,81 @@ static void svia_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
170202 outl (val , ap -> ioaddr .scr_addr + (4 * sc_reg ));
171203}
172204
205+ /**
206+ * vt6420_prereset - prereset for vt6420
207+ * @ap: target ATA port
208+ *
209+ * SCR registers on vt6420 are pieces of shit and may hang the
210+ * whole machine completely if accessed with the wrong timing.
211+ * To avoid such catastrophe, vt6420 doesn't provide generic SCR
212+ * access operations, but uses SStatus and SControl only during
213+ * boot probing in controlled way.
214+ *
215+ * As the old (pre EH update) probing code is proven to work, we
216+ * strictly follow the access pattern.
217+ *
218+ * LOCKING:
219+ * Kernel thread context (may sleep)
220+ *
221+ * RETURNS:
222+ * 0 on success, -errno otherwise.
223+ */
224+ static int vt6420_prereset (struct ata_port * ap )
225+ {
226+ struct ata_eh_context * ehc = & ap -> eh_context ;
227+ unsigned long timeout = jiffies + (HZ * 5 );
228+ u32 sstatus , scontrol ;
229+ int online ;
230+
231+ /* don't do any SCR stuff if we're not loading */
232+ if (!ATA_PFLAG_LOADING )
233+ goto skip_scr ;
234+
235+ /* Resume phy. This is the old resume sequence from
236+ * __sata_phy_reset().
237+ */
238+ svia_scr_write (ap , SCR_CONTROL , 0x300 );
239+ svia_scr_read (ap , SCR_CONTROL ); /* flush */
240+
241+ /* wait for phy to become ready, if necessary */
242+ do {
243+ msleep (200 );
244+ if ((svia_scr_read (ap , SCR_STATUS ) & 0xf ) != 1 )
245+ break ;
246+ } while (time_before (jiffies , timeout ));
247+
248+ /* open code sata_print_link_status() */
249+ sstatus = svia_scr_read (ap , SCR_STATUS );
250+ scontrol = svia_scr_read (ap , SCR_CONTROL );
251+
252+ online = (sstatus & 0xf ) == 0x3 ;
253+
254+ ata_port_printk (ap , KERN_INFO ,
255+ "SATA link %s 1.5 Gbps (SStatus %X SControl %X)\n" ,
256+ online ? "up" : "down" , sstatus , scontrol );
257+
258+ /* SStatus is read one more time */
259+ svia_scr_read (ap , SCR_STATUS );
260+
261+ if (!online ) {
262+ /* tell EH to bail */
263+ ehc -> i .action &= ~ATA_EH_RESET_MASK ;
264+ return 0 ;
265+ }
266+
267+ skip_scr :
268+ /* wait for !BSY */
269+ ata_busy_sleep (ap , ATA_TMOUT_BOOT_QUICK , ATA_TMOUT_BOOT );
270+
271+ return 0 ;
272+ }
273+
274+ static void vt6420_error_handler (struct ata_port * ap )
275+ {
276+ return ata_bmdma_drive_eh (ap , vt6420_prereset , ata_std_softreset ,
277+ NULL , ata_std_postreset );
278+ }
279+
173280static const unsigned int svia_bar_sizes [] = {
174281 8 , 4 , 8 , 4 , 16 , 256
175282};
@@ -210,7 +317,7 @@ static void vt6421_init_addrs(struct ata_probe_ent *probe_ent,
210317static struct ata_probe_ent * vt6420_init_probe_ent (struct pci_dev * pdev )
211318{
212319 struct ata_probe_ent * probe_ent ;
213- struct ata_port_info * ppi = & svia_port_info ;
320+ struct ata_port_info * ppi = & vt6420_port_info ;
214321
215322 probe_ent = ata_pci_init_native_mode (pdev , & ppi , ATA_PORT_PRIMARY | ATA_PORT_SECONDARY );
216323 if (!probe_ent )
@@ -239,7 +346,7 @@ static struct ata_probe_ent *vt6421_init_probe_ent(struct pci_dev *pdev)
239346
240347 probe_ent -> sht = & svia_sht ;
241348 probe_ent -> host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY ;
242- probe_ent -> port_ops = & svia_sata_ops ;
349+ probe_ent -> port_ops = & vt6421_sata_ops ;
243350 probe_ent -> n_ports = N_PORTS ;
244351 probe_ent -> irq = pdev -> irq ;
245352 probe_ent -> irq_flags = IRQF_SHARED ;
0 commit comments