aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2006-06-17 02:49:56 -0400
committerJeff Garzik <jeff@garzik.org>2006-06-20 04:59:22 -0400
commit39f8758259868a01ecad29b4379661dd3f21881f (patch)
tree12c9583bc5ed11d2c7c4b95b796251d30c465c16 /drivers
parentada364e884eb7e60ee96e84cbce07b3c90234c9d (diff)
[PATCH] sata_nv: convert to new EH
Convert to new EH. Signed-off-by: Tejun Heo <htejun@gmail.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/sata_nv.c115
1 files changed, 89 insertions, 26 deletions
diff --git a/drivers/scsi/sata_nv.c b/drivers/scsi/sata_nv.c
index 94cb17903fae..2a1bd85404e0 100644
--- a/drivers/scsi/sata_nv.c
+++ b/drivers/scsi/sata_nv.c
@@ -68,6 +68,9 @@ enum {
68 68
69 NV_INT_PORT_SHIFT = 4, /* each port occupies 4 bits */ 69 NV_INT_PORT_SHIFT = 4, /* each port occupies 4 bits */
70 70
71 NV_INT_ALL = 0x0f,
72 NV_INT_MASK = NV_INT_DEV,
73
71 /* INT_CONFIG */ 74 /* INT_CONFIG */
72 NV_INT_CONFIG = 0x12, 75 NV_INT_CONFIG = 0x12,
73 NV_INT_CONFIG_METHD = 0x01, // 0 = INT, 1 = SMI 76 NV_INT_CONFIG_METHD = 0x01, // 0 = INT, 1 = SMI
@@ -88,6 +91,12 @@ static irqreturn_t nv_ck804_interrupt(int irq, void *dev_instance,
88static u32 nv_scr_read (struct ata_port *ap, unsigned int sc_reg); 91static u32 nv_scr_read (struct ata_port *ap, unsigned int sc_reg);
89static void nv_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); 92static void nv_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
90 93
94static void nv_nf2_freeze(struct ata_port *ap);
95static void nv_nf2_thaw(struct ata_port *ap);
96static void nv_ck804_freeze(struct ata_port *ap);
97static void nv_ck804_thaw(struct ata_port *ap);
98static void nv_error_handler(struct ata_port *ap);
99
91enum nv_host_type 100enum nv_host_type
92{ 101{
93 GENERIC, 102 GENERIC,
@@ -166,14 +175,16 @@ static const struct ata_port_operations nv_generic_ops = {
166 .exec_command = ata_exec_command, 175 .exec_command = ata_exec_command,
167 .check_status = ata_check_status, 176 .check_status = ata_check_status,
168 .dev_select = ata_std_dev_select, 177 .dev_select = ata_std_dev_select,
169 .phy_reset = sata_phy_reset,
170 .bmdma_setup = ata_bmdma_setup, 178 .bmdma_setup = ata_bmdma_setup,
171 .bmdma_start = ata_bmdma_start, 179 .bmdma_start = ata_bmdma_start,
172 .bmdma_stop = ata_bmdma_stop, 180 .bmdma_stop = ata_bmdma_stop,
173 .bmdma_status = ata_bmdma_status, 181 .bmdma_status = ata_bmdma_status,
174 .qc_prep = ata_qc_prep, 182 .qc_prep = ata_qc_prep,
175 .qc_issue = ata_qc_issue_prot, 183 .qc_issue = ata_qc_issue_prot,
176 .eng_timeout = ata_eng_timeout, 184 .freeze = ata_bmdma_freeze,
185 .thaw = ata_bmdma_thaw,
186 .error_handler = nv_error_handler,
187 .post_internal_cmd = ata_bmdma_post_internal_cmd,
177 .data_xfer = ata_pio_data_xfer, 188 .data_xfer = ata_pio_data_xfer,
178 .irq_handler = nv_generic_interrupt, 189 .irq_handler = nv_generic_interrupt,
179 .irq_clear = ata_bmdma_irq_clear, 190 .irq_clear = ata_bmdma_irq_clear,
@@ -191,14 +202,16 @@ static const struct ata_port_operations nv_nf2_ops = {
191 .exec_command = ata_exec_command, 202 .exec_command = ata_exec_command,
192 .check_status = ata_check_status, 203 .check_status = ata_check_status,
193 .dev_select = ata_std_dev_select, 204 .dev_select = ata_std_dev_select,
194 .phy_reset = sata_phy_reset,
195 .bmdma_setup = ata_bmdma_setup, 205 .bmdma_setup = ata_bmdma_setup,
196 .bmdma_start = ata_bmdma_start, 206 .bmdma_start = ata_bmdma_start,
197 .bmdma_stop = ata_bmdma_stop, 207 .bmdma_stop = ata_bmdma_stop,
198 .bmdma_status = ata_bmdma_status, 208 .bmdma_status = ata_bmdma_status,
199 .qc_prep = ata_qc_prep, 209 .qc_prep = ata_qc_prep,
200 .qc_issue = ata_qc_issue_prot, 210 .qc_issue = ata_qc_issue_prot,
201 .eng_timeout = ata_eng_timeout, 211 .freeze = nv_nf2_freeze,
212 .thaw = nv_nf2_thaw,
213 .error_handler = nv_error_handler,
214 .post_internal_cmd = ata_bmdma_post_internal_cmd,
202 .data_xfer = ata_pio_data_xfer, 215 .data_xfer = ata_pio_data_xfer,
203 .irq_handler = nv_nf2_interrupt, 216 .irq_handler = nv_nf2_interrupt,
204 .irq_clear = ata_bmdma_irq_clear, 217 .irq_clear = ata_bmdma_irq_clear,
@@ -216,14 +229,16 @@ static const struct ata_port_operations nv_ck804_ops = {
216 .exec_command = ata_exec_command, 229 .exec_command = ata_exec_command,
217 .check_status = ata_check_status, 230 .check_status = ata_check_status,
218 .dev_select = ata_std_dev_select, 231 .dev_select = ata_std_dev_select,
219 .phy_reset = sata_phy_reset,
220 .bmdma_setup = ata_bmdma_setup, 232 .bmdma_setup = ata_bmdma_setup,
221 .bmdma_start = ata_bmdma_start, 233 .bmdma_start = ata_bmdma_start,
222 .bmdma_stop = ata_bmdma_stop, 234 .bmdma_stop = ata_bmdma_stop,
223 .bmdma_status = ata_bmdma_status, 235 .bmdma_status = ata_bmdma_status,
224 .qc_prep = ata_qc_prep, 236 .qc_prep = ata_qc_prep,
225 .qc_issue = ata_qc_issue_prot, 237 .qc_issue = ata_qc_issue_prot,
226 .eng_timeout = ata_eng_timeout, 238 .freeze = nv_ck804_freeze,
239 .thaw = nv_ck804_thaw,
240 .error_handler = nv_error_handler,
241 .post_internal_cmd = ata_bmdma_post_internal_cmd,
227 .data_xfer = ata_pio_data_xfer, 242 .data_xfer = ata_pio_data_xfer,
228 .irq_handler = nv_ck804_interrupt, 243 .irq_handler = nv_ck804_interrupt,
229 .irq_clear = ata_bmdma_irq_clear, 244 .irq_clear = ata_bmdma_irq_clear,
@@ -234,22 +249,11 @@ static const struct ata_port_operations nv_ck804_ops = {
234 .host_stop = nv_ck804_host_stop, 249 .host_stop = nv_ck804_host_stop,
235}; 250};
236 251
237/* FIXME: The hardware provides the necessary SATA PHY controls
238 * to support ATA_FLAG_SATA_RESET. However, it is currently
239 * necessary to disable that flag, to solve misdetection problems.
240 * See http://bugme.osdl.org/show_bug.cgi?id=3352 for more info.
241 *
242 * This problem really needs to be investigated further. But in the
243 * meantime, we avoid ATA_FLAG_SATA_RESET to get people working.
244 */
245static struct ata_port_info nv_port_info[] = { 252static struct ata_port_info nv_port_info[] = {
246 /* generic */ 253 /* generic */
247 { 254 {
248 .sht = &nv_sht, 255 .sht = &nv_sht,
249 .host_flags = ATA_FLAG_SATA | 256 .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
250 /* ATA_FLAG_SATA_RESET | */
251 ATA_FLAG_SRST |
252 ATA_FLAG_NO_LEGACY,
253 .pio_mask = NV_PIO_MASK, 257 .pio_mask = NV_PIO_MASK,
254 .mwdma_mask = NV_MWDMA_MASK, 258 .mwdma_mask = NV_MWDMA_MASK,
255 .udma_mask = NV_UDMA_MASK, 259 .udma_mask = NV_UDMA_MASK,
@@ -258,10 +262,7 @@ static struct ata_port_info nv_port_info[] = {
258 /* nforce2/3 */ 262 /* nforce2/3 */
259 { 263 {
260 .sht = &nv_sht, 264 .sht = &nv_sht,
261 .host_flags = ATA_FLAG_SATA | 265 .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
262 /* ATA_FLAG_SATA_RESET | */
263 ATA_FLAG_SRST |
264 ATA_FLAG_NO_LEGACY,
265 .pio_mask = NV_PIO_MASK, 266 .pio_mask = NV_PIO_MASK,
266 .mwdma_mask = NV_MWDMA_MASK, 267 .mwdma_mask = NV_MWDMA_MASK,
267 .udma_mask = NV_UDMA_MASK, 268 .udma_mask = NV_UDMA_MASK,
@@ -270,10 +271,7 @@ static struct ata_port_info nv_port_info[] = {
270 /* ck804 */ 271 /* ck804 */
271 { 272 {
272 .sht = &nv_sht, 273 .sht = &nv_sht,
273 .host_flags = ATA_FLAG_SATA | 274 .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
274 /* ATA_FLAG_SATA_RESET | */
275 ATA_FLAG_SRST |
276 ATA_FLAG_NO_LEGACY,
277 .pio_mask = NV_PIO_MASK, 275 .pio_mask = NV_PIO_MASK,
278 .mwdma_mask = NV_MWDMA_MASK, 276 .mwdma_mask = NV_MWDMA_MASK,
279 .udma_mask = NV_UDMA_MASK, 277 .udma_mask = NV_UDMA_MASK,
@@ -410,6 +408,71 @@ static void nv_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
410 iowrite32(val, (void __iomem *)ap->ioaddr.scr_addr + (sc_reg * 4)); 408 iowrite32(val, (void __iomem *)ap->ioaddr.scr_addr + (sc_reg * 4));
411} 409}
412 410
411static void nv_nf2_freeze(struct ata_port *ap)
412{
413 unsigned long scr_addr = ap->host_set->ports[0]->ioaddr.scr_addr;
414 int shift = ap->port_no * NV_INT_PORT_SHIFT;
415 u8 mask;
416
417 mask = inb(scr_addr + NV_INT_ENABLE);
418 mask &= ~(NV_INT_ALL << shift);
419 outb(mask, scr_addr + NV_INT_ENABLE);
420}
421
422static void nv_nf2_thaw(struct ata_port *ap)
423{
424 unsigned long scr_addr = ap->host_set->ports[0]->ioaddr.scr_addr;
425 int shift = ap->port_no * NV_INT_PORT_SHIFT;
426 u8 mask;
427
428 outb(NV_INT_ALL << shift, scr_addr + NV_INT_STATUS);
429
430 mask = inb(scr_addr + NV_INT_ENABLE);
431 mask |= (NV_INT_MASK << shift);
432 outb(mask, scr_addr + NV_INT_ENABLE);
433}
434
435static void nv_ck804_freeze(struct ata_port *ap)
436{
437 void __iomem *mmio_base = ap->host_set->mmio_base;
438 int shift = ap->port_no * NV_INT_PORT_SHIFT;
439 u8 mask;
440
441 mask = readb(mmio_base + NV_INT_ENABLE_CK804);
442 mask &= ~(NV_INT_ALL << shift);
443 writeb(mask, mmio_base + NV_INT_ENABLE_CK804);
444}
445
446static void nv_ck804_thaw(struct ata_port *ap)
447{
448 void __iomem *mmio_base = ap->host_set->mmio_base;
449 int shift = ap->port_no * NV_INT_PORT_SHIFT;
450 u8 mask;
451
452 writeb(NV_INT_ALL << shift, mmio_base + NV_INT_STATUS_CK804);
453
454 mask = readb(mmio_base + NV_INT_ENABLE_CK804);
455 mask |= (NV_INT_MASK << shift);
456 writeb(mask, mmio_base + NV_INT_ENABLE_CK804);
457}
458
459static int nv_hardreset(struct ata_port *ap, unsigned int *class)
460{
461 unsigned int dummy;
462
463 /* SATA hardreset fails to retrieve proper device signature on
464 * some controllers. Don't classify on hardreset. For more
465 * info, see http://bugme.osdl.org/show_bug.cgi?id=3352
466 */
467 return sata_std_hardreset(ap, &dummy);
468}
469
470static void nv_error_handler(struct ata_port *ap)
471{
472 ata_bmdma_drive_eh(ap, ata_std_prereset, ata_std_softreset,
473 nv_hardreset, ata_std_postreset);
474}
475
413static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) 476static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
414{ 477{
415 static int printed_version = 0; 478 static int printed_version = 0;