lkml.org 
[lkml]   [2003]   [Mar]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    SubjectPATCH: update ide core
    - New style ide-default driver
    - Don't attach non existant drives
    - DRIVER()==NULL checks can go
    - Ioctl checks that were missing are now in
    diff -u --new-file --recursive --exclude-from /usr/src/exclude linux-2.5.65/drivers/ide/ide.c linux-2.5.65-ac2/drivers/ide/ide.c
    --- linux-2.5.65/drivers/ide/ide.c 2003-03-03 19:20:09.000000000 +0000
    +++ linux-2.5.65-ac2/drivers/ide/ide.c 2003-03-20 18:23:19.000000000 +0000
    @@ -1,5 +1,5 @@
    /*
    - * linux/drivers/ide/ide.c Version 7.00alpha1 August 19 2002
    + * linux/drivers/ide/ide.c Version 7.00beta2 Mar 05 2003
    *
    * Copyright (C) 1994-1998 Linus Torvalds & authors (see below)
    */
    @@ -177,6 +177,7 @@
    static int system_bus_speed; /* holds what we think is VESA/PCI bus speed */
    static int initializing; /* set while initializing built-in drivers */

    +DECLARE_MUTEX(ide_cfg_sem);
    spinlock_t ide_lock __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;

    static int ide_scan_direction; /* THIS was formerly 2.2.x pci=reverse */
    @@ -214,6 +215,8 @@
    EXPORT_SYMBOL(idetape);
    EXPORT_SYMBOL(idescsi);

    +extern ide_driver_t idedefault_driver;
    +static void setup_driver_defaults (ide_drive_t *drive);

    /*
    * Do not even *think* about calling this!
    @@ -271,6 +274,8 @@
    drive->max_failures = IDE_DEFAULT_MAX_FAILURES;
    drive->using_dma = 0;
    drive->is_flash = 0;
    + drive->driver = &idedefault_driver;
    + setup_driver_defaults(drive);
    drive->vdma = 0;
    INIT_LIST_HEAD(&drive->list);
    }
    @@ -349,9 +354,7 @@
    {
    if (!drive->present)
    return 0;
    - if (drive->driver != NULL)
    - return DRIVER(drive)->capacity(drive);
    - return 0;
    + return DRIVER(drive)->capacity(drive);
    }

    EXPORT_SYMBOL(current_capacity);
    @@ -580,17 +583,19 @@

    void ide_unregister (unsigned int index)
    {
    - ide_drive_t *drive, *d;
    + ide_drive_t *drive;
    ide_hwif_t *hwif, *g;
    ide_hwgroup_t *hwgroup;
    int irq_count = 0, unit, i;
    - unsigned long flags;
    ide_hwif_t old_hwif;

    if (index >= MAX_HWIFS)
    BUG();

    - spin_lock_irqsave(&ide_lock, flags);
    + BUG_ON(in_interrupt());
    + BUG_ON(irqs_disabled());
    + down(&ide_cfg_sem);
    + spin_lock_irq(&ide_lock);
    hwif = &ide_hwifs[index];
    if (!hwif->present)
    goto abort;
    @@ -600,25 +605,23 @@
    continue;
    if (drive->usage)
    goto abort;
    - if (drive->driver != NULL && DRIVER(drive)->shutdown(drive))
    + if (DRIVER(drive)->shutdown(drive))
    goto abort;
    }
    hwif->present = 0;

    - spin_unlock_irqrestore(&ide_lock, flags);
    + spin_unlock_irq(&ide_lock);

    for (unit = 0; unit < MAX_DRIVES; ++unit) {
    drive = &hwif->drives[unit];
    if (!drive->present)
    continue;
    - if (drive->driver != NULL)
    - DRIVER(drive)->cleanup(drive);
    + DRIVER(drive)->cleanup(drive);
    }

    #ifdef CONFIG_PROC_FS
    destroy_proc_ide_drives(hwif);
    #endif
    - spin_lock_irqsave(&ide_lock, flags);
    hwgroup = hwif->hwgroup;

    /*
    @@ -633,6 +636,7 @@
    if (irq_count == 1)
    free_irq(hwif->irq, hwgroup);

    + spin_lock_irq(&ide_lock);
    /*
    * Note that we only release the standard ports,
    * and do not even try to handle any extra ports
    @@ -644,7 +648,6 @@
    * Remove us from the hwgroup, and free
    * the hwgroup if we were the only member
    */
    - d = hwgroup->drive;
    for (i = 0; i < MAX_DRIVES; ++i) {
    drive = &hwif->drives[i];
    if (drive->de) {
    @@ -653,11 +656,23 @@
    }
    if (!drive->present)
    continue;
    - while (hwgroup->drive->next != drive)
    - hwgroup->drive = hwgroup->drive->next;
    - hwgroup->drive->next = drive->next;
    - if (hwgroup->drive == drive)
    + if (drive == drive->next) {
    + /* special case: last drive from hwgroup. */
    + BUG_ON(hwgroup->drive != drive);
    hwgroup->drive = NULL;
    + } else {
    + ide_drive_t *walk;
    +
    + walk = hwgroup->drive;
    + while (walk->next != drive)
    + walk = walk->next;
    + walk->next = drive->next;
    + if (hwgroup->drive == drive) {
    + hwgroup->drive = drive->next;
    + hwgroup->hwif = HWIF(hwgroup->drive);
    + }
    + }
    + BUG_ON(hwgroup->drive == drive);
    if (drive->id != NULL) {
    kfree(drive->id);
    drive->id = NULL;
    @@ -665,15 +680,28 @@
    drive->present = 0;
    blk_cleanup_queue(&drive->queue);
    }
    - if (d->present)
    - hwgroup->drive = d;
    - while (hwgroup->hwif->next != hwif)
    - hwgroup->hwif = hwgroup->hwif->next;
    - hwgroup->hwif->next = hwif->next;
    - if (hwgroup->hwif == hwif)
    + if (hwif->next == hwif) {
    kfree(hwgroup);
    - else
    - hwgroup->hwif = HWIF(hwgroup->drive);
    + BUG_ON(hwgroup->hwif != hwif);
    + } else {
    + /* There is another interface in hwgroup.
    + * Unlink us, and set hwgroup->drive and ->hwif to
    + * something sane.
    + */
    + g = hwgroup->hwif;
    + while (g->next != hwif)
    + g = g->next;
    + g->next = hwif->next;
    + if (hwgroup->hwif == hwif) {
    + /* Chose a random hwif for hwgroup->hwif.
    + * It's guaranteed that there are no drives
    + * left in the hwgroup.
    + */
    + BUG_ON(hwgroup->drive != NULL);
    + hwgroup->hwif = g;
    + }
    + BUG_ON(hwgroup->hwif == hwif);
    + }

    #if !defined(CONFIG_DMA_NONPCI)
    if (hwif->dma_base) {
    @@ -813,7 +841,8 @@

    hwif->hwif_data = old_hwif.hwif_data;
    abort:
    - spin_unlock_irqrestore(&ide_lock, flags);
    + spin_unlock_irq(&ide_lock);
    + up(&ide_cfg_sem);
    }

    EXPORT_SYMBOL(ide_unregister);
    @@ -998,7 +1027,7 @@
    setting->set = set;

    setting->next = *p;
    - if (drive->driver)
    + if (drive->driver != &idedefault_driver)
    setting->auto_remove = 1;
    *p = setting;
    up(&ide_setting_sem);
    @@ -1304,15 +1334,9 @@
    return 0;
    }

    - if (drive->driver != NULL) {
    -#if 0
    - ide_unregister_subdriver(drive);
    -#else
    - if (DRIVER(drive)->cleanup(drive)) {
    - drive->scsi = 0;
    - return 0;
    - }
    -#endif
    + if (DRIVER(drive)->cleanup(drive)) {
    + drive->scsi = 0;
    + return 0;
    }

    drive->scsi = (u8) arg;
    @@ -1353,7 +1377,7 @@
    mdelay(50);
    #else
    __set_current_state(TASK_UNINTERRUPTIBLE);
    - schedule_timeout(HZ/20);
    + schedule_timeout(1+HZ/20);
    #endif /* CONFIG_BLK_DEV_IDECS */
    }

    @@ -1375,7 +1399,7 @@
    {
    if (!drive->present || drive->usage || drive->dead)
    goto abort;
    - if (drive->driver != NULL && DRIVER(drive)->cleanup(drive))
    + if (DRIVER(drive)->cleanup(drive))
    goto abort;
    strncpy(drive->driver_req, driver, 9);
    if (ata_attach(drive)) {
    @@ -1387,7 +1411,7 @@
    } else {
    drive->driver_req[0] = 0;
    }
    - if (DRIVER(drive) && !strcmp(DRIVER(drive)->name, driver))
    + if (DRIVER(drive)!= &idedefault_driver && !strcmp(DRIVER(drive)->name, driver))
    return 0;
    abort:
    return 1;
    @@ -1412,10 +1436,12 @@
    spin_lock(&drivers_lock);
    module_put(driver->owner);
    }
    + drive->gendev.driver = &idedefault_driver.gen_driver;
    spin_unlock(&drivers_lock);
    + if(idedefault_driver.attach(drive) != 0)
    + panic("ide: default attach failed");
    spin_lock(&drives_lock);
    list_add_tail(&drive->list, &ata_unused);
    - drive->gendev.driver = NULL;
    spin_unlock(&drives_lock);
    return 1;
    }
    @@ -1476,7 +1502,7 @@
    case HDIO_GET_IDENTITY:
    if (bdev != bdev->bd_contains)
    return -EINVAL;
    - if (drive->id == NULL)
    + if (drive->id_read == 0)
    return -ENOMSG;
    if (copy_to_user((char *)arg, (char *)drive->id, (cmd == HDIO_GET_IDENTITY) ? sizeof(*drive->id) : 142))
    return -EFAULT;
    @@ -1521,7 +1547,7 @@
    case HDIO_SCAN_HWIF:
    {
    int args[3];
    - if (!capable(CAP_SYS_ADMIN)) return -EACCES;
    + if (!capable(CAP_SYS_RAWIO)) return -EACCES;
    if (copy_from_user(args, (void *)arg, 3 * sizeof(int)))
    return -EFAULT;
    if (ide_register(args[0], args[1], args[2]) == -1)
    @@ -1529,14 +1555,12 @@
    return 0;
    }
    case HDIO_UNREGISTER_HWIF:
    - if (!capable(CAP_SYS_ADMIN)) return -EACCES;
    + if (!capable(CAP_SYS_RAWIO)) return -EACCES;
    /* (arg > MAX_HWIFS) checked in function */
    ide_unregister(arg);
    return 0;
    case HDIO_SET_NICE:
    if (!capable(CAP_SYS_ADMIN)) return -EACCES;
    - if (drive->driver == NULL)
    - return -EPERM;
    if (arg != (arg & ((1 << IDE_NICE_DSC_OVERLAP) | (1 << IDE_NICE_1))))
    return -EPERM;
    drive->dsc_overlap = (arg >> IDE_NICE_DSC_OVERLAP) & 1;
    @@ -1550,18 +1574,26 @@
    {
    unsigned long flags;
    if (!capable(CAP_SYS_ADMIN)) return -EACCES;
    -#if 1
    +
    + /*
    + * Abort the current command on the
    + * group if there is one, taking
    + * care not to allow anything else
    + * to be queued and to die on the
    + * spot if we miss one somehow
    + */
    +
    spin_lock_irqsave(&ide_lock, flags);
    - if ( HWGROUP(drive)->handler != NULL) {
    - printk(KERN_ERR "%s: ide_set_handler: handler not null; %p\n", drive->name, HWGROUP(drive)->handler);
    - (void) HWGROUP(drive)->handler(drive);
    -// HWGROUP(drive)->handler = NULL;
    - HWGROUP(drive)->expiry = NULL;
    - del_timer(&HWGROUP(drive)->timer);
    - }
    +
    + DRIVER(drive)->abort(drive, "drive reset");
    + if(HWGROUP(drive)->handler)
    + BUG();
    +
    + /* Ensure nothing gets queued after we
    + drop the lock. Reset will clear the busy */
    +
    + HWGROUP(drive)->busy = 1;
    spin_unlock_irqrestore(&ide_lock, flags);
    -
    -#endif
    (void) ide_do_reset(drive);
    if (drive->suspend_reset) {
    /*
    @@ -1593,9 +1625,8 @@
    if (!capable(CAP_SYS_ADMIN))
    return -EACCES;
    if (HWIF(drive)->busproc)
    - HWIF(drive)->busproc(drive, (int)arg);
    - return 0;
    -
    + return HWIF(drive)->busproc(drive, (int)arg);
    + return -EOPNOTSUPP;
    default:
    return -EINVAL;
    }
    @@ -2193,7 +2224,7 @@

    static int default_shutdown(ide_drive_t *drive)
    {
    - if (drive->usage || drive->driver == NULL || DRIVER(drive)->busy) {
    + if (drive->usage || DRIVER(drive)->busy) {
    return 1;
    }
    drive->dead = 1;
    @@ -2261,6 +2292,11 @@
    return 0;
    }

    +static ide_startstop_t default_abort (ide_drive_t *drive, const char *msg)
    +{
    + return ide_abort(drive, msg);
    +}
    +
    static void setup_driver_defaults (ide_drive_t *drive)
    {
    ide_driver_t *d = drive->driver;
    @@ -2272,6 +2308,7 @@
    if (d->end_request == NULL) d->end_request = default_end_request;
    if (d->sense == NULL) d->sense = default_sense;
    if (d->error == NULL) d->error = default_error;
    + if (d->abort == NULL) d->abort = default_abort;
    if (d->pre_reset == NULL) d->pre_reset = default_pre_reset;
    if (d->capacity == NULL) d->capacity = default_capacity;
    if (d->special == NULL) d->special = default_special;
    @@ -2282,9 +2319,11 @@
    {
    unsigned long flags;

    + BUG_ON(drive->driver == NULL);
    +
    spin_lock_irqsave(&ide_lock, flags);
    if (version != IDE_SUBDRIVER_VERSION || !drive->present ||
    - drive->driver != NULL || drive->usage || drive->dead) {
    + drive->driver != &idedefault_driver || drive->usage || drive->dead) {
    spin_unlock_irqrestore(&ide_lock, flags);
    return 1;
    }
    @@ -2294,6 +2333,7 @@
    spin_lock(&drives_lock);
    list_add(&drive->list, &driver->drives);
    spin_unlock(&drives_lock);
    +// printk(KERN_INFO "%s: attached %s driver.\n", drive->name, driver->name);
    if ((drive->autotune == IDE_TUNE_DEFAULT) ||
    (drive->autotune == IDE_TUNE_AUTO)) {
    /* DMA timings and setup moved to ide-probe.c */
    @@ -2318,7 +2358,7 @@
    unsigned long flags;

    spin_lock_irqsave(&ide_lock, flags);
    - if (drive->usage || drive->driver == NULL || DRIVER(drive)->busy) {
    + if (drive->usage || drive->driver == &idedefault_driver || DRIVER(drive)->busy) {
    spin_unlock_irqrestore(&ide_lock, flags);
    return 1;
    }
    @@ -2330,10 +2370,12 @@
    ide_remove_proc_entries(drive->proc, generic_subdriver_entries);
    #endif
    auto_remove_settings(drive);
    - drive->driver = NULL;
    + drive->driver = &idedefault_driver;
    + setup_driver_defaults(drive);
    spin_unlock_irqrestore(&ide_lock, flags);
    spin_lock(&drives_lock);
    list_del_init(&drive->list);
    + list_add(&drive->list, &drive->driver->drives);
    spin_unlock(&drives_lock);
    return 0;
    }
    @@ -2343,10 +2385,7 @@
    static int ide_drive_remove(struct device * dev)
    {
    ide_drive_t * drive = container_of(dev,ide_drive_t,gendev);
    - ide_driver_t * driver = drive->driver;
    -
    - if (driver && driver->cleanup)
    - driver->cleanup(drive);
    + DRIVER(drive)->cleanup(drive);
    return 0;
    }

    @@ -2366,7 +2405,8 @@
    while (!list_empty(&list)) {
    ide_drive_t *drive = list_entry(list.next, ide_drive_t, list);
    list_del_init(&drive->list);
    - ata_attach(drive);
    + if (drive->present)
    + ata_attach(drive);
    }
    driver->gen_driver.name = (char *) driver->name;
    driver->gen_driver.bus = &ide_bus_type;
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/
    \
     
     \ /
      Last update: 2005-03-22 13:34    [W:0.040 / U:30.448 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site