diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-03 06:02:24 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-03 06:02:24 -0700 |
commit | c753237cb5783cd92b01fbfb6e6028dcac28b113 (patch) | |
tree | acc4225515c921abef8d607e9fa622a5b93d009a | |
parent | 184a2f07d38d9bde2119d867c851efe9a2dcb382 (diff) | |
parent | a04780b2d7f0c71486a6c3e4b452ff8b05f2bd59 (diff) | |
download | history-c753237cb5783cd92b01fbfb6e6028dcac28b113.tar.gz |
Merge bk://bart.bkbits.net/ide-2.6
into ppc970.osdl.org:/home/torvalds/v2.6/linux
-rw-r--r-- | drivers/ide/Makefile | 3 | ||||
-rw-r--r-- | drivers/ide/ide-cd.c | 71 | ||||
-rw-r--r-- | drivers/ide/ide-cd.h | 2 | ||||
-rw-r--r-- | drivers/ide/ide-default.c | 76 | ||||
-rw-r--r-- | drivers/ide/ide-disk.c | 30 | ||||
-rw-r--r-- | drivers/ide/ide-dma.c | 8 | ||||
-rw-r--r-- | drivers/ide/ide-floppy.c | 48 | ||||
-rw-r--r-- | drivers/ide/ide-io.c | 46 | ||||
-rw-r--r-- | drivers/ide/ide-probe.c | 122 | ||||
-rw-r--r-- | drivers/ide/ide-proc.c | 12 | ||||
-rw-r--r-- | drivers/ide/ide-tape.c | 41 | ||||
-rw-r--r-- | drivers/ide/ide-taskfile.c | 11 | ||||
-rw-r--r-- | drivers/ide/ide.c | 86 | ||||
-rw-r--r-- | drivers/ide/pci/via82cxxx.c | 7 | ||||
-rw-r--r-- | drivers/scsi/ide-scsi.c | 44 | ||||
-rw-r--r-- | include/linux/ide.h | 6 |
16 files changed, 338 insertions, 275 deletions
diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile index eb3c8087764732..5be8ad6dc9edcf 100644 --- a/drivers/ide/Makefile +++ b/drivers/ide/Makefile @@ -13,8 +13,7 @@ EXTRA_CFLAGS += -Idrivers/ide obj-$(CONFIG_BLK_DEV_IDE) += pci/ -ide-core-y += ide.o ide-default.o ide-io.o ide-iops.o ide-lib.o ide-probe.o \ - ide-taskfile.o +ide-core-y += ide.o ide-io.o ide-iops.o ide-lib.o ide-probe.o ide-taskfile.o ide-core-$(CONFIG_BLK_DEV_CMD640) += pci/cmd640.o diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 4b96aa193161fb..33a020faeabde2 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -328,7 +328,8 @@ static DECLARE_MUTEX(idecd_ref_sem); #define to_ide_cd(obj) container_of(obj, struct cdrom_info, kref) -#define ide_cd_g(disk) ((disk)->private_data) +#define ide_cd_g(disk) \ + container_of((disk)->private_data, struct cdrom_info, driver) static struct cdrom_info *ide_cd_get(struct gendisk *disk) { @@ -556,10 +557,13 @@ void cdrom_analyze_sense_data(ide_drive_t *drive, /* * Initialize a ide-cd packet command request */ -static void cdrom_prepare_request(struct request *rq) +static void cdrom_prepare_request(ide_drive_t *drive, struct request *rq) { + struct cdrom_info *cd = drive->driver_data; + ide_init_drive_cmd(rq); rq->flags = REQ_PC; + rq->rq_disk = cd->disk; } static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense, @@ -572,7 +576,7 @@ static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense, sense = &info->sense_data; /* stuff the sense request in front of our current request */ - cdrom_prepare_request(rq); + cdrom_prepare_request(drive, rq); rq->data = sense; rq->cmd[0] = GPCMD_REQUEST_SENSE; @@ -1856,7 +1860,7 @@ static ide_startstop_t cdrom_start_write_cont(ide_drive_t *drive) static ide_startstop_t cdrom_start_write(ide_drive_t *drive, struct request *rq) { struct cdrom_info *info = drive->driver_data; - struct gendisk *g = drive->disk; + struct gendisk *g = info->disk; unsigned short sectors_per_frame = queue_hardsect_size(drive->queue) >> SECTOR_BITS; /* @@ -2048,7 +2052,7 @@ static int cdrom_check_status(ide_drive_t *drive, struct request_sense *sense) struct cdrom_info *info = drive->driver_data; struct cdrom_device_info *cdi = &info->devinfo; - cdrom_prepare_request(&req); + cdrom_prepare_request(drive, &req); req.sense = sense; req.cmd[0] = GPCMD_TEST_UNIT_READY; @@ -2080,7 +2084,7 @@ cdrom_lockdoor(ide_drive_t *drive, int lockflag, struct request_sense *sense) if (CDROM_CONFIG_FLAGS(drive)->no_doorlock) { stat = 0; } else { - cdrom_prepare_request(&req); + cdrom_prepare_request(drive, &req); req.sense = sense; req.cmd[0] = GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL; req.cmd[4] = lockflag ? 1 : 0; @@ -2124,7 +2128,7 @@ static int cdrom_eject(ide_drive_t *drive, int ejectflag, if (CDROM_STATE_FLAGS(drive)->door_locked && ejectflag) return 0; - cdrom_prepare_request(&req); + cdrom_prepare_request(drive, &req); /* only tell drive to close tray if open, if it can do that */ if (ejectflag && !CDROM_CONFIG_FLAGS(drive)->close_tray) @@ -2148,7 +2152,7 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity, int stat; struct request req; - cdrom_prepare_request(&req); + cdrom_prepare_request(drive, &req); req.sense = sense; req.cmd[0] = GPCMD_READ_CDVD_CAPACITY; @@ -2171,7 +2175,7 @@ static int cdrom_read_tocentry(ide_drive_t *drive, int trackno, int msf_flag, { struct request req; - cdrom_prepare_request(&req); + cdrom_prepare_request(drive, &req); req.sense = sense; req.data = buf; @@ -2228,7 +2232,7 @@ static int cdrom_read_toc(ide_drive_t *drive, struct request_sense *sense) if (stat) toc->capacity = 0x1fffff; - set_capacity(drive->disk, toc->capacity * sectors_per_frame); + set_capacity(info->disk, toc->capacity * sectors_per_frame); blk_queue_hardsect_size(drive->queue, sectors_per_frame << SECTOR_BITS); @@ -2348,7 +2352,7 @@ static int cdrom_read_toc(ide_drive_t *drive, struct request_sense *sense) stat = cdrom_get_last_written(cdi, &last_written); if (!stat && (last_written > toc->capacity)) { toc->capacity = last_written; - set_capacity(drive->disk, toc->capacity * sectors_per_frame); + set_capacity(info->disk, toc->capacity * sectors_per_frame); } /* Remember that we've read this stuff. */ @@ -2363,7 +2367,7 @@ static int cdrom_read_subchannel(ide_drive_t *drive, int format, char *buf, { struct request req; - cdrom_prepare_request(&req); + cdrom_prepare_request(drive, &req); req.sense = sense; req.data = buf; @@ -2383,7 +2387,7 @@ static int cdrom_select_speed(ide_drive_t *drive, int speed, struct request_sense *sense) { struct request req; - cdrom_prepare_request(&req); + cdrom_prepare_request(drive, &req); req.sense = sense; if (speed == 0) @@ -2413,7 +2417,7 @@ static int cdrom_play_audio(ide_drive_t *drive, int lba_start, int lba_end) struct request_sense sense; struct request req; - cdrom_prepare_request(&req); + cdrom_prepare_request(drive, &req); req.sense = &sense; req.cmd[0] = GPCMD_PLAY_AUDIO_MSF; @@ -2463,7 +2467,7 @@ static int ide_cdrom_packet(struct cdrom_device_info *cdi, /* here we queue the commands from the uniform CD-ROM layer. the packet must be complete, as we do not touch it at all. */ - cdrom_prepare_request(&req); + cdrom_prepare_request(drive, &req); memcpy(req.cmd, cgc->cmd, CDROM_PACKET_SIZE); if (cgc->sense) memset(cgc->sense, 0, sizeof(struct request_sense)); @@ -2613,7 +2617,7 @@ int ide_cdrom_reset (struct cdrom_device_info *cdi) struct request req; int ret; - cdrom_prepare_request(&req); + cdrom_prepare_request(drive, &req); req.flags = REQ_SPECIAL | REQ_QUIET; ret = ide_do_drive_cmd(drive, &req, ide_wait); @@ -2857,7 +2861,7 @@ static int ide_cdrom_register (ide_drive_t *drive, int nslots) if (!CDROM_CONFIG_FLAGS(drive)->mo_drive) devinfo->mask |= CDC_MO_DRIVE; - devinfo->disk = drive->disk; + devinfo->disk = info->disk; return register_cdrom(devinfo); } @@ -3219,6 +3223,9 @@ int ide_cdrom_setup (ide_drive_t *drive) */ blk_queue_hardsect_size(drive->queue, CD_FRAMESIZE); + if (drive->autotune == IDE_TUNE_DEFAULT || + drive->autotune == IDE_TUNE_AUTO) + drive->dsc_overlap = (drive->next != drive); #if 0 drive->dsc_overlap = (HWIF(drive)->no_dsc) ? 0 : 1; if (HWIF(drive)->no_dsc) { @@ -3259,7 +3266,7 @@ int ide_cdrom_cleanup(ide_drive_t *drive) return 1; } - del_gendisk(drive->disk); + del_gendisk(info->disk); ide_cd_put(info); @@ -3271,7 +3278,7 @@ static void ide_cd_release(struct kref *kref) struct cdrom_info *info = to_ide_cd(kref); struct cdrom_device_info *devinfo = &info->devinfo; ide_drive_t *drive = info->drive; - struct gendisk *g = drive->disk; + struct gendisk *g = info->disk; if (info->buffer != NULL) kfree(info->buffer); @@ -3282,10 +3289,11 @@ static void ide_cd_release(struct kref *kref) if (devinfo->handle == drive && unregister_cdrom(devinfo)) printk(KERN_ERR "%s: %s failed to unregister device from the cdrom " "driver.\n", __FUNCTION__, drive->name); + drive->dsc_overlap = 0; drive->driver_data = NULL; blk_queue_prep_rq(drive->queue, NULL); g->private_data = NULL; - g->fops = ide_fops; + put_disk(g); kfree(info); } @@ -3413,7 +3421,7 @@ MODULE_DESCRIPTION("ATAPI CD-ROM Driver"); static int ide_cdrom_attach (ide_drive_t *drive) { struct cdrom_info *info; - struct gendisk *g = drive->disk; + struct gendisk *g; struct request_sense sense; if (!strstr("ide-cdrom", drive->driver_req)) @@ -3438,17 +3446,28 @@ static int ide_cdrom_attach (ide_drive_t *drive) printk(KERN_ERR "%s: Can't allocate a cdrom structure\n", drive->name); goto failed; } + + g = alloc_disk(1 << PARTN_BITS); + if (!g) + goto out_free_cd; + + ide_init_disk(g, drive); + if (ide_register_subdriver(drive, &ide_cdrom_driver)) { printk(KERN_ERR "%s: Failed to register the driver with ide.c\n", drive->name); - kfree(info); - goto failed; + goto out_put_disk; } memset(info, 0, sizeof (struct cdrom_info)); kref_init(&info->kref); info->drive = drive; + info->driver = &ide_cdrom_driver; + info->disk = g; + + g->private_data = &info->driver; + drive->driver_data = info; DRIVER(drive)->busy++; @@ -3477,10 +3496,14 @@ static int ide_cdrom_attach (ide_drive_t *drive) cdrom_read_toc(drive, &sense); g->fops = &idecd_ops; - g->private_data = info; g->flags |= GENHD_FL_REMOVABLE; add_disk(g); return 0; + +out_put_disk: + put_disk(g); +out_free_cd: + kfree(info); failed: return 1; } diff --git a/drivers/ide/ide-cd.h b/drivers/ide/ide-cd.h index 171c65eb313852..7ca3e5afc66551 100644 --- a/drivers/ide/ide-cd.h +++ b/drivers/ide/ide-cd.h @@ -461,6 +461,8 @@ struct atapi_changer_info { /* Extra per-device info for cdrom drives. */ struct cdrom_info { ide_drive_t *drive; + ide_driver_t *driver; + struct gendisk *disk; struct kref kref; /* Buffer for table of contents. NULL if we haven't allocated diff --git a/drivers/ide/ide-default.c b/drivers/ide/ide-default.c deleted file mode 100644 index 8b0c8520f7ce66..00000000000000 --- a/drivers/ide/ide-default.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * ide-default - Driver for unbound ide devices - * - * This provides a clean way to bind a device to default operations - * by having an actual driver class that rather than special casing - * "no driver" all over the IDE code - * - * Copyright (C) 2003, Red Hat <alan@redhat.com> - */ - -#include <linux/config.h> -#include <linux/module.h> -#include <linux/types.h> -#include <linux/string.h> -#include <linux/kernel.h> -#include <linux/delay.h> -#include <linux/timer.h> -#include <linux/mm.h> -#include <linux/interrupt.h> -#include <linux/major.h> -#include <linux/errno.h> -#include <linux/genhd.h> -#include <linux/slab.h> -#include <linux/cdrom.h> -#include <linux/ide.h> -#include <linux/bitops.h> - -#include <asm/byteorder.h> -#include <asm/irq.h> -#include <asm/uaccess.h> -#include <asm/io.h> -#include <asm/unaligned.h> - -#define IDEDEFAULT_VERSION "0.9.newide" -/* - * Driver initialization. - */ - -static int idedefault_attach(ide_drive_t *drive); - -static ide_startstop_t idedefault_do_request(ide_drive_t *drive, struct request *rq, sector_t block) -{ - ide_end_request(drive, 0, 0); - return ide_stopped; -} - -/* - * IDE subdriver functions, registered with ide.c - */ - -ide_driver_t idedefault_driver = { - .name = "ide-default", - .version = IDEDEFAULT_VERSION, - .attach = idedefault_attach, - .cleanup = ide_unregister_subdriver, - .do_request = idedefault_do_request, - .end_request = ide_end_request, - .error = __ide_error, - .abort = __ide_abort, - .drives = LIST_HEAD_INIT(idedefault_driver.drives) -}; - -static int idedefault_attach (ide_drive_t *drive) -{ - if (ide_register_subdriver(drive, &idedefault_driver)) { - printk(KERN_ERR "ide-default: %s: Failed to register the " - "driver with ide.c\n", drive->name); - return 1; - } - - return 0; -} - -MODULE_DESCRIPTION("IDE Default Driver"); - -MODULE_LICENSE("GPL"); diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index 9636135ee07790..5d54f77561007f 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c @@ -73,6 +73,8 @@ struct ide_disk_obj { ide_drive_t *drive; + ide_driver_t *driver; + struct gendisk *disk; struct kref kref; }; @@ -80,7 +82,8 @@ static DECLARE_MUTEX(idedisk_ref_sem); #define to_ide_disk(obj) container_of(obj, struct ide_disk_obj, kref) -#define ide_disk_g(disk) ((disk)->private_data) +#define ide_disk_g(disk) \ + container_of((disk)->private_data, struct ide_disk_obj, driver) static struct ide_disk_obj *ide_disk_get(struct gendisk *disk) { @@ -1024,7 +1027,7 @@ static void ide_cacheflush_p(ide_drive_t *drive) static int idedisk_cleanup (ide_drive_t *drive) { struct ide_disk_obj *idkp = drive->driver_data; - struct gendisk *g = drive->disk; + struct gendisk *g = idkp->disk; ide_cacheflush_p(drive); if (ide_unregister_subdriver(drive)) @@ -1040,12 +1043,12 @@ static void ide_disk_release(struct kref *kref) { struct ide_disk_obj *idkp = to_ide_disk(kref); ide_drive_t *drive = idkp->drive; - struct gendisk *g = drive->disk; + struct gendisk *g = idkp->disk; drive->driver_data = NULL; drive->devfs_name[0] = '\0'; g->private_data = NULL; - g->fops = ide_fops; + put_disk(g); kfree(idkp); } @@ -1199,7 +1202,7 @@ MODULE_DESCRIPTION("ATA DISK Driver"); static int idedisk_attach(ide_drive_t *drive) { struct ide_disk_obj *idkp; - struct gendisk *g = drive->disk; + struct gendisk *g; /* strstr("foo", "") is non-NULL */ if (!strstr("ide-disk", drive->driver_req)) @@ -1213,9 +1216,15 @@ static int idedisk_attach(ide_drive_t *drive) if (!idkp) goto failed; + g = alloc_disk(1 << PARTN_BITS); + if (!g) + goto out_free_idkp; + + ide_init_disk(g, drive); + if (ide_register_subdriver(drive, &idedisk_driver)) { printk (KERN_ERR "ide-disk: %s: Failed to register the driver with ide.c\n", drive->name); - goto out_free_idkp; + goto out_put_disk; } memset(idkp, 0, sizeof(*idkp)); @@ -1223,6 +1232,11 @@ static int idedisk_attach(ide_drive_t *drive) kref_init(&idkp->kref); idkp->drive = drive; + idkp->driver = &idedisk_driver; + idkp->disk = g; + + g->private_data = &idkp->driver; + drive->driver_data = idkp; DRIVER(drive)->busy++; @@ -1240,9 +1254,11 @@ static int idedisk_attach(ide_drive_t *drive) g->flags = drive->removable ? GENHD_FL_REMOVABLE : 0; set_capacity(g, idedisk_capacity(drive)); g->fops = &idedisk_ops; - g->private_data = idkp; add_disk(g); return 0; + +out_put_disk: + put_disk(g); out_free_idkp: kfree(idkp); failed: diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index 1179a31f81405a..2d2eefb610dd80 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c @@ -176,7 +176,13 @@ ide_startstop_t ide_dma_intr (ide_drive_t *drive) if (!dma_stat) { struct request *rq = HWGROUP(drive)->rq; - DRIVER(drive)->end_request(drive, 1, rq->nr_sectors); + if (rq->rq_disk) { + ide_driver_t *drv; + + drv = *(ide_driver_t **)rq->rq_disk->private_data;; + drv->end_request(drive, 1, rq->nr_sectors); + } else + ide_end_request(drive, 1, rq->nr_sectors); return ide_stopped; } printk(KERN_ERR "%s: dma_intr: bad DMA status (dma_stat=%x)\n", diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index 0e9421b57cc5a7..36c0b74a4e45b6 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -276,6 +276,8 @@ typedef struct { */ typedef struct ide_floppy_obj { ide_drive_t *drive; + ide_driver_t *driver; + struct gendisk *disk; struct kref kref; /* Current packet command */ @@ -519,7 +521,8 @@ static DECLARE_MUTEX(idefloppy_ref_sem); #define to_ide_floppy(obj) container_of(obj, struct ide_floppy_obj, kref) -#define ide_floppy_g(disk) ((disk)->private_data) +#define ide_floppy_g(disk) \ + container_of((disk)->private_data, struct ide_floppy_obj, driver) static struct ide_floppy_obj *ide_floppy_get(struct gendisk *disk) { @@ -680,9 +683,12 @@ static void idefloppy_update_buffers (ide_drive_t *drive, idefloppy_pc_t *pc) */ static void idefloppy_queue_pc_head (ide_drive_t *drive,idefloppy_pc_t *pc,struct request *rq) { + struct ide_floppy_obj *floppy = drive->driver_data; + ide_init_drive_cmd(rq); rq->buffer = (char *) pc; rq->flags = REQ_SPECIAL; //rq->cmd = IDEFLOPPY_PC_RQ; + rq->rq_disk = floppy->disk; (void) ide_do_drive_cmd(drive, rq, ide_preempt); } @@ -1274,7 +1280,8 @@ static ide_startstop_t idefloppy_do_request (ide_drive_t *drive, struct request unsigned long block = (unsigned long)block_s; debug_log(KERN_INFO "rq_status: %d, dev: %s, flags: %lx, errors: %d\n", - rq->rq_status, rq->rq_disk->disk_name, + rq->rq_status, + rq->rq_disk ? rq->rq_disk->disk_name ? "?", rq->flags, rq->errors); debug_log(KERN_INFO "sector: %ld, nr_sectors: %ld, " "current_nr_sectors: %d\n", (long)rq->sector, @@ -1329,11 +1336,13 @@ static ide_startstop_t idefloppy_do_request (ide_drive_t *drive, struct request */ static int idefloppy_queue_pc_tail (ide_drive_t *drive,idefloppy_pc_t *pc) { + struct ide_floppy_obj *floppy = drive->driver_data; struct request rq; ide_init_drive_cmd (&rq); rq.buffer = (char *) pc; rq.flags = REQ_SPECIAL; // rq.cmd = IDEFLOPPY_PC_RQ; + rq.rq_disk = floppy->disk; return ide_do_drive_cmd(drive, &rq, ide_wait); } @@ -1358,7 +1367,7 @@ static int idefloppy_get_flexible_disk_page (ide_drive_t *drive) } header = (idefloppy_mode_parameter_header_t *) pc.buffer; floppy->wp = header->wp; - set_disk_ro(drive->disk, floppy->wp); + set_disk_ro(floppy->disk, floppy->wp); page = (idefloppy_flexible_disk_page_t *) (header + 1); page->transfer_rate = ntohs(page->transfer_rate); @@ -1424,7 +1433,7 @@ static int idefloppy_get_capacity (ide_drive_t *drive) drive->bios_cyl = 0; drive->bios_head = drive->bios_sect = 0; floppy->blocks = floppy->bs_factor = 0; - set_capacity(drive->disk, 0); + set_capacity(floppy->disk, 0); idefloppy_create_read_capacity_cmd(&pc); if (idefloppy_queue_pc_tail(drive, &pc)) { @@ -1498,7 +1507,7 @@ static int idefloppy_get_capacity (ide_drive_t *drive) (void) idefloppy_get_flexible_disk_page(drive); } - set_capacity(drive->disk, floppy->blocks * floppy->bs_factor); + set_capacity(floppy->disk, floppy->blocks * floppy->bs_factor); return rc; } @@ -1859,7 +1868,7 @@ static void idefloppy_setup (ide_drive_t *drive, idefloppy_floppy_t *floppy) static int idefloppy_cleanup (ide_drive_t *drive) { idefloppy_floppy_t *floppy = drive->driver_data; - struct gendisk *g = drive->disk; + struct gendisk *g = floppy->disk; if (ide_unregister_subdriver(drive)) return 1; @@ -1875,11 +1884,11 @@ static void ide_floppy_release(struct kref *kref) { struct ide_floppy_obj *floppy = to_ide_floppy(kref); ide_drive_t *drive = floppy->drive; - struct gendisk *g = drive->disk; + struct gendisk *g = floppy->disk; drive->driver_data = NULL; g->private_data = NULL; - g->fops = ide_fops; + put_disk(g); kfree(floppy); } @@ -2116,7 +2125,8 @@ static struct block_device_operations idefloppy_ops = { static int idefloppy_attach (ide_drive_t *drive) { idefloppy_floppy_t *floppy; - struct gendisk *g = drive->disk; + struct gendisk *g; + if (!strstr("ide-floppy", drive->driver_req)) goto failed; if (!drive->present) @@ -2135,10 +2145,16 @@ static int idefloppy_attach (ide_drive_t *drive) printk (KERN_ERR "ide-floppy: %s: Can't allocate a floppy structure\n", drive->name); goto failed; } + + g = alloc_disk(1 << PARTN_BITS); + if (!g) + goto out_free_floppy; + + ide_init_disk(g, drive); + if (ide_register_subdriver(drive, &idefloppy_driver)) { printk (KERN_ERR "ide-floppy: %s: Failed to register the driver with ide.c\n", drive->name); - kfree (floppy); - goto failed; + goto out_put_disk; } memset(floppy, 0, sizeof(*floppy)); @@ -2146,6 +2162,10 @@ static int idefloppy_attach (ide_drive_t *drive) kref_init(&floppy->kref); floppy->drive = drive; + floppy->driver = &idefloppy_driver; + floppy->disk = g; + + g->private_data = &floppy->driver; drive->driver_data = floppy; @@ -2157,10 +2177,14 @@ static int idefloppy_attach (ide_drive_t *drive) strcpy(g->devfs_name, drive->devfs_name); g->flags = drive->removable ? GENHD_FL_REMOVABLE : 0; g->fops = &idefloppy_ops; - g->private_data = floppy; drive->attach = 1; add_disk(g); return 0; + +out_put_disk: + put_disk(g); +out_free_floppy: + kfree(floppy); failed: return 1; } diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 65f5267992dc9c..248e3cc8b3527d 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -410,6 +410,17 @@ static void try_to_flush_leftover_data (ide_drive_t *drive) } } +static void ide_kill_rq(ide_drive_t *drive, struct request *rq) +{ + if (rq->rq_disk) { + ide_driver_t *drv; + + drv = *(ide_driver_t **)rq->rq_disk->private_data; + drv->end_request(drive, 0, 0); + } else + ide_end_request(drive, 0, 0); +} + static ide_startstop_t ide_ata_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err) { ide_hwif_t *hwif = drive->hwif; @@ -444,7 +455,7 @@ static ide_startstop_t ide_ata_error(ide_drive_t *drive, struct request *rq, u8 hwif->OUTB(WIN_IDLEIMMEDIATE, IDE_COMMAND_REG); if (rq->errors >= ERROR_MAX || blk_noretry_request(rq)) - drive->driver->end_request(drive, 0, 0); + ide_kill_rq(drive, rq); else { if ((rq->errors & ERROR_RESET) == ERROR_RESET) { ++rq->errors; @@ -473,7 +484,7 @@ static ide_startstop_t ide_atapi_error(ide_drive_t *drive, struct request *rq, u hwif->OUTB(WIN_IDLEIMMEDIATE, IDE_COMMAND_REG); if (rq->errors >= ERROR_MAX) { - drive->driver->end_request(drive, 0, 0); + ide_kill_rq(drive, rq); } else { if ((rq->errors & ERROR_RESET) == ERROR_RESET) { ++rq->errors; @@ -525,7 +536,13 @@ ide_startstop_t ide_error (ide_drive_t *drive, const char *msg, u8 stat) return ide_stopped; } - return drive->driver->error(drive, rq, stat, err); + if (rq->rq_disk) { + ide_driver_t *drv; + + drv = *(ide_driver_t **)rq->rq_disk->private_data; + return drv->error(drive, rq, stat, err); + } else + return __ide_error(drive, rq, stat, err); } EXPORT_SYMBOL_GPL(ide_error); @@ -535,7 +552,8 @@ ide_startstop_t __ide_abort(ide_drive_t *drive, struct request *rq) if (drive->media != ide_disk) rq->errors |= ERROR_RESET; - DRIVER(drive)->end_request(drive, 0, 0); + ide_kill_rq(drive, rq); + return ide_stopped; } @@ -569,7 +587,13 @@ ide_startstop_t ide_abort(ide_drive_t *drive, const char *msg) return ide_stopped; } - return drive->driver->abort(drive, rq); + if (rq->rq_disk) { + ide_driver_t *drv; + + drv = *(ide_driver_t **)rq->rq_disk->private_data; + return drv->abort(drive, rq); + } else + return __ide_abort(drive, rq); } /** @@ -622,7 +646,7 @@ static ide_startstop_t drive_cmd_intr (ide_drive_t *drive) udelay(100); } - if (!OK_STAT(stat, READY_STAT, BAD_STAT) && DRIVER(drive) != NULL) + if (!OK_STAT(stat, READY_STAT, BAD_STAT)) return ide_error(drive, "drive_cmd", stat); /* calls ide_end_drive_cmd */ ide_end_drive_cmd(drive, stat, hwif->INB(IDE_ERROR_REG)); @@ -922,6 +946,8 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq) return startstop; } if (!drive->special.all) { + ide_driver_t *drv; + if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK)) return execute_drive_cmd(drive, rq); else if (rq->flags & REQ_DRIVE_TASKFILE) @@ -937,11 +963,13 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq) ide_complete_pm_request(drive, rq); return startstop; } - return (DRIVER(drive)->do_request(drive, rq, block)); + + drv = *(ide_driver_t **)rq->rq_disk->private_data; + return drv->do_request(drive, rq, block); } return do_special(drive); kill_rq: - DRIVER(drive)->end_request(drive, 0, 0); + ide_kill_rq(drive, rq); return ide_stopped; } @@ -1616,8 +1644,6 @@ int ide_do_drive_cmd (ide_drive_t *drive, struct request *rq, ide_action_t actio rq->errors = 0; rq->rq_status = RQ_ACTIVE; - rq->rq_disk = drive->disk; - /* * we need to hold an extra reference to request for safe inspection * after completion diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index cb158558d20125..554473a95cf747 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -862,6 +862,13 @@ static void probe_hwif(ide_hwif_t *hwif) drive->autotune == IDE_TUNE_AUTO) /* auto-tune PIO mode */ hwif->tuneproc(drive, 255); + + if (drive->autotune != IDE_TUNE_DEFAULT && + drive->autotune != IDE_TUNE_AUTO) + continue; + + drive->nice1 = 1; + /* * MAJOR HACK BARF :-/ * @@ -871,9 +878,7 @@ static void probe_hwif(ide_hwif_t *hwif) * Move here to prevent module loading clashing. */ // drive->autodma = hwif->autodma; - if ((hwif->ide_dma_check) && - ((drive->autotune == IDE_TUNE_DEFAULT) || - (drive->autotune == IDE_TUNE_AUTO))) { + if (hwif->ide_dma_check) { /* * Force DMAing for the beginning of the check. * Some chipsets appear to do interesting @@ -1006,10 +1011,8 @@ static int ide_init_queue(ide_drive_t *drive) blk_queue_max_hw_segments(q, max_sg_entries); blk_queue_max_phys_segments(q, max_sg_entries); - /* assign drive and gendisk queue */ + /* assign drive queue */ drive->queue = q; - if (drive->disk) - drive->disk->queue = drive->queue; /* needs drive->queue to be set */ ide_toggle_bounce(drive, 1); @@ -1209,8 +1212,6 @@ static int ata_lock(dev_t dev, void *data) return 0; } -extern ide_driver_t idedefault_driver; - static struct kobject *ata_probe(dev_t dev, int *part, void *data) { ide_hwif_t *hwif = data; @@ -1218,52 +1219,66 @@ static struct kobject *ata_probe(dev_t dev, int *part, void *data) ide_drive_t *drive = &hwif->drives[unit]; if (!drive->present) return NULL; - if (drive->driver == &idedefault_driver) { - if (drive->media == ide_disk) - (void) request_module("ide-disk"); - if (drive->scsi) - (void) request_module("ide-scsi"); - if (drive->media == ide_cdrom || drive->media == ide_optical) - (void) request_module("ide-cd"); - if (drive->media == ide_tape) - (void) request_module("ide-tape"); - if (drive->media == ide_floppy) - (void) request_module("ide-floppy"); - } - if (drive->driver == &idedefault_driver) - return NULL; + + if (drive->media == ide_disk) + request_module("ide-disk"); + if (drive->scsi) + request_module("ide-scsi"); + if (drive->media == ide_cdrom || drive->media == ide_optical) + request_module("ide-cd"); + if (drive->media == ide_tape) + request_module("ide-tape"); + if (drive->media == ide_floppy) + request_module("ide-floppy"); + + return NULL; +} + +static struct kobject *exact_match(dev_t dev, int *part, void *data) +{ + struct gendisk *p = data; *part &= (1 << PARTN_BITS) - 1; - return get_disk(drive->disk); + return &p->kobj; } -static int alloc_disks(ide_hwif_t *hwif) +static int exact_lock(dev_t dev, void *data) { - unsigned int unit; - struct gendisk *disks[MAX_DRIVES]; + struct gendisk *p = data; - for (unit = 0; unit < MAX_DRIVES; unit++) { - disks[unit] = alloc_disk(1 << PARTN_BITS); - if (!disks[unit]) - goto Enomem; - } - for (unit = 0; unit < MAX_DRIVES; ++unit) { - ide_drive_t *drive = &hwif->drives[unit]; - struct gendisk *disk = disks[unit]; - disk->major = hwif->major; - disk->first_minor = unit << PARTN_BITS; - sprintf(disk->disk_name,"hd%c",'a'+hwif->index*MAX_DRIVES+unit); - disk->fops = ide_fops; - disk->private_data = drive; - drive->disk = disk; - } + if (!get_disk(p)) + return -1; return 0; -Enomem: - printk(KERN_WARNING "(ide::init_gendisk) Out of memory\n"); - while (unit--) - put_disk(disks[unit]); - return -ENOMEM; } +void ide_register_region(struct gendisk *disk) +{ + blk_register_region(MKDEV(disk->major, disk->first_minor), + disk->minors, NULL, exact_match, exact_lock, disk); +} + +EXPORT_SYMBOL_GPL(ide_register_region); + +void ide_unregister_region(struct gendisk *disk) +{ + blk_unregister_region(MKDEV(disk->major, disk->first_minor), + disk->minors); +} + +EXPORT_SYMBOL_GPL(ide_unregister_region); + +void ide_init_disk(struct gendisk *disk, ide_drive_t *drive) +{ + ide_hwif_t *hwif = drive->hwif; + unsigned int unit = (drive->select.all >> 4) & 1; + + disk->major = hwif->major; + disk->first_minor = unit << PARTN_BITS; + sprintf(disk->disk_name, "hd%c", 'a' + hwif->index * MAX_DRIVES + unit); + disk->queue = drive->queue; +} + +EXPORT_SYMBOL_GPL(ide_init_disk); + static void drive_release_dev (struct device *dev) { ide_drive_t *drive = container_of(dev, ide_drive_t, gendev); @@ -1304,7 +1319,7 @@ static void init_gendisk (ide_hwif_t *hwif) static int hwif_init(ide_hwif_t *hwif) { - int old_irq, unit; + int old_irq; /* Return success if no device is connected */ if (!hwif->present) @@ -1340,9 +1355,6 @@ static int hwif_init(ide_hwif_t *hwif) printk(KERN_ERR "%s: unable to allocate SG table.\n", hwif->name); goto out; } - - if (alloc_disks(hwif) < 0) - goto out; if (init_irq(hwif) == 0) goto done; @@ -1355,12 +1367,12 @@ static int hwif_init(ide_hwif_t *hwif) if (!(hwif->irq = ide_default_irq(hwif->io_ports[IDE_DATA_OFFSET]))) { printk("%s: Disabled unable to get IRQ %d.\n", hwif->name, old_irq); - goto out_disks; + goto out; } if (init_irq(hwif)) { printk("%s: probed IRQ %d and default IRQ %d failed.\n", hwif->name, old_irq, hwif->irq); - goto out_disks; + goto out; } printk("%s: probed IRQ %d failed, using default.\n", hwif->name, hwif->irq); @@ -1370,12 +1382,6 @@ done: hwif->present = 1; /* success */ return 1; -out_disks: - for (unit = 0; unit < MAX_DRIVES; unit++) { - struct gendisk *disk = hwif->drives[unit].disk; - hwif->drives[unit].disk = NULL; - put_disk(disk); - } out: unregister_blkdev(hwif->major, hwif->name); return 0; diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c index 30e9611fc728de..bdff5ac580531c 100644 --- a/drivers/ide/ide-proc.c +++ b/drivers/ide/ide-proc.c @@ -107,8 +107,6 @@ static int proc_ide_read_identify if (drive) { unsigned short *val = (unsigned short *) page; - BUG_ON(!drive->driver); - err = taskfile_lib_get_identify(drive, page); if (!err) { char *out = ((char *)page) + (SECTOR_WORDS * 4); @@ -312,8 +310,11 @@ static int proc_ide_read_driver ide_driver_t *driver = drive->driver; int len; - len = sprintf(page, "%s version %s\n", - driver->name, driver->version); + if (driver) { + len = sprintf(page, "%s version %s\n", + driver->name, driver->version); + } else + len = sprintf(page, "ide-default version 0.9.newide\n"); PROC_IDE_READ_RETURN(page,start,off,count,eof,len); } @@ -421,10 +422,7 @@ static void create_proc_ide_drives(ide_hwif_t *hwif) static void destroy_proc_ide_device(ide_hwif_t *hwif, ide_drive_t *drive) { - ide_driver_t *driver = drive->driver; - if (drive->proc) { - ide_remove_proc_entries(drive->proc, driver->proc); ide_remove_proc_entries(drive->proc, generic_drive_entries); remove_proc_entry(drive->name, proc_ide_root); remove_proc_entry(drive->name, hwif->proc); diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 913d762c5220d4..4825448549850d 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -783,6 +783,8 @@ typedef struct { */ typedef struct ide_tape_obj { ide_drive_t *drive; + ide_driver_t *driver; + struct gendisk *disk; struct kref kref; /* @@ -1013,7 +1015,8 @@ static DECLARE_MUTEX(idetape_ref_sem); #define to_ide_tape(obj) container_of(obj, struct ide_tape_obj, kref) -#define ide_tape_g(disk) ((disk)->private_data) +#define ide_tape_g(disk) \ + container_of((disk)->private_data, struct ide_tape_obj, driver) static struct ide_tape_obj *ide_tape_get(struct gendisk *disk) { @@ -1543,6 +1546,7 @@ static void idetape_active_next_stage (ide_drive_t *drive) } #endif /* IDETAPE_DEBUG_BUGS */ + rq->rq_disk = tape->disk; rq->buffer = NULL; rq->special = (void *)stage->bh; tape->active_data_request = rq; @@ -1795,8 +1799,11 @@ static void idetape_init_rq(struct request *rq, u8 cmd) */ static void idetape_queue_pc_head (ide_drive_t *drive, idetape_pc_t *pc,struct request *rq) { + struct ide_tape_obj *tape = drive->driver_data; + idetape_init_rq(rq, REQ_IDETAPE_PC1); rq->buffer = (char *) pc; + rq->rq_disk = tape->disk; (void) ide_do_drive_cmd(drive, rq, ide_preempt); } @@ -2852,10 +2859,12 @@ static void idetape_create_test_unit_ready_cmd(idetape_pc_t *pc) */ static int __idetape_queue_pc_tail (ide_drive_t *drive, idetape_pc_t *pc) { + struct ide_tape_obj *tape = drive->driver_data; struct request rq; idetape_init_rq(&rq, REQ_IDETAPE_PC1); rq.buffer = (char *) pc; + rq.rq_disk = tape->disk; return ide_do_drive_cmd(drive, &rq, ide_wait); } @@ -3079,6 +3088,7 @@ static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int blocks, struct #endif /* IDETAPE_DEBUG_BUGS */ idetape_init_rq(&rq, cmd); + rq.rq_disk = tape->disk; rq.special = (void *)bh; rq.sector = tape->first_frame_position; rq.nr_sectors = rq.current_nr_sectors = blocks; @@ -4687,6 +4697,8 @@ static int idetape_cleanup (ide_drive_t *drive) DRIVER(drive)->busy = 0; (void) ide_unregister_subdriver(drive); + ide_unregister_region(tape->disk); + ide_tape_put(tape); return 0; @@ -4696,15 +4708,16 @@ static void ide_tape_release(struct kref *kref) { struct ide_tape_obj *tape = to_ide_tape(kref); ide_drive_t *drive = tape->drive; - struct gendisk *g = drive->disk; + struct gendisk *g = tape->disk; + drive->dsc_overlap = 0; drive->driver_data = NULL; devfs_remove("%s/mt", drive->devfs_name); devfs_remove("%s/mtn", drive->devfs_name); devfs_unregister_tape(g->number); idetape_devs[tape->minor] = NULL; g->private_data = NULL; - g->fops = ide_fops; + put_disk(g); kfree(tape); } @@ -4819,7 +4832,7 @@ static struct block_device_operations idetape_block_ops = { static int idetape_attach (ide_drive_t *drive) { idetape_tape_t *tape; - struct gendisk *g = drive->disk; + struct gendisk *g; int minor; if (!strstr("ide-tape", drive->driver_req)) @@ -4845,10 +4858,16 @@ static int idetape_attach (ide_drive_t *drive) printk(KERN_ERR "ide-tape: %s: Can't allocate a tape structure\n", drive->name); goto failed; } + + g = alloc_disk(1 << PARTN_BITS); + if (!g) + goto out_free_tape; + + ide_init_disk(g, drive); + if (ide_register_subdriver(drive, &idetape_driver)) { printk(KERN_ERR "ide-tape: %s: Failed to register the driver with ide.c\n", drive->name); - kfree(tape); - goto failed; + goto out_put_disk; } memset(tape, 0, sizeof(*tape)); @@ -4856,6 +4875,10 @@ static int idetape_attach (ide_drive_t *drive) kref_init(&tape->kref); tape->drive = drive; + tape->driver = &idetape_driver; + tape->disk = g; + + g->private_data = &tape->driver; drive->driver_data = tape; @@ -4876,9 +4899,13 @@ static int idetape_attach (ide_drive_t *drive) g->number = devfs_register_tape(drive->devfs_name); g->fops = &idetape_block_ops; - g->private_data = tape; + ide_register_region(g); return 0; +out_put_disk: + put_disk(g); +out_free_tape: + kfree(tape); failed: return 1; } diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c index 246a1a1bd46577..d04f62ab5de199 100644 --- a/drivers/ide/ide-taskfile.c +++ b/drivers/ide/ide-taskfile.c @@ -354,8 +354,12 @@ static ide_startstop_t task_error(ide_drive_t *drive, struct request *rq, break; } - if (sectors > 0) - drive->driver->end_request(drive, 1, sectors); + if (sectors > 0) { + ide_driver_t *drv; + + drv = *(ide_driver_t **)rq->rq_disk->private_data; + drv->end_request(drive, 1, sectors); + } } return ide_error(drive, s, stat); } @@ -371,7 +375,8 @@ static void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat) return; } } - drive->driver->end_request(drive, 1, rq->hard_nr_sectors); + + ide_end_request(drive, 1, rq->hard_nr_sectors); } /* diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 20da2d61b200f9..973dec799b5c8b 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -196,7 +196,7 @@ ide_hwif_t ide_hwifs[MAX_HWIFS]; /* master data repository */ EXPORT_SYMBOL(ide_hwifs); -extern ide_driver_t idedefault_driver; +static struct list_head ide_drives = LIST_HEAD_INIT(ide_drives); /* * Do not even *think* about calling this! @@ -245,7 +245,6 @@ static void init_hwif_data(ide_hwif_t *hwif, unsigned int index) drive->max_failures = IDE_DEFAULT_MAX_FAILURES; drive->using_dma = 0; drive->is_flash = 0; - drive->driver = &idedefault_driver; drive->vdma = 0; INIT_LIST_HEAD(&drive->list); sema_init(&drive->gendev_rel_sem, 0); @@ -359,11 +358,6 @@ static int ide_system_bus_speed(void) return system_bus_speed; } -static int ide_open (struct inode * inode, struct file * filp) -{ - return -ENXIO; -} - /* * drives_lock protects the list of drives, drivers_lock the * list of drivers. Currently nobody takes both at once. @@ -763,11 +757,6 @@ void ide_unregister(unsigned int index) * Remove us from the kernel's knowledge */ blk_unregister_region(MKDEV(hwif->major, 0), MAX_DRIVES<<PARTN_BITS); - for (i = 0; i < MAX_DRIVES; i++) { - struct gendisk *disk = hwif->drives[i].disk; - hwif->drives[i].disk = NULL; - put_disk(disk); - } kfree(hwif->sg_table); unregister_blkdev(hwif->major, hwif->name); spin_lock_irq(&ide_lock); @@ -931,7 +920,7 @@ EXPORT_SYMBOL(ide_register_hw); DECLARE_MUTEX(ide_setting_sem); /** - * ide_add_setting - add an ide setting option + * __ide_add_setting - add an ide setting option * @drive: drive to use * @name: setting name * @rw: true if the function is read write @@ -944,6 +933,7 @@ DECLARE_MUTEX(ide_setting_sem); * @div_factor: divison scale * @data: private data field * @set: setting + * @auto_remove: setting auto removal flag * * Removes the setting named from the device if it is present. * The function takes the settings_lock to protect against @@ -955,8 +945,8 @@ DECLARE_MUTEX(ide_setting_sem); * a driver is attached we assume the driver settings are auto * remove. */ - -int ide_add_setting (ide_drive_t *drive, const char *name, int rw, int read_ioctl, int write_ioctl, int data_type, int min, int max, int mul_factor, int div_factor, void *data, ide_procset_t *set) + +static int __ide_add_setting(ide_drive_t *drive, const char *name, int rw, int read_ioctl, int write_ioctl, int data_type, int min, int max, int mul_factor, int div_factor, void *data, ide_procset_t *set, int auto_remove) { ide_settings_t **p = (ide_settings_t **) &drive->settings, *setting = NULL; @@ -981,7 +971,7 @@ int ide_add_setting (ide_drive_t *drive, const char *name, int rw, int read_ioct setting->set = set; setting->next = *p; - if (drive->driver != &idedefault_driver) + if (auto_remove) setting->auto_remove = 1; *p = setting; up(&ide_setting_sem); @@ -993,6 +983,11 @@ abort: return -1; } +int ide_add_setting(ide_drive_t *drive, const char *name, int rw, int read_ioctl, int write_ioctl, int data_type, int min, int max, int mul_factor, int div_factor, void *data, ide_procset_t *set) +{ + return __ide_add_setting(drive, name, rw, read_ioctl, write_ioctl, data_type, min, max, mul_factor, div_factor, data, set, 1); +} + EXPORT_SYMBOL(ide_add_setting); /** @@ -1282,17 +1277,17 @@ static int set_xfer_rate (ide_drive_t *drive, int arg) void ide_add_generic_settings (ide_drive_t *drive) { /* - * drive setting name read/write access read ioctl write ioctl data type min max mul_factor div_factor data pointer set function + * drive setting name read/write access read ioctl write ioctl data type min max mul_factor div_factor data pointer set function */ - ide_add_setting(drive, "io_32bit", drive->no_io_32bit ? SETTING_READ : SETTING_RW, HDIO_GET_32BIT, HDIO_SET_32BIT, TYPE_BYTE, 0, 1 + (SUPPORT_VLB_SYNC << 1), 1, 1, &drive->io_32bit, set_io_32bit); - ide_add_setting(drive, "keepsettings", SETTING_RW, HDIO_GET_KEEPSETTINGS, HDIO_SET_KEEPSETTINGS, TYPE_BYTE, 0, 1, 1, 1, &drive->keep_settings, NULL); - ide_add_setting(drive, "nice1", SETTING_RW, -1, -1, TYPE_BYTE, 0, 1, 1, 1, &drive->nice1, NULL); - ide_add_setting(drive, "pio_mode", SETTING_WRITE, -1, HDIO_SET_PIO_MODE, TYPE_BYTE, 0, 255, 1, 1, NULL, set_pio_mode); - ide_add_setting(drive, "unmaskirq", drive->no_unmask ? SETTING_READ : SETTING_RW, HDIO_GET_UNMASKINTR, HDIO_SET_UNMASKINTR, TYPE_BYTE, 0, 1, 1, 1, &drive->unmask, NULL); - ide_add_setting(drive, "using_dma", SETTING_RW, HDIO_GET_DMA, HDIO_SET_DMA, TYPE_BYTE, 0, 1, 1, 1, &drive->using_dma, set_using_dma); - ide_add_setting(drive, "init_speed", SETTING_RW, -1, -1, TYPE_BYTE, 0, 70, 1, 1, &drive->init_speed, NULL); - ide_add_setting(drive, "current_speed", SETTING_RW, -1, -1, TYPE_BYTE, 0, 70, 1, 1, &drive->current_speed, set_xfer_rate); - ide_add_setting(drive, "number", SETTING_RW, -1, -1, TYPE_BYTE, 0, 3, 1, 1, &drive->dn, NULL); + __ide_add_setting(drive, "io_32bit", drive->no_io_32bit ? SETTING_READ : SETTING_RW, HDIO_GET_32BIT, HDIO_SET_32BIT, TYPE_BYTE, 0, 1 + (SUPPORT_VLB_SYNC << 1), 1, 1, &drive->io_32bit, set_io_32bit, 0); + __ide_add_setting(drive, "keepsettings", SETTING_RW, HDIO_GET_KEEPSETTINGS, HDIO_SET_KEEPSETTINGS, TYPE_BYTE, 0, 1, 1, 1, &drive->keep_settings, NULL, 0); + __ide_add_setting(drive, "nice1", SETTING_RW, -1, -1, TYPE_BYTE, 0, 1, 1, 1, &drive->nice1, NULL, 0); + __ide_add_setting(drive, "pio_mode", SETTING_WRITE, -1, HDIO_SET_PIO_MODE, TYPE_BYTE, 0, 255, 1, 1, NULL, set_pio_mode, 0); + __ide_add_setting(drive, "unmaskirq", drive->no_unmask ? SETTING_READ : SETTING_RW, HDIO_GET_UNMASKINTR, HDIO_SET_UNMASKINTR, TYPE_BYTE, 0, 1, 1, 1, &drive->unmask, NULL, 0); + __ide_add_setting(drive, "using_dma", SETTING_RW, HDIO_GET_DMA, HDIO_SET_DMA, TYPE_BYTE, 0, 1, 1, 1, &drive->using_dma, set_using_dma, 0); + __ide_add_setting(drive, "init_speed", SETTING_RW, -1, -1, TYPE_BYTE, 0, 70, 1, 1, &drive->init_speed, NULL, 0); + __ide_add_setting(drive, "current_speed", SETTING_RW, -1, -1, TYPE_BYTE, 0, 70, 1, 1, &drive->current_speed, set_xfer_rate, 0); + __ide_add_setting(drive, "number", SETTING_RW, -1, -1, TYPE_BYTE, 0, 3, 1, 1, &drive->dn, NULL, 0); } /** @@ -1330,7 +1325,7 @@ int ide_replace_subdriver (ide_drive_t *drive, const char *driver) } else { drive->driver_req[0] = 0; } - if (DRIVER(drive)!= &idedefault_driver && !strcmp(DRIVER(drive)->name, driver)) + if (drive->driver && !strcmp(drive->driver->name, driver)) return 0; abort: return 1; @@ -1369,9 +1364,9 @@ int ata_attach(ide_drive_t *drive) spin_lock(&drivers_lock); module_put(driver->owner); } - drive->gendev.driver = &idedefault_driver.gen_driver; + drive->gendev.driver = NULL; spin_unlock(&drivers_lock); - if(idedefault_driver.attach(drive) != 0) + if (ide_register_subdriver(drive, NULL)) panic("ide: default attach failed"); return 1; } @@ -1418,6 +1413,7 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device unsigned int cmd, unsigned long arg) { ide_settings_t *setting; + ide_driver_t *drv; int err = 0; void __user *p = (void __user *)arg; @@ -1517,7 +1513,8 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device if (arg != (arg & ((1 << IDE_NICE_DSC_OVERLAP) | (1 << IDE_NICE_1)))) return -EPERM; drive->dsc_overlap = (arg >> IDE_NICE_DSC_OVERLAP) & 1; - if (drive->dsc_overlap && !DRIVER(drive)->supports_dsc_overlap) { + drv = *(ide_driver_t **)bdev->bd_disk->private_data; + if (drive->dsc_overlap && !drv->supports_dsc_overlap) { drive->dsc_overlap = 0; return -EPERM; } @@ -2020,10 +2017,8 @@ int ide_register_subdriver(ide_drive_t *drive, ide_driver_t *driver) { unsigned long flags; - BUG_ON(!drive->driver); - spin_lock_irqsave(&ide_lock, flags); - if (!drive->present || drive->driver != &idedefault_driver || + if (!drive->present || drive->driver != NULL || drive->usage || drive->dead) { spin_unlock_irqrestore(&ide_lock, flags); return 1; @@ -2031,17 +2026,11 @@ int ide_register_subdriver(ide_drive_t *drive, ide_driver_t *driver) drive->driver = driver; spin_unlock_irqrestore(&ide_lock, flags); spin_lock(&drives_lock); - list_add_tail(&drive->list, &driver->drives); + list_add_tail(&drive->list, driver ? &driver->drives : &ide_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 */ - drive->dsc_overlap = (drive->next != drive && driver->supports_dsc_overlap); - drive->nice1 = 1; - } #ifdef CONFIG_PROC_FS - if (drive->driver != &idedefault_driver) + if (driver) ide_add_proc_entries(drive->proc, driver->proc, drive); #endif return 0; @@ -2069,7 +2058,7 @@ int ide_unregister_subdriver (ide_drive_t *drive) down(&ide_setting_sem); spin_lock_irqsave(&ide_lock, flags); - if (drive->usage || drive->driver == &idedefault_driver || DRIVER(drive)->busy) { + if (drive->usage || drive->driver == NULL || DRIVER(drive)->busy) { spin_unlock_irqrestore(&ide_lock, flags); up(&ide_setting_sem); return 1; @@ -2078,13 +2067,13 @@ int ide_unregister_subdriver (ide_drive_t *drive) ide_remove_proc_entries(drive->proc, DRIVER(drive)->proc); #endif auto_remove_settings(drive); - drive->driver = &idedefault_driver; + drive->driver = NULL; spin_unlock_irqrestore(&ide_lock, flags); up(&ide_setting_sem); spin_lock(&drives_lock); list_del_init(&drive->list); spin_unlock(&drives_lock); - /* drive will be added to &idedefault_driver->drives in ata_attach() */ + /* drive will be added to &ide_drives in ata_attach() */ return 0; } @@ -2120,7 +2109,7 @@ int ide_register_driver(ide_driver_t *driver) INIT_LIST_HEAD(&list); spin_lock(&drives_lock); - list_splice_init(&idedefault_driver.drives, &list); + list_splice_init(&ide_drives, &list); spin_unlock(&drives_lock); list_for_each_safe(list_loop, tmp_storage, &list) { @@ -2170,13 +2159,6 @@ void ide_unregister_driver(ide_driver_t *driver) EXPORT_SYMBOL(ide_unregister_driver); -struct block_device_operations ide_fops[] = {{ - .owner = THIS_MODULE, - .open = ide_open, -}}; - -EXPORT_SYMBOL(ide_fops); - /* * Probe module */ diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c index d90f4d2251ab0f..069dbffe211667 100644 --- a/drivers/ide/pci/via82cxxx.c +++ b/drivers/ide/pci/via82cxxx.c @@ -332,11 +332,8 @@ static int via_set_drive(ide_drive_t *drive, u8 speed) struct ide_timing t, p; unsigned int T, UT; - if (speed != XFER_PIO_SLOW && speed != drive->current_speed) - if (ide_config_drive_speed(drive, speed)) - printk(KERN_WARNING "ide%d: Drive %d didn't " - "accept speed setting. Oh, well.\n", - drive->dn >> 1, drive->dn & 1); + if (speed != XFER_PIO_SLOW) + ide_config_drive_speed(drive, speed); T = 1000000000 / via_clock; diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index 805cccd042b671..2e2486b035dd95 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -98,6 +98,8 @@ typedef struct idescsi_pc_s { typedef struct ide_scsi_obj { ide_drive_t *drive; + ide_driver_t *driver; + struct gendisk *disk; struct Scsi_Host *host; idescsi_pc_t *pc; /* Current packet command */ @@ -108,7 +110,8 @@ typedef struct ide_scsi_obj { static DECLARE_MUTEX(idescsi_ref_sem); -#define ide_scsi_g(disk) ((disk)->private_data) +#define ide_scsi_g(disk) \ + container_of((disk)->private_data, struct ide_scsi_obj, driver) static struct ide_scsi_obj *ide_scsi_get(struct gendisk *disk) { @@ -323,9 +326,12 @@ static int idescsi_check_condition(ide_drive_t *drive, struct request *failed_co printk ("ide-scsi: %s: queue cmd = ", drive->name); hexdump(pc->c, 6); } + rq->rq_disk = scsi->disk; return ide_do_drive_cmd(drive, rq, ide_preempt); } +static int idescsi_end_request(ide_drive_t *, int, int); + static ide_startstop_t idescsi_atapi_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err) { @@ -334,7 +340,9 @@ idescsi_atapi_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err) HWIF(drive)->OUTB(WIN_IDLEIMMEDIATE,IDE_COMMAND_REG); rq->errors++; - DRIVER(drive)->end_request(drive, 0, 0); + + idescsi_end_request(drive, 0, 0); + return ide_stopped; } @@ -346,7 +354,9 @@ idescsi_atapi_abort(ide_drive_t *drive, struct request *rq) ((idescsi_pc_t *) rq->special)->scsi_cmd->serial_number); #endif rq->errors |= ERROR_MAX; - DRIVER(drive)->end_request(drive, 0, 0); + + idescsi_end_request(drive, 0, 0); + return ide_stopped; } @@ -718,17 +728,20 @@ static void idescsi_setup (ide_drive_t *drive, idescsi_scsi_t *scsi) static int idescsi_cleanup (ide_drive_t *drive) { struct Scsi_Host *scsihost = drive->driver_data; - struct gendisk *g = drive->disk; + struct ide_scsi_obj *scsi = scsihost_to_idescsi(scsihost); + struct gendisk *g = scsi->disk; if (ide_unregister_subdriver(drive)) return 1; + ide_unregister_region(g); + drive->driver_data = NULL; g->private_data = NULL; - g->fops = ide_fops; + put_disk(g); scsi_remove_host(scsihost); - ide_scsi_put(scsihost_to_idescsi(scsihost)); + ide_scsi_put(scsi); return 0; } @@ -910,6 +923,7 @@ static int idescsi_queue (struct scsi_cmnd *cmd, rq->special = (char *) pc; rq->flags = REQ_SPECIAL; spin_unlock_irq(host->host_lock); + rq->rq_disk = scsi->disk; (void) ide_do_drive_cmd (drive, rq, ide_end); spin_lock_irq(host->host_lock); return 0; @@ -1085,9 +1099,9 @@ static int idescsi_attach(ide_drive_t *drive) { idescsi_scsi_t *idescsi; struct Scsi_Host *host; - struct gendisk *g = drive->disk; + struct gendisk *g; static int warned; - int err; + int err = -ENOMEM; if (!warned && drive->media == ide_cdrom) { printk(KERN_WARNING "ide-scsi is deprecated for cd burning! Use ide-cd and give dev=/dev/hdX as device\n"); @@ -1100,6 +1114,12 @@ static int idescsi_attach(ide_drive_t *drive) !(host = scsi_host_alloc(&idescsi_template,sizeof(idescsi_scsi_t)))) return 1; + g = alloc_disk(1 << PARTN_BITS); + if (!g) + goto out_host_put; + + ide_init_disk(g, drive); + host->max_id = 1; #if IDESCSI_DEBUG_LOG @@ -1114,21 +1134,27 @@ static int idescsi_attach(ide_drive_t *drive) drive->driver_data = host; idescsi = scsihost_to_idescsi(host); idescsi->drive = drive; + idescsi->driver = &idescsi_driver; idescsi->host = host; + idescsi->disk = g; + g->private_data = &idescsi->driver; err = ide_register_subdriver(drive, &idescsi_driver); if (!err) { idescsi_setup (drive, idescsi); g->fops = &idescsi_ops; - g->private_data = idescsi; + ide_register_region(g); err = scsi_add_host(host, &drive->gendev); if (!err) { scsi_scan_host(host); return 0; } /* fall through on error */ + ide_unregister_region(g); ide_unregister_subdriver(drive); } + put_disk(g); +out_host_put: scsi_host_put(host); return err; } diff --git a/include/linux/ide.h b/include/linux/ide.h index 58d91a9d533256..9cfc0999becba7 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -756,7 +756,6 @@ typedef struct ide_drive_s { struct list_head list; struct device gendev; struct semaphore gendev_rel_sem; /* to deal with device release() */ - struct gendisk *disk; } ide_drive_t; #define IDE_CHIPSET_PCI_MASK \ @@ -1327,7 +1326,7 @@ extern irqreturn_t ide_intr(int irq, void *dev_id, struct pt_regs *regs); extern void do_ide_request(request_queue_t *); extern void ide_init_subdrivers(void); -extern struct block_device_operations ide_fops[]; +void ide_init_disk(struct gendisk *, ide_drive_t *); extern int ata_attach(ide_drive_t *); @@ -1442,6 +1441,9 @@ extern int ide_hwif_request_regions(ide_hwif_t *hwif); extern void ide_hwif_release_regions(ide_hwif_t* hwif); extern void ide_unregister (unsigned int index); +void ide_register_region(struct gendisk *); +void ide_unregister_region(struct gendisk *); + void ide_undecoded_slave(ide_hwif_t *); int probe_hwif_init_with_fixup(ide_hwif_t *, void (*)(ide_hwif_t *)); |