diff options
Diffstat (limited to 'drivers/ide/ide.c')
| -rw-r--r-- | drivers/ide/ide.c | 419 |
1 files changed, 95 insertions, 324 deletions
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index fc69fe2e3ec0..917c72dcd33d 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c | |||
| @@ -78,6 +78,8 @@ | |||
| 78 | /* default maximum number of failures */ | 78 | /* default maximum number of failures */ |
| 79 | #define IDE_DEFAULT_MAX_FAILURES 1 | 79 | #define IDE_DEFAULT_MAX_FAILURES 1 |
| 80 | 80 | ||
| 81 | struct class *ide_port_class; | ||
| 82 | |||
| 81 | static const u8 ide_hwif_to_major[] = { IDE0_MAJOR, IDE1_MAJOR, | 83 | static const u8 ide_hwif_to_major[] = { IDE0_MAJOR, IDE1_MAJOR, |
| 82 | IDE2_MAJOR, IDE3_MAJOR, | 84 | IDE2_MAJOR, IDE3_MAJOR, |
| 83 | IDE4_MAJOR, IDE5_MAJOR, | 85 | IDE4_MAJOR, IDE5_MAJOR, |
| @@ -90,10 +92,6 @@ static int system_bus_speed; /* holds what we think is VESA/PCI bus speed */ | |||
| 90 | DEFINE_MUTEX(ide_cfg_mtx); | 92 | DEFINE_MUTEX(ide_cfg_mtx); |
| 91 | __cacheline_aligned_in_smp DEFINE_SPINLOCK(ide_lock); | 93 | __cacheline_aligned_in_smp DEFINE_SPINLOCK(ide_lock); |
| 92 | 94 | ||
| 93 | #ifdef CONFIG_IDEPCI_PCIBUS_ORDER | ||
| 94 | int ide_scan_direction; /* THIS was formerly 2.2.x pci=reverse */ | ||
| 95 | #endif | ||
| 96 | |||
| 97 | int noautodma = 0; | 95 | int noautodma = 0; |
| 98 | 96 | ||
| 99 | #ifdef CONFIG_BLK_DEV_IDEACPI | 97 | #ifdef CONFIG_BLK_DEV_IDEACPI |
| @@ -109,13 +107,13 @@ ide_hwif_t ide_hwifs[MAX_HWIFS]; /* master data repository */ | |||
| 109 | 107 | ||
| 110 | EXPORT_SYMBOL(ide_hwifs); | 108 | EXPORT_SYMBOL(ide_hwifs); |
| 111 | 109 | ||
| 110 | static void ide_port_init_devices_data(ide_hwif_t *); | ||
| 111 | |||
| 112 | /* | 112 | /* |
| 113 | * Do not even *think* about calling this! | 113 | * Do not even *think* about calling this! |
| 114 | */ | 114 | */ |
| 115 | void ide_init_port_data(ide_hwif_t *hwif, unsigned int index) | 115 | void ide_init_port_data(ide_hwif_t *hwif, unsigned int index) |
| 116 | { | 116 | { |
| 117 | unsigned int unit; | ||
| 118 | |||
| 119 | /* bulk initialize hwif & drive info with zeros */ | 117 | /* bulk initialize hwif & drive info with zeros */ |
| 120 | memset(hwif, 0, sizeof(ide_hwif_t)); | 118 | memset(hwif, 0, sizeof(ide_hwif_t)); |
| 121 | 119 | ||
| @@ -134,8 +132,20 @@ void ide_init_port_data(ide_hwif_t *hwif, unsigned int index) | |||
| 134 | 132 | ||
| 135 | default_hwif_iops(hwif); | 133 | default_hwif_iops(hwif); |
| 136 | default_hwif_transport(hwif); | 134 | default_hwif_transport(hwif); |
| 135 | |||
| 136 | ide_port_init_devices_data(hwif); | ||
| 137 | } | ||
| 138 | EXPORT_SYMBOL_GPL(ide_init_port_data); | ||
| 139 | |||
| 140 | static void ide_port_init_devices_data(ide_hwif_t *hwif) | ||
| 141 | { | ||
| 142 | int unit; | ||
| 143 | |||
| 137 | for (unit = 0; unit < MAX_DRIVES; ++unit) { | 144 | for (unit = 0; unit < MAX_DRIVES; ++unit) { |
| 138 | ide_drive_t *drive = &hwif->drives[unit]; | 145 | ide_drive_t *drive = &hwif->drives[unit]; |
| 146 | u8 j = (hwif->index * MAX_DRIVES) + unit; | ||
| 147 | |||
| 148 | memset(drive, 0, sizeof(*drive)); | ||
| 139 | 149 | ||
| 140 | drive->media = ide_disk; | 150 | drive->media = ide_disk; |
| 141 | drive->select.all = (unit<<4)|0xa0; | 151 | drive->select.all = (unit<<4)|0xa0; |
| @@ -147,32 +157,13 @@ void ide_init_port_data(ide_hwif_t *hwif, unsigned int index) | |||
| 147 | drive->special.b.set_geometry = 1; | 157 | drive->special.b.set_geometry = 1; |
| 148 | drive->name[0] = 'h'; | 158 | drive->name[0] = 'h'; |
| 149 | drive->name[1] = 'd'; | 159 | drive->name[1] = 'd'; |
| 150 | drive->name[2] = 'a' + (index * MAX_DRIVES) + unit; | 160 | drive->name[2] = 'a' + j; |
| 151 | drive->max_failures = IDE_DEFAULT_MAX_FAILURES; | 161 | drive->max_failures = IDE_DEFAULT_MAX_FAILURES; |
| 152 | drive->using_dma = 0; | 162 | |
| 153 | drive->vdma = 0; | ||
| 154 | INIT_LIST_HEAD(&drive->list); | 163 | INIT_LIST_HEAD(&drive->list); |
| 155 | init_completion(&drive->gendev_rel_comp); | 164 | init_completion(&drive->gendev_rel_comp); |
| 156 | } | 165 | } |
| 157 | } | 166 | } |
| 158 | EXPORT_SYMBOL_GPL(ide_init_port_data); | ||
| 159 | |||
| 160 | static void init_hwif_default(ide_hwif_t *hwif, unsigned int index) | ||
| 161 | { | ||
| 162 | hw_regs_t hw; | ||
| 163 | |||
| 164 | memset(&hw, 0, sizeof(hw_regs_t)); | ||
| 165 | |||
| 166 | ide_init_hwif_ports(&hw, ide_default_io_base(index), 0, &hwif->irq); | ||
| 167 | |||
| 168 | memcpy(hwif->io_ports, hw.io_ports, sizeof(hw.io_ports)); | ||
| 169 | |||
| 170 | hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET]; | ||
| 171 | #ifdef CONFIG_BLK_DEV_HD | ||
| 172 | if (hwif->io_ports[IDE_DATA_OFFSET] == HD_DATA) | ||
| 173 | hwif->noprobe = 1; /* may be overridden by ide_setup() */ | ||
| 174 | #endif | ||
| 175 | } | ||
| 176 | 167 | ||
| 177 | /* | 168 | /* |
| 178 | * init_ide_data() sets reasonable default values into all fields | 169 | * init_ide_data() sets reasonable default values into all fields |
| @@ -194,7 +185,6 @@ static void init_hwif_default(ide_hwif_t *hwif, unsigned int index) | |||
| 194 | #define MAGIC_COOKIE 0x12345678 | 185 | #define MAGIC_COOKIE 0x12345678 |
| 195 | static void __init init_ide_data (void) | 186 | static void __init init_ide_data (void) |
| 196 | { | 187 | { |
| 197 | ide_hwif_t *hwif; | ||
| 198 | unsigned int index; | 188 | unsigned int index; |
| 199 | static unsigned long magic_cookie = MAGIC_COOKIE; | 189 | static unsigned long magic_cookie = MAGIC_COOKIE; |
| 200 | 190 | ||
| @@ -204,13 +194,9 @@ static void __init init_ide_data (void) | |||
| 204 | 194 | ||
| 205 | /* Initialise all interface structures */ | 195 | /* Initialise all interface structures */ |
| 206 | for (index = 0; index < MAX_HWIFS; ++index) { | 196 | for (index = 0; index < MAX_HWIFS; ++index) { |
| 207 | hwif = &ide_hwifs[index]; | 197 | ide_hwif_t *hwif = &ide_hwifs[index]; |
| 198 | |||
| 208 | ide_init_port_data(hwif, index); | 199 | ide_init_port_data(hwif, index); |
| 209 | init_hwif_default(hwif, index); | ||
| 210 | #if !defined(CONFIG_PPC32) || !defined(CONFIG_PCI) | ||
| 211 | hwif->irq = | ||
| 212 | ide_init_default_irq(hwif->io_ports[IDE_DATA_OFFSET]); | ||
| 213 | #endif | ||
| 214 | } | 200 | } |
| 215 | } | 201 | } |
| 216 | 202 | ||
| @@ -259,7 +245,7 @@ ide_hwif_t * ide_find_port(unsigned long base) | |||
| 259 | 245 | ||
| 260 | for (i = 0; i < MAX_HWIFS; i++) { | 246 | for (i = 0; i < MAX_HWIFS; i++) { |
| 261 | hwif = &ide_hwifs[i]; | 247 | hwif = &ide_hwifs[i]; |
| 262 | if (hwif->io_ports[IDE_DATA_OFFSET] == 0) | 248 | if (hwif->chipset == ide_unknown) |
| 263 | goto found; | 249 | goto found; |
| 264 | } | 250 | } |
| 265 | 251 | ||
| @@ -357,108 +343,6 @@ void ide_hwif_release_regions(ide_hwif_t *hwif) | |||
| 357 | release_region(hwif->io_ports[i], 1); | 343 | release_region(hwif->io_ports[i], 1); |
| 358 | } | 344 | } |
| 359 | 345 | ||
| 360 | /** | ||
| 361 | * ide_hwif_restore - restore hwif to template | ||
| 362 | * @hwif: hwif to update | ||
| 363 | * @tmp_hwif: template | ||
| 364 | * | ||
| 365 | * Restore hwif to a previous state by copying most settings | ||
| 366 | * from the template. | ||
| 367 | */ | ||
| 368 | |||
| 369 | static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif) | ||
| 370 | { | ||
| 371 | hwif->hwgroup = tmp_hwif->hwgroup; | ||
| 372 | |||
| 373 | hwif->gendev.parent = tmp_hwif->gendev.parent; | ||
| 374 | |||
| 375 | hwif->proc = tmp_hwif->proc; | ||
| 376 | |||
| 377 | hwif->major = tmp_hwif->major; | ||
| 378 | hwif->straight8 = tmp_hwif->straight8; | ||
| 379 | hwif->bus_state = tmp_hwif->bus_state; | ||
| 380 | |||
| 381 | hwif->host_flags = tmp_hwif->host_flags; | ||
| 382 | |||
| 383 | hwif->pio_mask = tmp_hwif->pio_mask; | ||
| 384 | |||
| 385 | hwif->ultra_mask = tmp_hwif->ultra_mask; | ||
| 386 | hwif->mwdma_mask = tmp_hwif->mwdma_mask; | ||
| 387 | hwif->swdma_mask = tmp_hwif->swdma_mask; | ||
| 388 | |||
| 389 | hwif->cbl = tmp_hwif->cbl; | ||
| 390 | |||
| 391 | hwif->chipset = tmp_hwif->chipset; | ||
| 392 | hwif->hold = tmp_hwif->hold; | ||
| 393 | |||
| 394 | hwif->dev = tmp_hwif->dev; | ||
| 395 | |||
| 396 | #ifdef CONFIG_BLK_DEV_IDEPCI | ||
| 397 | hwif->cds = tmp_hwif->cds; | ||
| 398 | #endif | ||
| 399 | |||
| 400 | hwif->set_pio_mode = tmp_hwif->set_pio_mode; | ||
| 401 | hwif->set_dma_mode = tmp_hwif->set_dma_mode; | ||
| 402 | hwif->mdma_filter = tmp_hwif->mdma_filter; | ||
| 403 | hwif->udma_filter = tmp_hwif->udma_filter; | ||
| 404 | hwif->selectproc = tmp_hwif->selectproc; | ||
| 405 | hwif->reset_poll = tmp_hwif->reset_poll; | ||
| 406 | hwif->pre_reset = tmp_hwif->pre_reset; | ||
| 407 | hwif->resetproc = tmp_hwif->resetproc; | ||
| 408 | hwif->maskproc = tmp_hwif->maskproc; | ||
| 409 | hwif->quirkproc = tmp_hwif->quirkproc; | ||
| 410 | hwif->busproc = tmp_hwif->busproc; | ||
| 411 | |||
| 412 | hwif->ata_input_data = tmp_hwif->ata_input_data; | ||
| 413 | hwif->ata_output_data = tmp_hwif->ata_output_data; | ||
| 414 | hwif->atapi_input_bytes = tmp_hwif->atapi_input_bytes; | ||
| 415 | hwif->atapi_output_bytes = tmp_hwif->atapi_output_bytes; | ||
| 416 | |||
| 417 | hwif->dma_host_set = tmp_hwif->dma_host_set; | ||
| 418 | hwif->dma_setup = tmp_hwif->dma_setup; | ||
| 419 | hwif->dma_exec_cmd = tmp_hwif->dma_exec_cmd; | ||
| 420 | hwif->dma_start = tmp_hwif->dma_start; | ||
| 421 | hwif->ide_dma_end = tmp_hwif->ide_dma_end; | ||
| 422 | hwif->ide_dma_test_irq = tmp_hwif->ide_dma_test_irq; | ||
| 423 | hwif->ide_dma_clear_irq = tmp_hwif->ide_dma_clear_irq; | ||
| 424 | hwif->dma_lost_irq = tmp_hwif->dma_lost_irq; | ||
| 425 | hwif->dma_timeout = tmp_hwif->dma_timeout; | ||
| 426 | |||
| 427 | hwif->OUTB = tmp_hwif->OUTB; | ||
| 428 | hwif->OUTBSYNC = tmp_hwif->OUTBSYNC; | ||
| 429 | hwif->OUTW = tmp_hwif->OUTW; | ||
| 430 | hwif->OUTSW = tmp_hwif->OUTSW; | ||
| 431 | hwif->OUTSL = tmp_hwif->OUTSL; | ||
| 432 | |||
| 433 | hwif->INB = tmp_hwif->INB; | ||
| 434 | hwif->INW = tmp_hwif->INW; | ||
| 435 | hwif->INSW = tmp_hwif->INSW; | ||
| 436 | hwif->INSL = tmp_hwif->INSL; | ||
| 437 | |||
| 438 | hwif->sg_max_nents = tmp_hwif->sg_max_nents; | ||
| 439 | |||
| 440 | hwif->mmio = tmp_hwif->mmio; | ||
| 441 | hwif->rqsize = tmp_hwif->rqsize; | ||
| 442 | |||
| 443 | #ifndef CONFIG_BLK_DEV_IDECS | ||
| 444 | hwif->irq = tmp_hwif->irq; | ||
| 445 | #endif | ||
| 446 | |||
| 447 | hwif->dma_base = tmp_hwif->dma_base; | ||
| 448 | hwif->dma_command = tmp_hwif->dma_command; | ||
| 449 | hwif->dma_vendor1 = tmp_hwif->dma_vendor1; | ||
| 450 | hwif->dma_status = tmp_hwif->dma_status; | ||
| 451 | hwif->dma_vendor3 = tmp_hwif->dma_vendor3; | ||
| 452 | hwif->dma_prdtable = tmp_hwif->dma_prdtable; | ||
| 453 | |||
| 454 | hwif->config_data = tmp_hwif->config_data; | ||
| 455 | hwif->select_data = tmp_hwif->select_data; | ||
| 456 | hwif->extra_base = tmp_hwif->extra_base; | ||
| 457 | hwif->extra_ports = tmp_hwif->extra_ports; | ||
| 458 | |||
| 459 | hwif->hwif_data = tmp_hwif->hwif_data; | ||
| 460 | } | ||
| 461 | |||
| 462 | void ide_remove_port_from_hwgroup(ide_hwif_t *hwif) | 346 | void ide_remove_port_from_hwgroup(ide_hwif_t *hwif) |
| 463 | { | 347 | { |
| 464 | ide_hwgroup_t *hwgroup = hwif->hwgroup; | 348 | ide_hwgroup_t *hwgroup = hwif->hwgroup; |
| @@ -494,11 +378,38 @@ void ide_remove_port_from_hwgroup(ide_hwif_t *hwif) | |||
| 494 | spin_unlock_irq(&ide_lock); | 378 | spin_unlock_irq(&ide_lock); |
| 495 | } | 379 | } |
| 496 | 380 | ||
| 381 | /* Called with ide_lock held. */ | ||
| 382 | static void __ide_port_unregister_devices(ide_hwif_t *hwif) | ||
| 383 | { | ||
| 384 | int i; | ||
| 385 | |||
| 386 | for (i = 0; i < MAX_DRIVES; i++) { | ||
| 387 | ide_drive_t *drive = &hwif->drives[i]; | ||
| 388 | |||
| 389 | if (drive->present) { | ||
| 390 | spin_unlock_irq(&ide_lock); | ||
| 391 | device_unregister(&drive->gendev); | ||
| 392 | wait_for_completion(&drive->gendev_rel_comp); | ||
| 393 | spin_lock_irq(&ide_lock); | ||
| 394 | } | ||
| 395 | } | ||
| 396 | } | ||
| 397 | |||
| 398 | void ide_port_unregister_devices(ide_hwif_t *hwif) | ||
| 399 | { | ||
| 400 | mutex_lock(&ide_cfg_mtx); | ||
| 401 | spin_lock_irq(&ide_lock); | ||
| 402 | __ide_port_unregister_devices(hwif); | ||
| 403 | hwif->present = 0; | ||
| 404 | ide_port_init_devices_data(hwif); | ||
| 405 | spin_unlock_irq(&ide_lock); | ||
| 406 | mutex_unlock(&ide_cfg_mtx); | ||
| 407 | } | ||
| 408 | EXPORT_SYMBOL_GPL(ide_port_unregister_devices); | ||
| 409 | |||
| 497 | /** | 410 | /** |
| 498 | * ide_unregister - free an IDE interface | 411 | * ide_unregister - free an IDE interface |
| 499 | * @index: index of interface (will change soon to a pointer) | 412 | * @index: index of interface (will change soon to a pointer) |
| 500 | * @init_default: init default hwif flag | ||
| 501 | * @restore: restore hwif flag | ||
| 502 | * | 413 | * |
| 503 | * Perform the final unregister of an IDE interface. At the moment | 414 | * Perform the final unregister of an IDE interface. At the moment |
| 504 | * we don't refcount interfaces so this will also get split up. | 415 | * we don't refcount interfaces so this will also get split up. |
| @@ -518,13 +429,11 @@ void ide_remove_port_from_hwgroup(ide_hwif_t *hwif) | |||
| 518 | * This is raving bonkers. | 429 | * This is raving bonkers. |
| 519 | */ | 430 | */ |
| 520 | 431 | ||
| 521 | void ide_unregister(unsigned int index, int init_default, int restore) | 432 | void ide_unregister(unsigned int index) |
| 522 | { | 433 | { |
| 523 | ide_drive_t *drive; | ||
| 524 | ide_hwif_t *hwif, *g; | 434 | ide_hwif_t *hwif, *g; |
| 525 | static ide_hwif_t tmp_hwif; /* protected by ide_cfg_mtx */ | ||
| 526 | ide_hwgroup_t *hwgroup; | 435 | ide_hwgroup_t *hwgroup; |
| 527 | int irq_count = 0, unit; | 436 | int irq_count = 0; |
| 528 | 437 | ||
| 529 | BUG_ON(index >= MAX_HWIFS); | 438 | BUG_ON(index >= MAX_HWIFS); |
| 530 | 439 | ||
| @@ -535,15 +444,7 @@ void ide_unregister(unsigned int index, int init_default, int restore) | |||
| 535 | hwif = &ide_hwifs[index]; | 444 | hwif = &ide_hwifs[index]; |
| 536 | if (!hwif->present) | 445 | if (!hwif->present) |
| 537 | goto abort; | 446 | goto abort; |
| 538 | for (unit = 0; unit < MAX_DRIVES; ++unit) { | 447 | __ide_port_unregister_devices(hwif); |
| 539 | drive = &hwif->drives[unit]; | ||
| 540 | if (!drive->present) | ||
| 541 | continue; | ||
| 542 | spin_unlock_irq(&ide_lock); | ||
| 543 | device_unregister(&drive->gendev); | ||
| 544 | wait_for_completion(&drive->gendev_rel_comp); | ||
| 545 | spin_lock_irq(&ide_lock); | ||
| 546 | } | ||
| 547 | hwif->present = 0; | 448 | hwif->present = 0; |
| 548 | 449 | ||
| 549 | spin_unlock_irq(&ide_lock); | 450 | spin_unlock_irq(&ide_lock); |
| @@ -565,6 +466,7 @@ void ide_unregister(unsigned int index, int init_default, int restore) | |||
| 565 | 466 | ||
| 566 | ide_remove_port_from_hwgroup(hwif); | 467 | ide_remove_port_from_hwgroup(hwif); |
| 567 | 468 | ||
| 469 | device_unregister(hwif->portdev); | ||
| 568 | device_unregister(&hwif->gendev); | 470 | device_unregister(&hwif->gendev); |
| 569 | wait_for_completion(&hwif->gendev_rel_comp); | 471 | wait_for_completion(&hwif->gendev_rel_comp); |
| 570 | 472 | ||
| @@ -576,34 +478,14 @@ void ide_unregister(unsigned int index, int init_default, int restore) | |||
| 576 | unregister_blkdev(hwif->major, hwif->name); | 478 | unregister_blkdev(hwif->major, hwif->name); |
| 577 | spin_lock_irq(&ide_lock); | 479 | spin_lock_irq(&ide_lock); |
| 578 | 480 | ||
| 579 | if (hwif->dma_base) { | 481 | if (hwif->dma_base) |
| 580 | (void) ide_release_dma(hwif); | 482 | (void)ide_release_dma(hwif); |
| 581 | |||
| 582 | hwif->dma_base = 0; | ||
| 583 | hwif->dma_command = 0; | ||
| 584 | hwif->dma_vendor1 = 0; | ||
| 585 | hwif->dma_status = 0; | ||
| 586 | hwif->dma_vendor3 = 0; | ||
| 587 | hwif->dma_prdtable = 0; | ||
| 588 | |||
| 589 | hwif->extra_base = 0; | ||
| 590 | hwif->extra_ports = 0; | ||
| 591 | } | ||
| 592 | 483 | ||
| 593 | ide_hwif_release_regions(hwif); | 484 | ide_hwif_release_regions(hwif); |
| 594 | 485 | ||
| 595 | /* copy original settings */ | ||
| 596 | tmp_hwif = *hwif; | ||
| 597 | |||
| 598 | /* restore hwif data to pristine status */ | 486 | /* restore hwif data to pristine status */ |
| 599 | ide_init_port_data(hwif, index); | 487 | ide_init_port_data(hwif, index); |
| 600 | 488 | ||
| 601 | if (init_default) | ||
| 602 | init_hwif_default(hwif, index); | ||
| 603 | |||
| 604 | if (restore) | ||
| 605 | ide_hwif_restore(hwif, &tmp_hwif); | ||
| 606 | |||
| 607 | abort: | 489 | abort: |
| 608 | spin_unlock_irq(&ide_lock); | 490 | spin_unlock_irq(&ide_lock); |
| 609 | mutex_unlock(&ide_cfg_mtx); | 491 | mutex_unlock(&ide_cfg_mtx); |
| @@ -622,79 +504,6 @@ void ide_init_port_hw(ide_hwif_t *hwif, hw_regs_t *hw) | |||
| 622 | } | 504 | } |
| 623 | EXPORT_SYMBOL_GPL(ide_init_port_hw); | 505 | EXPORT_SYMBOL_GPL(ide_init_port_hw); |
| 624 | 506 | ||
| 625 | ide_hwif_t *ide_deprecated_find_port(unsigned long base) | ||
| 626 | { | ||
| 627 | ide_hwif_t *hwif; | ||
| 628 | int i; | ||
| 629 | |||
| 630 | for (i = 0; i < MAX_HWIFS; i++) { | ||
| 631 | hwif = &ide_hwifs[i]; | ||
| 632 | if (hwif->io_ports[IDE_DATA_OFFSET] == base) | ||
| 633 | goto found; | ||
| 634 | } | ||
| 635 | |||
| 636 | for (i = 0; i < MAX_HWIFS; i++) { | ||
| 637 | hwif = &ide_hwifs[i]; | ||
| 638 | if (hwif->hold) | ||
| 639 | continue; | ||
| 640 | if (!hwif->present && hwif->mate == NULL) | ||
| 641 | goto found; | ||
| 642 | } | ||
| 643 | |||
| 644 | hwif = NULL; | ||
| 645 | found: | ||
| 646 | return hwif; | ||
| 647 | } | ||
| 648 | EXPORT_SYMBOL_GPL(ide_deprecated_find_port); | ||
| 649 | |||
| 650 | /** | ||
| 651 | * ide_register_hw - register IDE interface | ||
| 652 | * @hw: hardware registers | ||
| 653 | * @quirkproc: quirkproc function | ||
| 654 | * @hwifp: pointer to returned hwif | ||
| 655 | * | ||
| 656 | * Register an IDE interface, specifying exactly the registers etc. | ||
| 657 | * | ||
| 658 | * Returns -1 on error. | ||
| 659 | */ | ||
| 660 | |||
| 661 | int ide_register_hw(hw_regs_t *hw, void (*quirkproc)(ide_drive_t *), | ||
| 662 | ide_hwif_t **hwifp) | ||
| 663 | { | ||
| 664 | int index, retry = 1; | ||
| 665 | ide_hwif_t *hwif; | ||
| 666 | u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; | ||
| 667 | |||
| 668 | do { | ||
| 669 | hwif = ide_deprecated_find_port(hw->io_ports[IDE_DATA_OFFSET]); | ||
| 670 | if (hwif) | ||
| 671 | goto found; | ||
| 672 | for (index = 0; index < MAX_HWIFS; index++) | ||
| 673 | ide_unregister(index, 1, 1); | ||
| 674 | } while (retry--); | ||
| 675 | return -1; | ||
| 676 | found: | ||
| 677 | index = hwif->index; | ||
| 678 | if (hwif->present) | ||
| 679 | ide_unregister(index, 0, 1); | ||
| 680 | else if (!hwif->hold) | ||
| 681 | ide_init_port_data(hwif, index); | ||
| 682 | |||
| 683 | ide_init_port_hw(hwif, hw); | ||
| 684 | hwif->quirkproc = quirkproc; | ||
| 685 | |||
| 686 | idx[0] = index; | ||
| 687 | |||
| 688 | ide_device_add(idx, NULL); | ||
| 689 | |||
| 690 | if (hwifp) | ||
| 691 | *hwifp = hwif; | ||
| 692 | |||
| 693 | return hwif->present ? index : -1; | ||
| 694 | } | ||
| 695 | |||
| 696 | EXPORT_SYMBOL(ide_register_hw); | ||
| 697 | |||
| 698 | /* | 507 | /* |
| 699 | * Locks for IDE setting functionality | 508 | * Locks for IDE setting functionality |
| 700 | */ | 509 | */ |
| @@ -997,27 +806,6 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device | |||
| 997 | if (!capable(CAP_SYS_RAWIO)) | 806 | if (!capable(CAP_SYS_RAWIO)) |
| 998 | return -EACCES; | 807 | return -EACCES; |
| 999 | return ide_task_ioctl(drive, cmd, arg); | 808 | return ide_task_ioctl(drive, cmd, arg); |
| 1000 | |||
| 1001 | case HDIO_SCAN_HWIF: | ||
| 1002 | { | ||
| 1003 | hw_regs_t hw; | ||
| 1004 | int args[3]; | ||
| 1005 | if (!capable(CAP_SYS_RAWIO)) return -EACCES; | ||
| 1006 | if (copy_from_user(args, p, 3 * sizeof(int))) | ||
| 1007 | return -EFAULT; | ||
| 1008 | memset(&hw, 0, sizeof(hw)); | ||
| 1009 | ide_init_hwif_ports(&hw, (unsigned long) args[0], | ||
| 1010 | (unsigned long) args[1], NULL); | ||
| 1011 | hw.irq = args[2]; | ||
| 1012 | if (ide_register_hw(&hw, NULL, NULL) == -1) | ||
| 1013 | return -EIO; | ||
| 1014 | return 0; | ||
| 1015 | } | ||
| 1016 | case HDIO_UNREGISTER_HWIF: | ||
| 1017 | if (!capable(CAP_SYS_RAWIO)) return -EACCES; | ||
| 1018 | /* (arg > MAX_HWIFS) checked in function */ | ||
| 1019 | ide_unregister(arg, 1, 1); | ||
| 1020 | return 0; | ||
| 1021 | case HDIO_SET_NICE: | 809 | case HDIO_SET_NICE: |
| 1022 | if (!capable(CAP_SYS_ADMIN)) return -EACCES; | 810 | if (!capable(CAP_SYS_ADMIN)) return -EACCES; |
| 1023 | if (arg != (arg & ((1 << IDE_NICE_DSC_OVERLAP) | (1 << IDE_NICE_1)))) | 811 | if (arg != (arg & ((1 << IDE_NICE_DSC_OVERLAP) | (1 << IDE_NICE_1)))) |
| @@ -1071,8 +859,6 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device | |||
| 1071 | case HDIO_SET_BUSSTATE: | 859 | case HDIO_SET_BUSSTATE: |
| 1072 | if (!capable(CAP_SYS_ADMIN)) | 860 | if (!capable(CAP_SYS_ADMIN)) |
| 1073 | return -EACCES; | 861 | return -EACCES; |
| 1074 | if (HWIF(drive)->busproc) | ||
| 1075 | return HWIF(drive)->busproc(drive, (int)arg); | ||
| 1076 | return -EOPNOTSUPP; | 862 | return -EOPNOTSUPP; |
| 1077 | default: | 863 | default: |
| 1078 | return -EINVAL; | 864 | return -EINVAL; |
| @@ -1173,8 +959,9 @@ extern int probe_dtc2278; | |||
| 1173 | extern int probe_ht6560b; | 959 | extern int probe_ht6560b; |
| 1174 | extern int probe_qd65xx; | 960 | extern int probe_qd65xx; |
| 1175 | extern int cmd640_vlb; | 961 | extern int cmd640_vlb; |
| 962 | extern int probe_4drives; | ||
| 1176 | 963 | ||
| 1177 | static int __initdata is_chipset_set[MAX_HWIFS]; | 964 | static int __initdata is_chipset_set; |
| 1178 | 965 | ||
| 1179 | /* | 966 | /* |
| 1180 | * ide_setup() gets called VERY EARLY during initialization, | 967 | * ide_setup() gets called VERY EARLY during initialization, |
| @@ -1217,14 +1004,6 @@ static int __init ide_setup(char *s) | |||
| 1217 | goto obsolete_option; | 1004 | goto obsolete_option; |
| 1218 | } | 1005 | } |
| 1219 | 1006 | ||
| 1220 | #ifdef CONFIG_IDEPCI_PCIBUS_ORDER | ||
| 1221 | if (!strcmp(s, "ide=reverse")) { | ||
| 1222 | ide_scan_direction = 1; | ||
| 1223 | printk(" : Enabled support for IDE inverse scan order.\n"); | ||
| 1224 | goto obsolete_option; | ||
| 1225 | } | ||
| 1226 | #endif | ||
| 1227 | |||
| 1228 | #ifdef CONFIG_BLK_DEV_IDEACPI | 1007 | #ifdef CONFIG_BLK_DEV_IDEACPI |
| 1229 | if (!strcmp(s, "ide=noacpi")) { | 1008 | if (!strcmp(s, "ide=noacpi")) { |
| 1230 | //printk(" : Disable IDE ACPI support.\n"); | 1009 | //printk(" : Disable IDE ACPI support.\n"); |
| @@ -1335,13 +1114,11 @@ static int __init ide_setup(char *s) | |||
| 1335 | * (-8, -9, -10) are reserved to ease the hardcoding. | 1114 | * (-8, -9, -10) are reserved to ease the hardcoding. |
| 1336 | */ | 1115 | */ |
| 1337 | static const char *ide_words[] = { | 1116 | static const char *ide_words[] = { |
| 1338 | "noprobe", "serialize", "minus3", "minus4", | 1117 | "minus1", "serialize", "minus3", "minus4", |
| 1339 | "reset", "minus6", "ata66", "minus8", "minus9", | 1118 | "reset", "minus6", "ata66", "minus8", "minus9", |
| 1340 | "minus10", "four", "qd65xx", "ht6560b", "cmd640_vlb", | 1119 | "minus10", "four", "qd65xx", "ht6560b", "cmd640_vlb", |
| 1341 | "dtc2278", "umc8672", "ali14xx", NULL }; | 1120 | "dtc2278", "umc8672", "ali14xx", NULL }; |
| 1342 | 1121 | ||
| 1343 | hw_regs_t hwregs; | ||
| 1344 | |||
| 1345 | hw = s[3] - '0'; | 1122 | hw = s[3] - '0'; |
| 1346 | hwif = &ide_hwifs[hw]; | 1123 | hwif = &ide_hwifs[hw]; |
| 1347 | i = match_parm(&s[4], ide_words, vals, 3); | 1124 | i = match_parm(&s[4], ide_words, vals, 3); |
| @@ -1350,19 +1127,14 @@ static int __init ide_setup(char *s) | |||
| 1350 | * Cryptic check to ensure chipset not already set for hwif. | 1127 | * Cryptic check to ensure chipset not already set for hwif. |
| 1351 | * Note: we can't depend on hwif->chipset here. | 1128 | * Note: we can't depend on hwif->chipset here. |
| 1352 | */ | 1129 | */ |
| 1353 | if ((i >= -18 && i <= -11) || (i > 0 && i <= 3)) { | 1130 | if (i >= -18 && i <= -11) { |
| 1354 | /* chipset already specified */ | 1131 | /* chipset already specified */ |
| 1355 | if (is_chipset_set[hw]) | 1132 | if (is_chipset_set) |
| 1356 | goto bad_option; | 1133 | goto bad_option; |
| 1357 | if (i > -18 && i <= -11) { | 1134 | /* these drivers are for "ide0=" only */ |
| 1358 | /* these drivers are for "ide0=" only */ | 1135 | if (hw != 0) |
| 1359 | if (hw != 0) | 1136 | goto bad_hwif; |
| 1360 | goto bad_hwif; | 1137 | is_chipset_set = 1; |
| 1361 | /* chipset already specified for 2nd port */ | ||
| 1362 | if (is_chipset_set[hw+1]) | ||
| 1363 | goto bad_option; | ||
| 1364 | } | ||
| 1365 | is_chipset_set[hw] = 1; | ||
| 1366 | printk("\n"); | 1138 | printk("\n"); |
| 1367 | } | 1139 | } |
| 1368 | 1140 | ||
| @@ -1399,19 +1171,9 @@ static int __init ide_setup(char *s) | |||
| 1399 | #endif | 1171 | #endif |
| 1400 | #ifdef CONFIG_BLK_DEV_4DRIVES | 1172 | #ifdef CONFIG_BLK_DEV_4DRIVES |
| 1401 | case -11: /* "four" drives on one set of ports */ | 1173 | case -11: /* "four" drives on one set of ports */ |
| 1402 | { | 1174 | probe_4drives = 1; |
| 1403 | ide_hwif_t *mate = &ide_hwifs[hw^1]; | ||
| 1404 | mate->drives[0].select.all ^= 0x20; | ||
| 1405 | mate->drives[1].select.all ^= 0x20; | ||
| 1406 | hwif->chipset = mate->chipset = ide_4drives; | ||
| 1407 | mate->irq = hwif->irq; | ||
| 1408 | memcpy(mate->io_ports, hwif->io_ports, sizeof(hwif->io_ports)); | ||
| 1409 | hwif->mate = mate; | ||
| 1410 | mate->mate = hwif; | ||
| 1411 | hwif->serialized = mate->serialized = 1; | ||
| 1412 | goto obsolete_option; | 1175 | goto obsolete_option; |
| 1413 | } | 1176 | #endif |
| 1414 | #endif /* CONFIG_BLK_DEV_4DRIVES */ | ||
| 1415 | case -10: /* minus10 */ | 1177 | case -10: /* minus10 */ |
| 1416 | case -9: /* minus9 */ | 1178 | case -9: /* minus9 */ |
| 1417 | case -8: /* minus8 */ | 1179 | case -8: /* minus8 */ |
| @@ -1439,24 +1201,12 @@ static int __init ide_setup(char *s) | |||
| 1439 | hwif->serialized = hwif->mate->serialized = 1; | 1201 | hwif->serialized = hwif->mate->serialized = 1; |
| 1440 | goto obsolete_option; | 1202 | goto obsolete_option; |
| 1441 | 1203 | ||
| 1442 | case -1: /* "noprobe" */ | 1204 | case -1: |
| 1443 | hwif->noprobe = 1; | 1205 | case 0: |
| 1444 | goto obsolete_option; | 1206 | case 1: |
| 1445 | 1207 | case 2: | |
| 1446 | case 1: /* base */ | 1208 | case 3: |
| 1447 | vals[1] = vals[0] + 0x206; /* default ctl */ | 1209 | goto bad_option; |
| 1448 | case 2: /* base,ctl */ | ||
| 1449 | vals[2] = 0; /* default irq = probe for it */ | ||
| 1450 | case 3: /* base,ctl,irq */ | ||
| 1451 | memset(&hwregs, 0, sizeof(hwregs)); | ||
| 1452 | ide_init_hwif_ports(&hwregs, vals[0], vals[1], &hwif->irq); | ||
| 1453 | memcpy(hwif->io_ports, hwregs.io_ports, sizeof(hwif->io_ports)); | ||
| 1454 | hwif->irq = vals[2]; | ||
| 1455 | hwif->noprobe = 0; | ||
| 1456 | hwif->chipset = ide_forced; | ||
| 1457 | goto obsolete_option; | ||
| 1458 | |||
| 1459 | case 0: goto bad_option; | ||
| 1460 | default: | 1210 | default: |
| 1461 | printk(" -- SUPPORT NOT CONFIGURED IN THIS KERNEL\n"); | 1211 | printk(" -- SUPPORT NOT CONFIGURED IN THIS KERNEL\n"); |
| 1462 | return 1; | 1212 | return 1; |
| @@ -1601,6 +1351,13 @@ struct bus_type ide_bus_type = { | |||
| 1601 | 1351 | ||
| 1602 | EXPORT_SYMBOL_GPL(ide_bus_type); | 1352 | EXPORT_SYMBOL_GPL(ide_bus_type); |
| 1603 | 1353 | ||
| 1354 | static void ide_port_class_release(struct device *portdev) | ||
| 1355 | { | ||
| 1356 | ide_hwif_t *hwif = dev_get_drvdata(portdev); | ||
| 1357 | |||
| 1358 | put_device(&hwif->gendev); | ||
| 1359 | } | ||
| 1360 | |||
| 1604 | /* | 1361 | /* |
| 1605 | * This is gets invoked once during initialization, to set *everything* up | 1362 | * This is gets invoked once during initialization, to set *everything* up |
| 1606 | */ | 1363 | */ |
| @@ -1621,11 +1378,23 @@ static int __init ide_init(void) | |||
| 1621 | return ret; | 1378 | return ret; |
| 1622 | } | 1379 | } |
| 1623 | 1380 | ||
| 1381 | ide_port_class = class_create(THIS_MODULE, "ide_port"); | ||
| 1382 | if (IS_ERR(ide_port_class)) { | ||
| 1383 | ret = PTR_ERR(ide_port_class); | ||
| 1384 | goto out_port_class; | ||
| 1385 | } | ||
| 1386 | ide_port_class->dev_release = ide_port_class_release; | ||
| 1387 | |||
| 1624 | init_ide_data(); | 1388 | init_ide_data(); |
| 1625 | 1389 | ||
| 1626 | proc_ide_create(); | 1390 | proc_ide_create(); |
| 1627 | 1391 | ||
| 1628 | return 0; | 1392 | return 0; |
| 1393 | |||
| 1394 | out_port_class: | ||
| 1395 | bus_unregister(&ide_bus_type); | ||
| 1396 | |||
| 1397 | return ret; | ||
| 1629 | } | 1398 | } |
| 1630 | 1399 | ||
| 1631 | #ifdef MODULE | 1400 | #ifdef MODULE |
| @@ -1658,10 +1427,12 @@ void __exit cleanup_module (void) | |||
| 1658 | int index; | 1427 | int index; |
| 1659 | 1428 | ||
| 1660 | for (index = 0; index < MAX_HWIFS; ++index) | 1429 | for (index = 0; index < MAX_HWIFS; ++index) |
| 1661 | ide_unregister(index, 0, 0); | 1430 | ide_unregister(index); |
| 1662 | 1431 | ||
| 1663 | proc_ide_destroy(); | 1432 | proc_ide_destroy(); |
| 1664 | 1433 | ||
| 1434 | class_destroy(ide_port_class); | ||
| 1435 | |||
| 1665 | bus_unregister(&ide_bus_type); | 1436 | bus_unregister(&ide_bus_type); |
| 1666 | } | 1437 | } |
| 1667 | 1438 | ||
