diff options
author | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2008-07-23 13:55:56 -0400 |
---|---|---|
committer | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2008-07-23 13:55:56 -0400 |
commit | 374e042c3e767ac2e5a40b78529220e0b3de793c (patch) | |
tree | 433d258f6da9783f0cb34234af9c359353f531fe /drivers/ide/ide-probe.c | |
parent | d6276b5f5cc7508124de291f3ed59c6945c17ae7 (diff) |
ide: add struct ide_tp_ops (take 2)
* Add struct ide_tp_ops for transport methods.
* Add 'const struct ide_tp_ops *tp_ops' to struct ide_port_info
and ide_hwif_t.
* Set the default hwif->tp_ops in ide_init_port_data().
* Set host driver specific hwif->tp_ops in ide_init_port().
* Export ide_exec_command(), ide_read_status(), ide_read_altstatus(),
ide_read_sff_dma_status(), ide_set_irq(), ide_tf_{load,read}()
and ata_{in,out}put_data().
* Convert host drivers and core code to use struct ide_tp_ops.
* Remove no longer needed default_hwif_transport().
* Cleanup ide_hwif_t from methods that are now in struct ide_tp_ops.
While at it:
* Use struct ide_port_info in falconide.c and q40ide.c.
* Rename ata_{in,out}put_data() to ide_{in,out}put_data().
v2:
* Fix missing convertion in ns87415.c.
There should be no functional changes caused by this patch.
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Diffstat (limited to 'drivers/ide/ide-probe.c')
-rw-r--r-- | drivers/ide/ide-probe.c | 53 |
1 files changed, 30 insertions, 23 deletions
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 3cc8ade2cc4f..c588066295db 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c | |||
@@ -126,7 +126,7 @@ static inline void do_identify (ide_drive_t *drive, u8 cmd) | |||
126 | 126 | ||
127 | id = drive->id; | 127 | id = drive->id; |
128 | /* read 512 bytes of id info */ | 128 | /* read 512 bytes of id info */ |
129 | hwif->input_data(drive, NULL, id, SECTOR_SIZE); | 129 | hwif->tp_ops->input_data(drive, NULL, id, SECTOR_SIZE); |
130 | 130 | ||
131 | drive->id_read = 1; | 131 | drive->id_read = 1; |
132 | local_irq_enable(); | 132 | local_irq_enable(); |
@@ -267,6 +267,7 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd) | |||
267 | { | 267 | { |
268 | ide_hwif_t *hwif = HWIF(drive); | 268 | ide_hwif_t *hwif = HWIF(drive); |
269 | struct ide_io_ports *io_ports = &hwif->io_ports; | 269 | struct ide_io_ports *io_ports = &hwif->io_ports; |
270 | const struct ide_tp_ops *tp_ops = hwif->tp_ops; | ||
270 | int use_altstatus = 0, rc; | 271 | int use_altstatus = 0, rc; |
271 | unsigned long timeout; | 272 | unsigned long timeout; |
272 | u8 s = 0, a = 0; | 273 | u8 s = 0, a = 0; |
@@ -275,8 +276,8 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd) | |||
275 | msleep(50); | 276 | msleep(50); |
276 | 277 | ||
277 | if (io_ports->ctl_addr) { | 278 | if (io_ports->ctl_addr) { |
278 | a = hwif->read_altstatus(hwif); | 279 | a = tp_ops->read_altstatus(hwif); |
279 | s = hwif->read_status(hwif); | 280 | s = tp_ops->read_status(hwif); |
280 | if ((a ^ s) & ~INDEX_STAT) | 281 | if ((a ^ s) & ~INDEX_STAT) |
281 | /* ancient Seagate drives, broken interfaces */ | 282 | /* ancient Seagate drives, broken interfaces */ |
282 | printk(KERN_INFO "%s: probing with STATUS(0x%02x) " | 283 | printk(KERN_INFO "%s: probing with STATUS(0x%02x) " |
@@ -297,11 +298,11 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd) | |||
297 | /* disable DMA & overlap */ | 298 | /* disable DMA & overlap */ |
298 | task.tf_flags = IDE_TFLAG_OUT_FEATURE; | 299 | task.tf_flags = IDE_TFLAG_OUT_FEATURE; |
299 | 300 | ||
300 | drive->hwif->tf_load(drive, &task); | 301 | tp_ops->tf_load(drive, &task); |
301 | } | 302 | } |
302 | 303 | ||
303 | /* ask drive for ID */ | 304 | /* ask drive for ID */ |
304 | hwif->exec_command(hwif, cmd); | 305 | tp_ops->exec_command(hwif, cmd); |
305 | 306 | ||
306 | timeout = ((cmd == WIN_IDENTIFY) ? WAIT_WORSTCASE : WAIT_PIDENTIFY) / 2; | 307 | timeout = ((cmd == WIN_IDENTIFY) ? WAIT_WORSTCASE : WAIT_PIDENTIFY) / 2; |
307 | timeout += jiffies; | 308 | timeout += jiffies; |
@@ -312,13 +313,13 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd) | |||
312 | } | 313 | } |
313 | /* give drive a breather */ | 314 | /* give drive a breather */ |
314 | msleep(50); | 315 | msleep(50); |
315 | s = use_altstatus ? hwif->read_altstatus(hwif) | 316 | s = use_altstatus ? tp_ops->read_altstatus(hwif) |
316 | : hwif->read_status(hwif); | 317 | : tp_ops->read_status(hwif); |
317 | } while (s & BUSY_STAT); | 318 | } while (s & BUSY_STAT); |
318 | 319 | ||
319 | /* wait for IRQ and DRQ_STAT */ | 320 | /* wait for IRQ and DRQ_STAT */ |
320 | msleep(50); | 321 | msleep(50); |
321 | s = hwif->read_status(hwif); | 322 | s = tp_ops->read_status(hwif); |
322 | 323 | ||
323 | if (OK_STAT(s, DRQ_STAT, BAD_R_STAT)) { | 324 | if (OK_STAT(s, DRQ_STAT, BAD_R_STAT)) { |
324 | unsigned long flags; | 325 | unsigned long flags; |
@@ -330,7 +331,7 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd) | |||
330 | /* drive responded with ID */ | 331 | /* drive responded with ID */ |
331 | rc = 0; | 332 | rc = 0; |
332 | /* clear drive IRQ */ | 333 | /* clear drive IRQ */ |
333 | (void)hwif->read_status(hwif); | 334 | (void)tp_ops->read_status(hwif); |
334 | local_irq_restore(flags); | 335 | local_irq_restore(flags); |
335 | } else { | 336 | } else { |
336 | /* drive refused ID */ | 337 | /* drive refused ID */ |
@@ -352,6 +353,7 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd) | |||
352 | static int try_to_identify (ide_drive_t *drive, u8 cmd) | 353 | static int try_to_identify (ide_drive_t *drive, u8 cmd) |
353 | { | 354 | { |
354 | ide_hwif_t *hwif = HWIF(drive); | 355 | ide_hwif_t *hwif = HWIF(drive); |
356 | const struct ide_tp_ops *tp_ops = hwif->tp_ops; | ||
355 | int retval; | 357 | int retval; |
356 | int autoprobe = 0; | 358 | int autoprobe = 0; |
357 | unsigned long cookie = 0; | 359 | unsigned long cookie = 0; |
@@ -367,7 +369,7 @@ static int try_to_identify (ide_drive_t *drive, u8 cmd) | |||
367 | autoprobe = 1; | 369 | autoprobe = 1; |
368 | cookie = probe_irq_on(); | 370 | cookie = probe_irq_on(); |
369 | } | 371 | } |
370 | hwif->set_irq(hwif, autoprobe); | 372 | tp_ops->set_irq(hwif, autoprobe); |
371 | } | 373 | } |
372 | 374 | ||
373 | retval = actual_try_to_identify(drive, cmd); | 375 | retval = actual_try_to_identify(drive, cmd); |
@@ -375,9 +377,9 @@ static int try_to_identify (ide_drive_t *drive, u8 cmd) | |||
375 | if (autoprobe) { | 377 | if (autoprobe) { |
376 | int irq; | 378 | int irq; |
377 | 379 | ||
378 | hwif->set_irq(hwif, 0); | 380 | tp_ops->set_irq(hwif, 0); |
379 | /* clear drive IRQ */ | 381 | /* clear drive IRQ */ |
380 | (void)hwif->read_status(hwif); | 382 | (void)tp_ops->read_status(hwif); |
381 | udelay(5); | 383 | udelay(5); |
382 | irq = probe_irq_off(cookie); | 384 | irq = probe_irq_off(cookie); |
383 | if (!hwif->irq) { | 385 | if (!hwif->irq) { |
@@ -402,7 +404,7 @@ static int ide_busy_sleep(ide_hwif_t *hwif) | |||
402 | 404 | ||
403 | do { | 405 | do { |
404 | msleep(50); | 406 | msleep(50); |
405 | stat = hwif->read_status(hwif); | 407 | stat = hwif->tp_ops->read_status(hwif); |
406 | if ((stat & BUSY_STAT) == 0) | 408 | if ((stat & BUSY_STAT) == 0) |
407 | return 0; | 409 | return 0; |
408 | } while (time_before(jiffies, timeout)); | 410 | } while (time_before(jiffies, timeout)); |
@@ -417,7 +419,7 @@ static u8 ide_read_device(ide_drive_t *drive) | |||
417 | memset(&task, 0, sizeof(task)); | 419 | memset(&task, 0, sizeof(task)); |
418 | task.tf_flags = IDE_TFLAG_IN_DEVICE; | 420 | task.tf_flags = IDE_TFLAG_IN_DEVICE; |
419 | 421 | ||
420 | drive->hwif->tf_read(drive, &task); | 422 | drive->hwif->tp_ops->tf_read(drive, &task); |
421 | 423 | ||
422 | return task.tf.device; | 424 | return task.tf.device; |
423 | } | 425 | } |
@@ -446,6 +448,7 @@ static u8 ide_read_device(ide_drive_t *drive) | |||
446 | static int do_probe (ide_drive_t *drive, u8 cmd) | 448 | static int do_probe (ide_drive_t *drive, u8 cmd) |
447 | { | 449 | { |
448 | ide_hwif_t *hwif = HWIF(drive); | 450 | ide_hwif_t *hwif = HWIF(drive); |
451 | const struct ide_tp_ops *tp_ops = hwif->tp_ops; | ||
449 | int rc; | 452 | int rc; |
450 | u8 stat; | 453 | u8 stat; |
451 | 454 | ||
@@ -478,7 +481,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd) | |||
478 | return 3; | 481 | return 3; |
479 | } | 482 | } |
480 | 483 | ||
481 | stat = hwif->read_status(hwif); | 484 | stat = tp_ops->read_status(hwif); |
482 | 485 | ||
483 | if (OK_STAT(stat, READY_STAT, BUSY_STAT) || | 486 | if (OK_STAT(stat, READY_STAT, BUSY_STAT) || |
484 | drive->present || cmd == WIN_PIDENTIFY) { | 487 | drive->present || cmd == WIN_PIDENTIFY) { |
@@ -488,7 +491,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd) | |||
488 | rc = try_to_identify(drive,cmd); | 491 | rc = try_to_identify(drive,cmd); |
489 | } | 492 | } |
490 | 493 | ||
491 | stat = hwif->read_status(hwif); | 494 | stat = tp_ops->read_status(hwif); |
492 | 495 | ||
493 | if (stat == (BUSY_STAT | READY_STAT)) | 496 | if (stat == (BUSY_STAT | READY_STAT)) |
494 | return 4; | 497 | return 4; |
@@ -499,13 +502,13 @@ static int do_probe (ide_drive_t *drive, u8 cmd) | |||
499 | msleep(50); | 502 | msleep(50); |
500 | SELECT_DRIVE(drive); | 503 | SELECT_DRIVE(drive); |
501 | msleep(50); | 504 | msleep(50); |
502 | hwif->exec_command(hwif, WIN_SRST); | 505 | tp_ops->exec_command(hwif, WIN_SRST); |
503 | (void)ide_busy_sleep(hwif); | 506 | (void)ide_busy_sleep(hwif); |
504 | rc = try_to_identify(drive, cmd); | 507 | rc = try_to_identify(drive, cmd); |
505 | } | 508 | } |
506 | 509 | ||
507 | /* ensure drive IRQ is clear */ | 510 | /* ensure drive IRQ is clear */ |
508 | stat = hwif->read_status(hwif); | 511 | stat = tp_ops->read_status(hwif); |
509 | 512 | ||
510 | if (rc == 1) | 513 | if (rc == 1) |
511 | printk(KERN_ERR "%s: no response (status = 0x%02x)\n", | 514 | printk(KERN_ERR "%s: no response (status = 0x%02x)\n", |
@@ -519,7 +522,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd) | |||
519 | SELECT_DRIVE(&hwif->drives[0]); | 522 | SELECT_DRIVE(&hwif->drives[0]); |
520 | msleep(50); | 523 | msleep(50); |
521 | /* ensure drive irq is clear */ | 524 | /* ensure drive irq is clear */ |
522 | (void)hwif->read_status(hwif); | 525 | (void)tp_ops->read_status(hwif); |
523 | } | 526 | } |
524 | return rc; | 527 | return rc; |
525 | } | 528 | } |
@@ -530,12 +533,13 @@ static int do_probe (ide_drive_t *drive, u8 cmd) | |||
530 | static void enable_nest (ide_drive_t *drive) | 533 | static void enable_nest (ide_drive_t *drive) |
531 | { | 534 | { |
532 | ide_hwif_t *hwif = HWIF(drive); | 535 | ide_hwif_t *hwif = HWIF(drive); |
536 | const struct ide_tp_ops *tp_ops = hwif->tp_ops; | ||
533 | u8 stat; | 537 | u8 stat; |
534 | 538 | ||
535 | printk("%s: enabling %s -- ", hwif->name, drive->id->model); | 539 | printk("%s: enabling %s -- ", hwif->name, drive->id->model); |
536 | SELECT_DRIVE(drive); | 540 | SELECT_DRIVE(drive); |
537 | msleep(50); | 541 | msleep(50); |
538 | hwif->exec_command(hwif, EXABYTE_ENABLE_NEST); | 542 | tp_ops->exec_command(hwif, EXABYTE_ENABLE_NEST); |
539 | 543 | ||
540 | if (ide_busy_sleep(hwif)) { | 544 | if (ide_busy_sleep(hwif)) { |
541 | printk(KERN_CONT "failed (timeout)\n"); | 545 | printk(KERN_CONT "failed (timeout)\n"); |
@@ -544,7 +548,7 @@ static void enable_nest (ide_drive_t *drive) | |||
544 | 548 | ||
545 | msleep(50); | 549 | msleep(50); |
546 | 550 | ||
547 | stat = hwif->read_status(hwif); | 551 | stat = tp_ops->read_status(hwif); |
548 | 552 | ||
549 | if (!OK_STAT(stat, 0, BAD_STAT)) | 553 | if (!OK_STAT(stat, 0, BAD_STAT)) |
550 | printk(KERN_CONT "failed (status = 0x%02x)\n", stat); | 554 | printk(KERN_CONT "failed (status = 0x%02x)\n", stat); |
@@ -726,7 +730,7 @@ static int ide_port_wait_ready(ide_hwif_t *hwif) | |||
726 | /* Ignore disks that we will not probe for later. */ | 730 | /* Ignore disks that we will not probe for later. */ |
727 | if (!drive->noprobe || drive->present) { | 731 | if (!drive->noprobe || drive->present) { |
728 | SELECT_DRIVE(drive); | 732 | SELECT_DRIVE(drive); |
729 | hwif->set_irq(hwif, 1); | 733 | hwif->tp_ops->set_irq(hwif, 1); |
730 | mdelay(2); | 734 | mdelay(2); |
731 | rc = ide_wait_not_busy(hwif, 35000); | 735 | rc = ide_wait_not_busy(hwif, 35000); |
732 | if (rc) | 736 | if (rc) |
@@ -1083,7 +1087,7 @@ static int init_irq (ide_hwif_t *hwif) | |||
1083 | sa = IRQF_SHARED; | 1087 | sa = IRQF_SHARED; |
1084 | 1088 | ||
1085 | if (io_ports->ctl_addr) | 1089 | if (io_ports->ctl_addr) |
1086 | hwif->set_irq(hwif, 1); | 1090 | hwif->tp_ops->set_irq(hwif, 1); |
1087 | 1091 | ||
1088 | if (request_irq(hwif->irq,&ide_intr,sa,hwif->name,hwgroup)) | 1092 | if (request_irq(hwif->irq,&ide_intr,sa,hwif->name,hwgroup)) |
1089 | goto out_unlink; | 1093 | goto out_unlink; |
@@ -1361,6 +1365,9 @@ static void ide_init_port(ide_hwif_t *hwif, unsigned int port, | |||
1361 | hwif->host_flags |= d->host_flags; | 1365 | hwif->host_flags |= d->host_flags; |
1362 | hwif->pio_mask = d->pio_mask; | 1366 | hwif->pio_mask = d->pio_mask; |
1363 | 1367 | ||
1368 | if (d->tp_ops) | ||
1369 | hwif->tp_ops = d->tp_ops; | ||
1370 | |||
1364 | /* ->set_pio_mode for DTC2278 is currently limited to port 0 */ | 1371 | /* ->set_pio_mode for DTC2278 is currently limited to port 0 */ |
1365 | if (hwif->chipset != ide_dtc2278 || hwif->channel == 0) | 1372 | if (hwif->chipset != ide_dtc2278 || hwif->channel == 0) |
1366 | hwif->port_ops = d->port_ops; | 1373 | hwif->port_ops = d->port_ops; |