aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/ide.c
diff options
context:
space:
mode:
authorBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2008-04-17 18:46:24 -0400
committerBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2008-04-17 18:46:24 -0400
commit93de00fd1c70e1a23a73a865e0f9abfe74a7a719 (patch)
tree44a0112d29bc82bb619fe4b0437a64fd92620968 /drivers/ide/ide.c
parent9a0e77f28b50128df0c9e26ae489e44e29a7270a (diff)
ide: remove broken/dangerous HDIO_[UNREGISTER,SCAN]_HWIF ioctls (take 3)
hdparm explicitely marks HDIO_[UNREGISTER,SCAN]_HWIF ioctls as DANGEROUS and given the number of bugs we can assume that there are no real users: * DMA has no chance of working because DMA resources are released by ide_unregister() and they are never allocated again. * Since ide_init_hwif_ports() is used for ->io_ports[] setup the ioctls don't work for almost all hosts with "non-standard" (== non ISA-like) layout of IDE taskfile registers (there is a lot of such host drivers). * ide_port_init_devices() is not called when probing IDE devices so: - drive->autotune is never set and IDE host/devices are not programmed for the correct PIO/DMA transfer modes (=> possible data corruption) - host specific I/O 32-bit and IRQ unmasking settings are not applied (=> possible data corruption) - host specific ->port_init_devs method is not called (=> no luck with ht6560b, qd65xx and opti621 host drivers) * ->rw_disk method is not preserved (=> no HPT3xxN chipsets support). * ->serialized flag is not preserved (=> possible data corruption when using icside, aec62xx (ATP850UF chipset), cmd640, cs5530, hpt366 (HPT3xxN chipsets), rz1000, sc1200, dtc2278 and ht6560b host drivers). * ->ack_intr method is not preserved (=> needed by ide-cris, buddha, gayle and macide host drivers). * ->sata_scr[] and sata_misc[] is cleared by ide_unregister() and it isn't initialized again (SiI3112 support needs them). * To issue an ioctl() there need to be at least one IDE device present in the system. * ->cable_detect method is not preserved + it is not called when probing IDE devices so cable detection is broken (however since DMA support is also broken it doesn't really matter ;-). * Some objects which may have already been freed in ide_unregister() are restored by ide_hwif_restore() (i.e. ->hwgroup). * ide_register_hw() may unregister unrelated IDE ports if free ide_hwifs[] slot cannot be found. * When IDE host drivers are modular unregistered port may be re-used by different host driver that owned it first causing subtle bugs. Since we now have a proper warm-plug support remove these ioctls, then remove no longer needed: - ide_register_hw() and ide_hwif_restore() functions - 'init_default' and 'restore' arguments of ide_unregister() - zeroeing of hwif->{dma,extra}_* fields in ide_unregister() As an added bonus IDE core code size shrinks by ~3kB (x86-32). v2: * fix ide_unregister() arguments in cleanup_module() (Andrew Morton). v3: * fix ide_unregister() arguments in palm_bk3710.c. Acked-by: Sergei Shtylyov <sshtylyov@ru.mvista.com> Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Diffstat (limited to 'drivers/ide/ide.c')
-rw-r--r--drivers/ide/ide.c199
1 files changed, 4 insertions, 195 deletions
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index 7e789c97a8b8..1121d9cb2a9b 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -362,107 +362,6 @@ void ide_hwif_release_regions(ide_hwif_t *hwif)
362 release_region(hwif->io_ports[i], 1); 362 release_region(hwif->io_ports[i], 1);
363} 363}
364 364
365/**
366 * ide_hwif_restore - restore hwif to template
367 * @hwif: hwif to update
368 * @tmp_hwif: template
369 *
370 * Restore hwif to a previous state by copying most settings
371 * from the template.
372 */
373
374static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif)
375{
376 hwif->hwgroup = tmp_hwif->hwgroup;
377
378 hwif->gendev.parent = tmp_hwif->gendev.parent;
379
380 hwif->proc = tmp_hwif->proc;
381
382 hwif->major = tmp_hwif->major;
383 hwif->straight8 = tmp_hwif->straight8;
384 hwif->bus_state = tmp_hwif->bus_state;
385
386 hwif->host_flags = tmp_hwif->host_flags;
387
388 hwif->pio_mask = tmp_hwif->pio_mask;
389
390 hwif->ultra_mask = tmp_hwif->ultra_mask;
391 hwif->mwdma_mask = tmp_hwif->mwdma_mask;
392 hwif->swdma_mask = tmp_hwif->swdma_mask;
393
394 hwif->cbl = tmp_hwif->cbl;
395
396 hwif->chipset = tmp_hwif->chipset;
397 hwif->hold = tmp_hwif->hold;
398
399 hwif->dev = tmp_hwif->dev;
400
401#ifdef CONFIG_BLK_DEV_IDEPCI
402 hwif->cds = tmp_hwif->cds;
403#endif
404
405 hwif->set_pio_mode = tmp_hwif->set_pio_mode;
406 hwif->set_dma_mode = tmp_hwif->set_dma_mode;
407 hwif->mdma_filter = tmp_hwif->mdma_filter;
408 hwif->udma_filter = tmp_hwif->udma_filter;
409 hwif->selectproc = tmp_hwif->selectproc;
410 hwif->reset_poll = tmp_hwif->reset_poll;
411 hwif->pre_reset = tmp_hwif->pre_reset;
412 hwif->resetproc = tmp_hwif->resetproc;
413 hwif->maskproc = tmp_hwif->maskproc;
414 hwif->quirkproc = tmp_hwif->quirkproc;
415
416 hwif->ata_input_data = tmp_hwif->ata_input_data;
417 hwif->ata_output_data = tmp_hwif->ata_output_data;
418 hwif->atapi_input_bytes = tmp_hwif->atapi_input_bytes;
419 hwif->atapi_output_bytes = tmp_hwif->atapi_output_bytes;
420
421 hwif->dma_host_set = tmp_hwif->dma_host_set;
422 hwif->dma_setup = tmp_hwif->dma_setup;
423 hwif->dma_exec_cmd = tmp_hwif->dma_exec_cmd;
424 hwif->dma_start = tmp_hwif->dma_start;
425 hwif->ide_dma_end = tmp_hwif->ide_dma_end;
426 hwif->ide_dma_test_irq = tmp_hwif->ide_dma_test_irq;
427 hwif->ide_dma_clear_irq = tmp_hwif->ide_dma_clear_irq;
428 hwif->dma_lost_irq = tmp_hwif->dma_lost_irq;
429 hwif->dma_timeout = tmp_hwif->dma_timeout;
430
431 hwif->OUTB = tmp_hwif->OUTB;
432 hwif->OUTBSYNC = tmp_hwif->OUTBSYNC;
433 hwif->OUTW = tmp_hwif->OUTW;
434 hwif->OUTSW = tmp_hwif->OUTSW;
435 hwif->OUTSL = tmp_hwif->OUTSL;
436
437 hwif->INB = tmp_hwif->INB;
438 hwif->INW = tmp_hwif->INW;
439 hwif->INSW = tmp_hwif->INSW;
440 hwif->INSL = tmp_hwif->INSL;
441
442 hwif->sg_max_nents = tmp_hwif->sg_max_nents;
443
444 hwif->mmio = tmp_hwif->mmio;
445 hwif->rqsize = tmp_hwif->rqsize;
446
447#ifndef CONFIG_BLK_DEV_IDECS
448 hwif->irq = tmp_hwif->irq;
449#endif
450
451 hwif->dma_base = tmp_hwif->dma_base;
452 hwif->dma_command = tmp_hwif->dma_command;
453 hwif->dma_vendor1 = tmp_hwif->dma_vendor1;
454 hwif->dma_status = tmp_hwif->dma_status;
455 hwif->dma_vendor3 = tmp_hwif->dma_vendor3;
456 hwif->dma_prdtable = tmp_hwif->dma_prdtable;
457
458 hwif->config_data = tmp_hwif->config_data;
459 hwif->select_data = tmp_hwif->select_data;
460 hwif->extra_base = tmp_hwif->extra_base;
461 hwif->extra_ports = tmp_hwif->extra_ports;
462
463 hwif->hwif_data = tmp_hwif->hwif_data;
464}
465
466void ide_remove_port_from_hwgroup(ide_hwif_t *hwif) 365void ide_remove_port_from_hwgroup(ide_hwif_t *hwif)
467{ 366{
468 ide_hwgroup_t *hwgroup = hwif->hwgroup; 367 ide_hwgroup_t *hwgroup = hwif->hwgroup;
@@ -530,8 +429,6 @@ EXPORT_SYMBOL_GPL(ide_port_unregister_devices);
530/** 429/**
531 * ide_unregister - free an IDE interface 430 * ide_unregister - free an IDE interface
532 * @index: index of interface (will change soon to a pointer) 431 * @index: index of interface (will change soon to a pointer)
533 * @init_default: init default hwif flag
534 * @restore: restore hwif flag
535 * 432 *
536 * Perform the final unregister of an IDE interface. At the moment 433 * Perform the final unregister of an IDE interface. At the moment
537 * we don't refcount interfaces so this will also get split up. 434 * we don't refcount interfaces so this will also get split up.
@@ -551,10 +448,9 @@ EXPORT_SYMBOL_GPL(ide_port_unregister_devices);
551 * This is raving bonkers. 448 * This is raving bonkers.
552 */ 449 */
553 450
554void ide_unregister(unsigned int index, int init_default, int restore) 451void ide_unregister(unsigned int index)
555{ 452{
556 ide_hwif_t *hwif, *g; 453 ide_hwif_t *hwif, *g;
557 static ide_hwif_t tmp_hwif; /* protected by ide_cfg_mtx */
558 ide_hwgroup_t *hwgroup; 454 ide_hwgroup_t *hwgroup;
559 int irq_count = 0; 455 int irq_count = 0;
560 456
@@ -601,34 +497,14 @@ void ide_unregister(unsigned int index, int init_default, int restore)
601 unregister_blkdev(hwif->major, hwif->name); 497 unregister_blkdev(hwif->major, hwif->name);
602 spin_lock_irq(&ide_lock); 498 spin_lock_irq(&ide_lock);
603 499
604 if (hwif->dma_base) { 500 if (hwif->dma_base)
605 (void) ide_release_dma(hwif); 501 (void)ide_release_dma(hwif);
606
607 hwif->dma_base = 0;
608 hwif->dma_command = 0;
609 hwif->dma_vendor1 = 0;
610 hwif->dma_status = 0;
611 hwif->dma_vendor3 = 0;
612 hwif->dma_prdtable = 0;
613
614 hwif->extra_base = 0;
615 hwif->extra_ports = 0;
616 }
617 502
618 ide_hwif_release_regions(hwif); 503 ide_hwif_release_regions(hwif);
619 504
620 /* copy original settings */
621 tmp_hwif = *hwif;
622
623 /* restore hwif data to pristine status */ 505 /* restore hwif data to pristine status */
624 ide_init_port_data(hwif, index); 506 ide_init_port_data(hwif, index);
625 507
626 if (init_default)
627 init_hwif_default(hwif, index);
628
629 if (restore)
630 ide_hwif_restore(hwif, &tmp_hwif);
631
632abort: 508abort:
633 spin_unlock_irq(&ide_lock); 509 spin_unlock_irq(&ide_lock);
634 mutex_unlock(&ide_cfg_mtx); 510 mutex_unlock(&ide_cfg_mtx);
@@ -647,52 +523,6 @@ void ide_init_port_hw(ide_hwif_t *hwif, hw_regs_t *hw)
647} 523}
648EXPORT_SYMBOL_GPL(ide_init_port_hw); 524EXPORT_SYMBOL_GPL(ide_init_port_hw);
649 525
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
661static 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_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;
676found:
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/* 526/*
697 * Locks for IDE setting functionality 527 * Locks for IDE setting functionality
698 */ 528 */
@@ -995,27 +825,6 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device
995 if (!capable(CAP_SYS_RAWIO)) 825 if (!capable(CAP_SYS_RAWIO))
996 return -EACCES; 826 return -EACCES;
997 return ide_task_ioctl(drive, cmd, arg); 827 return ide_task_ioctl(drive, cmd, arg);
998
999 case HDIO_SCAN_HWIF:
1000 {
1001 hw_regs_t hw;
1002 int args[3];
1003 if (!capable(CAP_SYS_RAWIO)) return -EACCES;
1004 if (copy_from_user(args, p, 3 * sizeof(int)))
1005 return -EFAULT;
1006 memset(&hw, 0, sizeof(hw));
1007 ide_init_hwif_ports(&hw, (unsigned long) args[0],
1008 (unsigned long) args[1], NULL);
1009 hw.irq = args[2];
1010 if (ide_register_hw(&hw, NULL, NULL) == -1)
1011 return -EIO;
1012 return 0;
1013 }
1014 case HDIO_UNREGISTER_HWIF:
1015 if (!capable(CAP_SYS_RAWIO)) return -EACCES;
1016 /* (arg > MAX_HWIFS) checked in function */
1017 ide_unregister(arg, 1, 1);
1018 return 0;
1019 case HDIO_SET_NICE: 828 case HDIO_SET_NICE:
1020 if (!capable(CAP_SYS_ADMIN)) return -EACCES; 829 if (!capable(CAP_SYS_ADMIN)) return -EACCES;
1021 if (arg != (arg & ((1 << IDE_NICE_DSC_OVERLAP) | (1 << IDE_NICE_1)))) 830 if (arg != (arg & ((1 << IDE_NICE_DSC_OVERLAP) | (1 << IDE_NICE_1))))
@@ -1648,7 +1457,7 @@ void __exit cleanup_module (void)
1648 int index; 1457 int index;
1649 1458
1650 for (index = 0; index < MAX_HWIFS; ++index) 1459 for (index = 0; index < MAX_HWIFS; ++index)
1651 ide_unregister(index, 0, 0); 1460 ide_unregister(index);
1652 1461
1653 proc_ide_destroy(); 1462 proc_ide_destroy();
1654 1463