* [PATCH] driver model for scsi upper drivers, take 2
@ 2003-05-27 7:32 Christoph Hellwig
2003-05-27 9:43 ` Christoph Hellwig
0 siblings, 1 reply; 4+ messages in thread
From: Christoph Hellwig @ 2003-05-27 7:32 UTC (permalink / raw)
To: James.Bottomley; +Cc: linux-scsi
- removed the tape sysfs pseudodevice crap that caused hangs
- switched sg to a class_interface. This means sg can be used
on devices already claimed be an upper driver again. This
also means I had to remove the sg sysfs attributes temporarily
because the old mechanism is gone, but I'll restore them
differently in a followon patch.
--- 1.64/drivers/scsi/hosts.c Tue May 13 00:50:42 2003
+++ edited/drivers/scsi/hosts.c Fri May 16 17:34:35 2003
@@ -229,27 +229,18 @@
int scsi_add_host(struct Scsi_Host *shost, struct device *dev)
{
Scsi_Host_Template *sht = shost->hostt;
- struct scsi_device *sdev;
- int error = 0, saved_error = 0;
+ int error;
printk(KERN_INFO "scsi%d : %s\n", shost->host_no,
sht->info ? sht->info(shost) : sht->name);
error = scsi_sysfs_add_host(shost, dev);
- if (error)
- return error;
-
- scsi_proc_host_add(shost);
-
- scsi_scan_host(shost);
+ if (!error) {
+ scsi_proc_host_add(shost);
+ scsi_scan_host(shost);
+ };
- list_for_each_entry (sdev, &shost->my_devices, siblings) {
- error = scsi_attach_device(sdev);
- if (error)
- saved_error = error;
- }
-
- return saved_error;
+ return error;
}
/**
===== drivers/scsi/hosts.h 1.63 vs edited =====
--- 1.63/drivers/scsi/hosts.h Thu May 8 20:24:14 2003
+++ edited/drivers/scsi/hosts.h Fri May 16 17:34:35 2003
@@ -532,25 +532,18 @@
return shost->host_gendev.parent;
}
-struct Scsi_Device_Template
-{
- struct list_head list;
- const char * name;
- struct module * module; /* Used for loadable modules */
- unsigned char scsi_type;
- int (*attach)(Scsi_Device *); /* Attach devices to arrays */
- void (*detach)(Scsi_Device *);
- int (*init_command)(Scsi_Cmnd *); /* Used by new queueing code.
- Selects command for blkdevs */
- void (*rescan)(Scsi_Device *);
- struct device_driver scsi_driverfs_driver;
+struct scsi_driver {
+ struct module *owner;
+ struct device_driver gendrv;
+
+ int (*init_command)(struct scsi_cmnd *);
+ void (*rescan)(struct device *);
};
+#define to_scsi_driver(drv) \
+ container_of((drv), struct scsi_driver, gendrv)
-/*
- * Highlevel driver registration/unregistration.
- */
-extern int scsi_register_device(struct Scsi_Device_Template *);
-extern int scsi_unregister_device(struct Scsi_Device_Template *);
+extern int scsi_register_driver(struct scsi_driver *);
+extern void scsi_unregister_driver(struct scsi_driver *);
/*
* HBA allocation/freeing.
===== drivers/scsi/ide-scsi.c 1.23 vs edited =====
--- 1.23/drivers/scsi/ide-scsi.c Tue Jan 28 18:01:08 2003
+++ edited/drivers/scsi/ide-scsi.c Fri May 16 17:34:35 2003
@@ -770,8 +770,8 @@
struct gendisk *disk = cmd->request->rq_disk;
if (disk) {
- struct Scsi_Device_Template **p = disk->private_data;
- if (strcmp((*p)->scsi_driverfs_driver.name, "sg") == 0)
+ struct scsi_driver **p = disk->private_data;
+ if (strcmp((*p)->gendrv.name, "sg") == 0)
return test_bit(IDESCSI_SG_TRANSFORM, &scsi->transform);
}
return test_bit(IDESCSI_TRANSFORM, &scsi->transform);
===== drivers/scsi/osst.c 1.43 vs edited =====
--- 1.43/drivers/scsi/osst.c Wed May 7 16:15:37 2003
+++ edited/drivers/scsi/osst.c Fri May 16 17:34:35 2003
@@ -160,19 +160,15 @@
static int osst_copy_to_buffer(OSST_buffer *, unsigned char *);
static int osst_copy_from_buffer(OSST_buffer *, unsigned char *);
-static int osst_attach(Scsi_Device *);
-static void osst_detach(Scsi_Device *);
+static int osst_probe(struct device *);
+static int osst_remove(struct device *);
-struct Scsi_Device_Template osst_template =
-{
- .module = THIS_MODULE,
- .list = LIST_HEAD_INIT(osst_template.list),
- .name = "OnStream Tape",
- .scsi_type = TYPE_TAPE,
- .attach = osst_attach,
- .detach = osst_detach,
- .scsi_driverfs_driver = {
- .name = "osst",
+struct scsi_driver osst_template = {
+ .owner = THIS_MODULE,
+ .gendrv = {
+ .name = "osst",
+ .probe = osst_probe,
+ .remove = osst_remove,
}
};
@@ -5385,8 +5381,9 @@
* osst startup / cleanup code
*/
-static int osst_attach(Scsi_Device * SDp)
+static int osst_probe(struct device *dev)
{
+ Scsi_Device * SDp = to_scsi_device(dev);
OS_Scsi_Tape * tpnt;
ST_mode * STm;
ST_partstat * STps;
@@ -5395,12 +5392,12 @@
int i, mode, dev_num;
if (SDp->type != TYPE_TAPE || !osst_supports(SDp))
- return 1;
+ return -ENODEV;
drive = alloc_disk(1);
if (!drive) {
printk(KERN_ERR "osst :E: Out of memory. Device not attached.\n");
- return 1;
+ return -ENODEV;
}
/* if this is the first attach, build the infrastructure */
@@ -5576,16 +5573,17 @@
out_put_disk:
put_disk(drive);
- return 1;
+ return -ENODEV;
};
-static void osst_detach(Scsi_Device * SDp)
+static int osst_remove(struct device *dev)
{
+ Scsi_Device * SDp = to_scsi_device(dev);
OS_Scsi_Tape * tpnt;
int i, mode;
if ((SDp->type != TYPE_TAPE) || (osst_nr_dev <= 0))
- return;
+ return 0;
write_lock(&os_scsi_tapes_lock);
for(i=0; i < osst_max_dev; i++) {
@@ -5618,11 +5616,11 @@
kfree(tpnt->buffer);
}
kfree(tpnt);
- return;
+ return 0;
}
}
write_unlock(&os_scsi_tapes_lock);
- return;
+ return 0;
}
static int __init init_osst(void)
@@ -5631,7 +5629,7 @@
validate_options();
- if ((register_chrdev(OSST_MAJOR,"osst", &osst_fops) < 0) || scsi_register_device(&osst_template)) {
+ if ((register_chrdev(OSST_MAJOR,"osst", &osst_fops) < 0) || scsi_register_driver(&osst_template)) {
printk(KERN_ERR "osst :E: Unable to register major %d for OnStream tapes\n", OSST_MAJOR);
return 1;
}
@@ -5644,7 +5642,7 @@
int i;
OS_Scsi_Tape * STp;
- scsi_unregister_device(&osst_template);
+ scsi_unregister_driver(&osst_template);
unregister_chrdev(OSST_MAJOR, "osst");
if (os_scsi_tapes) {
===== drivers/scsi/osst.h 1.9 vs edited =====
--- 1.9/drivers/scsi/osst.h Fri Apr 18 17:57:20 2003
+++ edited/drivers/scsi/osst.h Fri May 16 17:34:35 2003
@@ -530,7 +530,7 @@
/* The OnStream tape drive descriptor */
typedef struct {
- struct Scsi_Device_Template *driver;
+ struct scsi_driver *driver;
unsigned capacity;
Scsi_Device* device;
struct semaphore lock; /* for serialization */
===== drivers/scsi/scsi.c 1.112 vs edited =====
--- 1.112/drivers/scsi/scsi.c Thu May 8 20:31:08 2003
+++ edited/drivers/scsi/scsi.c Fri May 16 17:34:35 2003
@@ -86,12 +86,6 @@
static unsigned long serial_number;
/*
- * List of all highlevel drivers.
- */
-LIST_HEAD(scsi_devicelist);
-static DECLARE_RWSEM(scsi_devicelist_mutex);
-
-/*
* Note - the initial logging level can be set here to log events at boot time.
* After the system is up, you may enable logging via the /proc interface.
*/
@@ -931,50 +925,6 @@
return depth;
}
-int scsi_attach_device(struct scsi_device *sdev)
-{
- struct Scsi_Device_Template *sdt;
-
- down_read(&scsi_devicelist_mutex);
- list_for_each_entry(sdt, &scsi_devicelist, list) {
- if (!try_module_get(sdt->module))
- continue;
- (*sdt->attach)(sdev);
- module_put(sdt->module);
- }
- up_read(&scsi_devicelist_mutex);
- return 0;
-}
-
-void scsi_detach_device(struct scsi_device *sdev)
-{
- struct Scsi_Device_Template *sdt;
-
- down_read(&scsi_devicelist_mutex);
- list_for_each_entry(sdt, &scsi_devicelist, list) {
- if (!try_module_get(sdt->module))
- continue;
- (*sdt->detach)(sdev);
- module_put(sdt->module);
- }
- up_read(&scsi_devicelist_mutex);
-}
-
-void scsi_rescan_device(struct scsi_device *sdev)
-{
- struct Scsi_Device_Template *sdt;
-
- down_read(&scsi_devicelist_mutex);
- list_for_each_entry(sdt, &scsi_devicelist, list) {
- if (!try_module_get(sdt->module))
- continue;
- if (*sdt->rescan)
- (*sdt->rescan)(sdev);
- module_put(sdt->module);
- }
- up_read(&scsi_devicelist_mutex);
-}
-
int scsi_device_get(struct scsi_device *sdev)
{
if (!try_module_get(sdev->host->hostt->module))
@@ -1028,71 +978,6 @@
} else {
/* FIXME: Send online state change hotplug event */
}
-}
-
-/*
- * This entry point is called from the upper level module's module_init()
- * routine. That implies that when this function is called, the
- * scsi_mod module is locked down because of upper module layering and
- * that the high level driver module is locked down by being in it's
- * init routine. So, the *only* thing we have to do to protect adds
- * we perform in this function is to make sure that all call's
- * to the high level driver's attach() and detach() call in points, other
- * than via scsi_register_device and scsi_unregister_device which are in
- * the module_init and module_exit code respectively and therefore already
- * locked down by the kernel module loader, are wrapped by try_module_get()
- * and module_put() to avoid races on device adds and removes.
- */
-int scsi_register_device(struct Scsi_Device_Template *tpnt)
-{
- struct scsi_device *sdev;
- struct Scsi_Host *shpnt;
-
-#ifdef CONFIG_KMOD
- if (scsi_host_get_next(NULL) == NULL)
- request_module("scsi_hostadapter");
-#endif
-
- if (!list_empty(&tpnt->list))
- return 1;
-
- down_write(&scsi_devicelist_mutex);
- list_add_tail(&tpnt->list, &scsi_devicelist);
- up_write(&scsi_devicelist_mutex);
-
- scsi_upper_driver_register(tpnt);
-
- for (shpnt = scsi_host_get_next(NULL); shpnt;
- shpnt = scsi_host_get_next(shpnt))
- list_for_each_entry(sdev, &shpnt->my_devices, siblings)
- (*tpnt->attach)(sdev);
-
- return 0;
-}
-
-int scsi_unregister_device(struct Scsi_Device_Template *tpnt)
-{
- struct scsi_device *sdev;
- struct Scsi_Host *shpnt;
-
- /*
- * Next, detach the devices from the driver.
- */
- for (shpnt = scsi_host_get_next(NULL); shpnt;
- shpnt = scsi_host_get_next(shpnt)) {
- list_for_each_entry(sdev, &shpnt->my_devices, siblings)
- (*tpnt->detach)(sdev);
- }
-
- /*
- * Extract the template from the linked list.
- */
- down_write(&scsi_devicelist_mutex);
- list_del(&tpnt->list);
- up_write(&scsi_devicelist_mutex);
-
- scsi_upper_driver_unregister(tpnt);
- return 0;
}
MODULE_DESCRIPTION("SCSI core");
===== drivers/scsi/scsi_lib.c 1.90 vs edited =====
--- 1.90/drivers/scsi/scsi_lib.c Thu May 8 21:14:09 2003
+++ edited/drivers/scsi/scsi_lib.c Fri May 16 17:34:35 2003
@@ -613,29 +613,6 @@
}
/*
- * Function: scsi_get_request_dev()
- *
- * Purpose: Find the upper-level driver that is responsible for this
- * request
- *
- * Arguments: request - I/O request we are preparing to queue.
- *
- * Lock status: No locks assumed to be held, but as it happens the
- * q->queue_lock is held when this is called.
- *
- * Returns: Nothing
- *
- * Notes: The requests in the request queue may have originated
- * from any block device driver. We need to find out which
- * one so that we can later form the appropriate command.
- */
-static struct Scsi_Device_Template *scsi_get_request_dev(struct request *req)
-{
- struct gendisk *p = req->rq_disk;
- return p ? *(struct Scsi_Device_Template **)p->private_data : NULL;
-}
-
-/*
* Function: scsi_io_completion()
*
* Purpose: Completion processing for block device I/O requests.
@@ -847,11 +824,7 @@
return;
}
if (result) {
- struct Scsi_Device_Template *sdt;
-
- sdt = scsi_get_request_dev(cmd->request);
- printk("SCSI %s error : <%d %d %d %d> return code = 0x%x\n",
- (sdt ? sdt->name : "device"),
+ printk("SCSI error : <%d %d %d %d> return code = 0x%x\n",
cmd->device->host->host_no,
cmd->device->channel,
cmd->device->id,
@@ -945,7 +918,6 @@
static int scsi_prep_fn(struct request_queue *q, struct request *req)
{
- struct Scsi_Device_Template *sdt;
struct scsi_device *sdev = q->queuedata;
struct scsi_cmnd *cmd;
@@ -1001,6 +973,7 @@
* happening now.
*/
if (req->flags & (REQ_CMD | REQ_BLOCK_PC)) {
+ struct scsi_driver *drv;
int ret;
/*
@@ -1015,8 +988,6 @@
* some kinds of consistency checking may cause the
* request to be rejected immediately.
*/
- sdt = scsi_get_request_dev(req);
- BUG_ON(!sdt);
/*
* This sets up the scatter-gather table (allocating if
@@ -1029,7 +1000,8 @@
/*
* Initialize the actual SCSI command for this request.
*/
- if (unlikely(!sdt->init_command(cmd))) {
+ drv = *(struct scsi_driver **)req->rq_disk->private_data;
+ if (unlikely(!drv->init_command(cmd))) {
scsi_release_buffers(cmd);
scsi_put_command(cmd);
return BLKPREP_KILL;
===== drivers/scsi/scsi_priv.h 1.6 vs edited =====
--- 1.6/drivers/scsi/scsi_priv.h Mon May 12 00:12:54 2003
+++ edited/drivers/scsi/scsi_priv.h Fri May 16 17:34:35 2003
@@ -41,9 +41,6 @@
#define SCSI_SENSE_VALID(scmd) \
(((scmd)->sense_buffer[0] & 0x70) == 0x70)
-struct Scsi_Device_Template;
-
-
/*
* scsi_target: representation of a scsi target, for now, this is only
* used for single_lun devices. If no one has active IO to the target,
@@ -68,9 +65,6 @@
extern void scsi_done(struct scsi_cmnd *cmd);
extern void scsi_finish_command(struct scsi_cmnd *cmd);
extern int scsi_retry_command(struct scsi_cmnd *cmd);
-extern int scsi_attach_device(struct scsi_device *sdev);
-extern void scsi_detach_device(struct scsi_device *sdev);
-extern void scsi_rescan_device(struct scsi_device *sdev);
extern int scsi_insert_special_req(struct scsi_request *sreq, int);
extern void scsi_init_cmd_from_req(struct scsi_cmnd *cmd,
struct scsi_request *sreq);
@@ -117,12 +111,11 @@
extern void scsi_free_sdev(struct scsi_device *);
extern void scsi_free_shost(struct Scsi_Host *);
extern void scsi_host_get(struct Scsi_Host *);
+extern void scsi_rescan_device(struct device *dev);
/* scsi_sysfs.c */
extern int scsi_device_register(struct scsi_device *);
extern void scsi_device_unregister(struct scsi_device *);
-extern int scsi_upper_driver_register(struct Scsi_Device_Template *);
-extern void scsi_upper_driver_unregister(struct Scsi_Device_Template *);
extern void scsi_sysfs_init_host(struct Scsi_Host *);
extern int scsi_sysfs_add_host(struct Scsi_Host *, struct device *);
extern void scsi_sysfs_remove_host(struct Scsi_Host *);
===== drivers/scsi/scsi_scan.c 1.85 vs edited =====
--- 1.85/drivers/scsi/scsi_scan.c Thu May 8 20:24:15 2003
+++ edited/drivers/scsi/scsi_scan.c Fri May 16 17:34:36 2003
@@ -1091,22 +1091,29 @@
uint channel, uint id, uint lun)
{
struct scsi_device *sdev;
- int error = -ENODEV, res;
+ int res;
res = scsi_probe_and_add_lun(shost, channel, id, lun, NULL, &sdev);
- if (res == SCSI_SCAN_LUN_PRESENT)
- error = scsi_attach_device(sdev);
-
- if (error)
- sdev = ERR_PTR(error);
+ if (res != SCSI_SCAN_LUN_PRESENT)
+ sdev = ERR_PTR(-ENODEV);
return sdev;
}
int scsi_remove_device(struct scsi_device *sdev)
{
- scsi_detach_device(sdev);
scsi_device_unregister(sdev);
return 0;
+}
+
+void scsi_rescan_device(struct device *dev)
+{
+ struct scsi_driver *drv = to_scsi_driver(dev->driver);
+
+ if (try_module_get(drv->owner)) {
+ if (drv->rescan)
+ drv->rescan(dev);
+ module_put(drv->owner);
+ }
}
/**
===== drivers/scsi/scsi_syms.c 1.36 vs edited =====
--- 1.36/drivers/scsi/scsi_syms.c Thu May 8 20:24:15 2003
+++ edited/drivers/scsi/scsi_syms.c Fri May 16 17:34:36 2003
@@ -29,8 +29,8 @@
* This source file contains the symbol table used by scsi loadable
* modules.
*/
-EXPORT_SYMBOL(scsi_register_device);
-EXPORT_SYMBOL(scsi_unregister_device);
+EXPORT_SYMBOL(scsi_register_driver);
+EXPORT_SYMBOL(scsi_unregister_driver);
EXPORT_SYMBOL(scsi_register_host);
EXPORT_SYMBOL(scsi_unregister_host);
EXPORT_SYMBOL(scsi_add_host);
===== drivers/scsi/scsi_sysfs.c 1.16 vs edited =====
--- 1.16/drivers/scsi/scsi_sysfs.c Mon May 12 00:12:40 2003
+++ edited/drivers/scsi/scsi_sysfs.c Fri May 16 17:34:36 2003
@@ -57,32 +57,12 @@
.name = "scsi_host",
};
-/**
- * scsi_bus_match:
- * @dev:
- * @dev_driver:
- *
- * Return value:
- **/
-static int scsi_bus_match(struct device *dev,
- struct device_driver *dev_driver)
+/* all probing is done in the individual ->probe routines */
+static int scsi_bus_match(struct device *dev, struct device_driver *gendrv)
{
- if (!strcmp("sg", dev_driver->name)) {
- if (strstr(dev->bus_id, ":gen"))
- return 1;
- } else if (!strcmp("st",dev_driver->name)) {
- if (strstr(dev->bus_id,":mt"))
- return 1;
- } else if (!strcmp("sd", dev_driver->name)) {
- if ((!strstr(dev->bus_id, ":gen")) &&
- (!strstr(dev->bus_id, ":mt"))) {
- return 1;
- }
- }
- return 0;
+ return 1;
}
-
static struct bus_type scsi_bus_type = {
.name = "scsi",
.match = scsi_bus_match,
@@ -109,34 +89,6 @@
bus_unregister(&scsi_bus_type);
}
-/**
- * scsi_upper_driver_register - register upper level driver.
- * @sdev_tp: Upper level driver to register with the scsi bus.
- *
- * Return value:
- * 0 on Success / non-zero on Failure
- **/
-int scsi_upper_driver_register(struct Scsi_Device_Template *sdev_tp)
-{
- int error = 0;
-
- sdev_tp->scsi_driverfs_driver.bus = &scsi_bus_type;
- error = driver_register(&sdev_tp->scsi_driverfs_driver);
-
- return error;
-}
-
-/**
- * scsi_upper_driver_unregister - unregister upper level driver
- * @sdev_tp: Upper level driver to unregister with the scsi bus.
- *
- **/
-void scsi_upper_driver_unregister(struct Scsi_Device_Template *sdev_tp)
-{
- driver_unregister(&sdev_tp->scsi_driverfs_driver);
-}
-
-
/*
* sdev_show_function: macro to create an attr function that can be used to
* show a non-bit field.
@@ -237,7 +189,7 @@
static ssize_t
store_rescan_field (struct device *dev, const char *buf, size_t count)
{
- scsi_rescan_device(to_scsi_device(dev));
+ scsi_rescan_device(dev);
return 0;
}
@@ -310,6 +262,18 @@
device_unregister(&sdev->sdev_driverfs_dev);
}
+int scsi_register_driver(struct scsi_driver *drv)
+{
+ drv->gendrv.bus = &scsi_bus_type;
+
+ return driver_register(&drv->gendrv);
+}
+
+void scsi_unregister_driver(struct scsi_driver *drv)
+{
+ driver_unregister(&drv->gendrv);
+}
+
static void scsi_host_release(struct device *dev)
{
struct Scsi_Host *shost;
@@ -347,7 +311,7 @@
int i, error;
if (!shost->host_gendev.parent)
- shost->host_gendev.parent = (dev) ? dev : &legacy_bus;
+ shost->host_gendev.parent = dev ? dev : &legacy_bus;
error = device_add(&shost->host_gendev);
if (error)
===== drivers/scsi/sd.c 1.112 vs edited =====
--- 1.112/drivers/scsi/sd.c Thu May 8 12:16:20 2003
+++ edited/drivers/scsi/sd.c Fri May 16 17:34:40 2003
@@ -73,8 +73,7 @@
#define SD_MAX_RETRIES 5
struct scsi_disk {
- struct list_head list; /* list of all scsi_disks */
- struct Scsi_Device_Template *driver; /* always &sd_template */
+ struct scsi_driver *driver; /* always &sd_template */
struct scsi_device *device;
struct gendisk *disk;
sector_t capacity; /* size in 512-byte sectors */
@@ -85,37 +84,31 @@
unsigned RCD : 1; /* state of disk RCD bit, unused */
};
-static LIST_HEAD(sd_devlist);
-static spinlock_t sd_devlist_lock = SPIN_LOCK_UNLOCKED;
-
static unsigned long sd_index_bits[SD_DISKS / BITS_PER_LONG];
static spinlock_t sd_index_lock = SPIN_LOCK_UNLOCKED;
static void sd_init_onedisk(struct scsi_disk * sdkp, struct gendisk *disk);
static void sd_rw_intr(struct scsi_cmnd * SCpnt);
-static int sd_attach(struct scsi_device *);
-static void sd_detach(struct scsi_device *);
-static void sd_rescan(struct scsi_device *);
+static int sd_probe(struct device *);
+static int sd_remove(struct device *);
+static void sd_shutdown(struct device *dev);
+static void sd_rescan(struct device *);
static int sd_init_command(struct scsi_cmnd *);
static int sd_synchronize_cache(struct scsi_disk *, int);
-static int sd_notifier(struct notifier_block *, unsigned long, void *);
static void sd_read_capacity(struct scsi_disk *sdkp, char *diskname,
struct scsi_request *SRpnt, unsigned char *buffer);
-static struct notifier_block sd_notifier_block = {sd_notifier, NULL, 0};
-static struct Scsi_Device_Template sd_template = {
- .module = THIS_MODULE,
- .list = LIST_HEAD_INIT(sd_template.list),
- .name = "disk",
- .scsi_type = TYPE_DISK,
- .attach = sd_attach,
- .detach = sd_detach,
- .rescan = sd_rescan,
- .init_command = sd_init_command,
- .scsi_driverfs_driver = {
- .name = "sd",
+static struct scsi_driver sd_template = {
+ .owner = THIS_MODULE,
+ .gendrv = {
+ .name = "sd",
+ .probe = sd_probe,
+ .remove = sd_remove,
+ .shutdown = sd_shutdown,
},
+ .rescan = sd_rescan,
+ .init_command = sd_init_command,
};
static int sd_major(int major_idx)
@@ -133,36 +126,6 @@
}
}
-static struct scsi_disk *sd_find_by_sdev(Scsi_Device *sd)
-{
- struct scsi_disk *sdkp;
-
- spin_lock(&sd_devlist_lock);
- list_for_each_entry(sdkp, &sd_devlist, list) {
- if (sdkp->device == sd) {
- spin_unlock(&sd_devlist_lock);
- return sdkp;
- }
- }
-
- spin_unlock(&sd_devlist_lock);
- return NULL;
-}
-
-static inline void sd_devlist_insert(struct scsi_disk *sdkp)
-{
- spin_lock(&sd_devlist_lock);
- list_add(&sdkp->list, &sd_devlist);
- spin_unlock(&sd_devlist_lock);
-}
-
-static inline void sd_devlist_remove(struct scsi_disk *sdkp)
-{
- spin_lock(&sd_devlist_lock);
- list_del(&sdkp->list);
- spin_unlock(&sd_devlist_lock);
-}
-
static inline struct scsi_disk *scsi_disk(struct gendisk *disk)
{
return container_of(disk->private_data, struct scsi_disk, driver);
@@ -635,12 +598,13 @@
return 1;
}
-static void sd_rescan(struct scsi_device * sdp)
+static void sd_rescan(struct device *dev)
{
- unsigned char *buffer;
- struct scsi_disk *sdkp = sd_find_by_sdev(sdp);
+ struct scsi_device *sdp = to_scsi_device(dev);
+ struct scsi_disk *sdkp = dev_get_drvdata(dev);
struct gendisk *gd;
struct scsi_request *SRpnt;
+ unsigned char *buffer;
if (!sdkp || sdp->online == FALSE || !sdkp->media_present)
return;
@@ -1288,10 +1252,10 @@
}
/**
- * sd_attach - called during driver initialization and whenever a
+ * sd_probe - called during driver initialization and whenever a
* new scsi device is attached to the system. It is called once
* for each scsi device (not just disks) present.
- * @sdp: pointer to mid level scsi device object
+ * @dev: pointer to device object
*
* Returns 0 if successful (or not interested in this scsi device
* (e.g. scanner)); 1 when there is an error.
@@ -1303,17 +1267,19 @@
* and minor number that is chosen here.
*
* Assume sd_attach is not re-entrant (for time being)
- * Also think about sd_attach() and sd_detach() running coincidentally.
+ * Also think about sd_attach() and sd_remove() running coincidentally.
**/
-static int sd_attach(struct scsi_device * sdp)
+static int sd_probe(struct device *dev)
{
+ struct scsi_device *sdp = to_scsi_device(dev);
struct scsi_disk *sdkp;
struct gendisk *gd;
u32 index;
int error;
+ error = -ENODEV;
if ((sdp->type != TYPE_DISK) && (sdp->type != TYPE_MOD))
- return 1;
+ goto out;
SCSI_LOG_HLQUEUE(3, printk("sd_attach: scsi device: <%d,%d,%d,%d>\n",
sdp->host->host_no, sdp->channel, sdp->id, sdp->lun));
@@ -1365,8 +1331,8 @@
gd->private_data = &sdkp->driver;
gd->queue = sdkp->device->request_queue;
- sd_devlist_insert(sdkp);
set_capacity(gd, sdkp->capacity);
+ dev_set_drvdata(dev, sdkp);
add_disk(gd);
printk(KERN_NOTICE "Attached scsi %sdisk %s at scsi%d, channel %d, "
@@ -1385,44 +1351,42 @@
}
/**
- * sd_detach - called whenever a scsi disk (previously recognized by
- * sd_attach) is detached from the system. It is called (potentially
+ * sd_remove - called whenever a scsi disk (previously recognized by
+ * sd_probe) is detached from the system. It is called (potentially
* multiple times) during sd module unload.
* @sdp: pointer to mid level scsi device object
*
* Note: this function is invoked from the scsi mid-level.
* This function potentially frees up a device name (e.g. /dev/sdc)
- * that could be re-used by a subsequent sd_attach().
+ * that could be re-used by a subsequent sd_probe().
* This function is not called when the built-in sd driver is "exit-ed".
**/
-static void sd_detach(struct scsi_device * sdp)
+static int sd_remove(struct device *dev)
{
- struct scsi_disk *sdkp;
-
- SCSI_LOG_HLQUEUE(3, printk("sd_detach: <%d,%d,%d,%d>\n",
- sdp->host->host_no, sdp->channel, sdp->id,
- sdp->lun));
-
- sdkp = sd_find_by_sdev(sdp);
- if (!sdkp)
- return;
+ struct scsi_disk *sdkp = dev_get_drvdata(dev);
- /* check that we actually have a write back cache to synchronize */
- if (sdkp->WCE) {
- printk(KERN_NOTICE "Synchronizing SCSI cache: ");
- sd_synchronize_cache(sdkp, 1);
- printk("\n");
- }
-
- sd_devlist_remove(sdkp);
del_gendisk(sdkp->disk);
spin_lock(&sd_index_lock);
clear_bit(sdkp->index, sd_index_bits);
spin_unlock(&sd_index_lock);
+ sd_shutdown(dev);
put_disk(sdkp->disk);
kfree(sdkp);
+
+ return 0;
+}
+
+static void sd_shutdown(struct device *dev)
+{
+ struct scsi_disk *sdkp = dev_get_drvdata(dev);
+
+ if (sdkp->WCE) {
+ printk(KERN_NOTICE "Synchronizing SCSI cache: ");
+ sd_synchronize_cache(sdkp, 1);
+ printk("\n");
+ }
}
/**
@@ -1433,7 +1397,7 @@
**/
static int __init init_sd(void)
{
- int majors = 0, rc = -ENODEV, i;
+ int majors = 0, i;
SCSI_LOG_HLQUEUE(3, printk("init_sd: sd driver entry point\n"));
@@ -1444,11 +1408,7 @@
if (!majors)
return -ENODEV;
- rc = scsi_register_device(&sd_template);
- if (rc)
- return rc;
- register_reboot_notifier(&sd_notifier_block);
- return rc;
+ return scsi_register_driver(&sd_template);
}
/**
@@ -1462,35 +1422,9 @@
SCSI_LOG_HLQUEUE(3, printk("exit_sd: exiting sd driver\n"));
- unregister_reboot_notifier(&sd_notifier_block);
- scsi_unregister_device(&sd_template);
+ scsi_unregister_driver(&sd_template);
for (i = 0; i < SD_MAJORS; i++)
unregister_blkdev(sd_major(i), "sd");
-}
-
-/*
- * XXX: this function does not take sd_devlist_lock to synchronize
- * access to sd_devlist. This should be safe as no other reboot
- * notifier can access it.
- */
-static int sd_notifier(struct notifier_block *n, unsigned long event, void *p)
-{
- if (event != SYS_RESTART &&
- event != SYS_HALT &&
- event != SYS_POWER_OFF)
- return NOTIFY_DONE;
-
- if (!list_empty(&sd_devlist)) {
- struct scsi_disk *sdkp;
-
- printk(KERN_NOTICE "Synchronizing SCSI caches: ");
- list_for_each_entry(sdkp, &sd_devlist, list)
- if (sdkp->WCE)
- sd_synchronize_cache(sdkp, 1);
- printk("\n");
- }
-
- return NOTIFY_OK;
}
/* send a SYNCHRONIZE CACHE instruction down to the device through the
===== drivers/scsi/sg.c 1.54 vs edited =====
--- 1.54/drivers/scsi/sg.c Wed May 7 16:15:40 2003
+++ edited/drivers/scsi/sg.c Fri May 16 17:34:40 2003
@@ -112,23 +112,20 @@
#define SG_DEV_ARR_LUMP 6 /* amount to over allocate sg_dev_arr by */
-static int sg_attach(Scsi_Device *);
-static void sg_detach(Scsi_Device *);
+static int sg_probe(struct device *);
+static int sg_remove(struct device *);
static Scsi_Request *dummy_cmdp; /* only used for sizeof */
static rwlock_t sg_dev_arr_lock = RW_LOCK_UNLOCKED; /* Also used to lock
file descriptor list for device */
-static struct Scsi_Device_Template sg_template = {
- .module = THIS_MODULE,
- .list = LIST_HEAD_INIT(sg_template.list),
- .name = "generic",
- .scsi_type = 0xff,
- .attach = sg_attach,
- .detach = sg_detach,
- .scsi_driverfs_driver = {
- .name = "sg",
+static struct scsi_driver sg_template = {
+ .owner = THIS_MODULE,
+ .gendrv = {
+ .name = "sg",
+ .probe = sg_probe,
+ .remove = sg_remove,
},
};
@@ -180,15 +177,14 @@
} Sg_fd;
typedef struct sg_device { /* holds the state of each scsi generic device */
- struct Scsi_Device_Template *driver;
- Scsi_Device *device;
+ struct scsi_driver *driver;
+ struct scsi_device *device;
wait_queue_head_t o_excl_wait; /* queue open() when O_EXCL in use */
int sg_tablesize; /* adapter's max scatter-gather table size */
Sg_fd *headfp; /* first open fd belonging to this device */
volatile char detached; /* 0->attached, 1->detached pending removal */
volatile char exclude; /* opened for exclusive access */
char sgdebug; /* 0->off, 1->sense, 9->dump dev, 10-> all devs */
- struct device sg_driverfs_dev;
struct gendisk *disk;
} Sg_device;
@@ -1332,7 +1328,7 @@
static ssize_t
sg_device_kdev_read(struct device *driverfs_dev, char *page)
{
- Sg_device *sdp = list_entry(driverfs_dev, Sg_device, sg_driverfs_dev);
+ Sg_device *sdp = dev_get_drvdata(driverfs_dev);
return sprintf(page, "%x\n", MKDEV(sdp->disk->major,
sdp->disk->first_minor));
}
@@ -1347,8 +1343,9 @@
static DEVICE_ATTR(type,S_IRUGO,sg_device_type_read,NULL);
static int
-sg_attach(Scsi_Device * scsidp)
+sg_probe(struct device *dev)
{
+ struct scsi_device *scsidp = to_scsi_device(dev);
struct gendisk *disk;
Sg_device *sdp = NULL;
unsigned long iflags;
@@ -1431,21 +1428,12 @@
sdp->detached = 0;
sdp->sg_tablesize = scsidp->host ? scsidp->host->sg_tablesize : 0;
- memset(&sdp->sg_driverfs_dev, 0, sizeof (struct device));
- snprintf(sdp->sg_driverfs_dev.bus_id, BUS_ID_SIZE, "%s:gen",
- scsidp->sdev_driverfs_dev.bus_id);
- snprintf(sdp->sg_driverfs_dev.name, DEVICE_NAME_SIZE, "%sgeneric",
- scsidp->sdev_driverfs_dev.name);
- sdp->sg_driverfs_dev.parent = &scsidp->sdev_driverfs_dev;
- sdp->sg_driverfs_dev.bus = scsidp->sdev_driverfs_dev.bus;
-
sg_nr_dev++;
sg_dev_arr[k] = sdp;
write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
- device_register(&sdp->sg_driverfs_dev);
- device_create_file(&sdp->sg_driverfs_dev, &dev_attr_type);
- device_create_file(&sdp->sg_driverfs_dev, &dev_attr_kdev);
+ device_create_file(&scsidp->sdev_driverfs_dev, &dev_attr_type);
+ device_create_file(&scsidp->sdev_driverfs_dev, &dev_attr_kdev);
sprintf(devfs_name, "%s/generic", scsidp->devfs_name);
devfs_register(NULL, devfs_name, 0,
@@ -1453,20 +1441,13 @@
S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP,
&sg_fops, sdp);
- switch (scsidp->type) {
- case TYPE_DISK:
- case TYPE_MOD:
- case TYPE_ROM:
- case TYPE_WORM:
- case TYPE_TAPE:
- break;
- default:
- printk(KERN_NOTICE
- "Attached scsi generic sg%d at scsi%d, channel"
- " %d, id %d, lun %d, type %d\n", k,
- scsidp->host->host_no, scsidp->channel, scsidp->id,
- scsidp->lun, scsidp->type);
- }
+ printk(KERN_NOTICE
+ "Attached scsi generic sg%d at scsi%d, channel"
+ " %d, id %d, lun %d, type %d\n", k,
+ scsidp->host->host_no, scsidp->channel, scsidp->id,
+ scsidp->lun, scsidp->type);
+
+ dev_set_drvdata(dev, sdp);
return 0;
out:
@@ -1474,9 +1455,10 @@
return error;
}
-static void
-sg_detach(Scsi_Device * scsidp)
+static int
+sg_remove(struct device *dev)
{
+ struct scsi_device *scsidp = to_scsi_device(dev);
Sg_device *sdp = NULL;
unsigned long iflags;
Sg_fd *sfp;
@@ -1486,7 +1468,7 @@
int k, delay;
if (NULL == sg_dev_arr)
- return;
+ return 0;
delay = 0;
write_lock_irqsave(&sg_dev_arr_lock, iflags);
for (k = 0; k < sg_dev_max; k++) {
@@ -1527,9 +1509,8 @@
if (sdp) {
devfs_remove("%s/generic", scsidp->devfs_name);
- device_remove_file(&sdp->sg_driverfs_dev, &dev_attr_type);
- device_remove_file(&sdp->sg_driverfs_dev, &dev_attr_kdev);
- device_unregister(&sdp->sg_driverfs_dev);
+ device_remove_file(&scsidp->sdev_driverfs_dev, &dev_attr_type);
+ device_remove_file(&scsidp->sdev_driverfs_dev, &dev_attr_kdev);
put_disk(sdp->disk);
sdp->disk = NULL;
if (NULL == sdp->headfp)
@@ -1538,6 +1519,8 @@
if (delay)
scsi_sleep(2); /* dirty detach so delay device destruction */
+
+ return 0;
}
/* Set 'perm' (4th argument) to 0 to disable module_param's definition
@@ -1595,7 +1578,7 @@
static void do_create_driverfs_files(void)
{
- struct device_driver * driverfs = &sg_template.scsi_driverfs_driver;
+ struct device_driver * driverfs = &sg_template.gendrv;
driver_create_file(driverfs, &driver_attr_allow_dio);
driver_create_file(driverfs, &driver_attr_def_reserved_size);
@@ -1604,7 +1587,7 @@
static void do_remove_driverfs_files(void)
{
- struct device_driver * driverfs = &sg_template.scsi_driverfs_driver;
+ struct device_driver * driverfs = &sg_template.gendrv;
driver_remove_file(driverfs, &driver_attr_version);
driver_remove_file(driverfs, &driver_attr_def_reserved_size);
@@ -1622,7 +1605,7 @@
rc = register_chrdev(SCSI_GENERIC_MAJOR, "sg", &sg_fops);
if (rc)
return rc;
- rc = scsi_register_device(&sg_template);
+ rc = scsi_register_driver(&sg_template);
if (rc)
return rc;
#ifdef CONFIG_PROC_FS
@@ -1639,7 +1622,7 @@
#ifdef CONFIG_PROC_FS
sg_proc_cleanup();
#endif /* CONFIG_PROC_FS */
- scsi_unregister_device(&sg_template);
+ scsi_unregister_driver(&sg_template);
unregister_chrdev(SCSI_GENERIC_MAJOR, "sg");
if (sg_dev_arr != NULL) {
vfree((char *) sg_dev_arr);
===== drivers/scsi/sr.c 1.78 vs edited =====
--- 1.78/drivers/scsi/sr.c Wed May 7 16:15:41 2003
+++ edited/drivers/scsi/sr.c Fri May 16 17:34:40 2003
@@ -67,26 +67,20 @@
CDC_PLAY_AUDIO|CDC_RESET|CDC_IOCTLS|CDC_DRIVE_STATUS| \
CDC_CD_R|CDC_CD_RW|CDC_DVD|CDC_DVD_R|CDC_GENERIC_PACKET)
-static int sr_attach(struct scsi_device *);
-static void sr_detach(struct scsi_device *);
+static int sr_probe(struct device *);
+static int sr_remove(struct device *);
static int sr_init_command(struct scsi_cmnd *);
-static struct Scsi_Device_Template sr_template = {
- .module = THIS_MODULE,
- .list = LIST_HEAD_INIT(sr_template.list),
- .name = "cdrom",
- .scsi_type = TYPE_ROM,
- .attach = sr_attach,
- .detach = sr_detach,
- .init_command = sr_init_command,
- .scsi_driverfs_driver = {
- .name = "sr",
+static struct scsi_driver sr_template = {
+ .owner = THIS_MODULE,
+ .gendrv = {
+ .name = "sr",
+ .probe = sr_probe,
+ .remove = sr_remove,
},
+ .init_command = sr_init_command,
};
-static LIST_HEAD(sr_devlist);
-static spinlock_t sr_devlist_lock = SPIN_LOCK_UNLOCKED;
-
static unsigned long sr_index_bits[SR_DISKS / BITS_PER_LONG];
static spinlock_t sr_index_lock = SPIN_LOCK_UNLOCKED;
@@ -99,37 +93,6 @@
static int sr_media_change(struct cdrom_device_info *, int);
static int sr_packet(struct cdrom_device_info *, struct cdrom_generic_command *);
-static Scsi_CD *sr_find_by_sdev(Scsi_Device *sd)
-{
- struct list_head *p;
- Scsi_CD *cd;
-
- spin_lock(&sr_devlist_lock);
- list_for_each(p, &sr_devlist) {
- cd = list_entry(p, Scsi_CD, list);
- if (cd->device == sd) {
- spin_unlock(&sr_devlist_lock);
- return cd;
- }
- }
- spin_unlock(&sr_devlist_lock);
- return NULL;
-}
-
-static inline void sr_devlist_insert(Scsi_CD *cd)
-{
- spin_lock(&sr_devlist_lock);
- list_add(&cd->list, &sr_devlist);
- spin_unlock(&sr_devlist_lock);
-}
-
-static inline void sr_devlist_remove(Scsi_CD *cd)
-{
- spin_lock(&sr_devlist_lock);
- list_del(&cd->list);
- spin_unlock(&sr_devlist_lock);
-}
-
static struct cdrom_device_ops sr_dops = {
.open = sr_open,
.release = sr_release,
@@ -506,14 +469,16 @@
scsi_device_put(cd->device);
}
-static int sr_attach(struct scsi_device *sdev)
+static int sr_probe(struct device *dev)
{
+ struct scsi_device *sdev = to_scsi_device(dev);
struct gendisk *disk;
struct scsi_cd *cd;
int minor, error;
+ error = -ENODEV;
if (sdev->type != TYPE_ROM && sdev->type != TYPE_WORM)
- return 1;
+ goto fail;
error = -ENOMEM;
cd = kmalloc(sizeof(*cd), GFP_KERNEL);
@@ -574,8 +539,8 @@
disk->private_data = &cd->driver;
disk->queue = sdev->request_queue;
+ dev_set_drvdata(dev, cd);
add_disk(disk);
- sr_devlist_insert(cd);
printk(KERN_DEBUG
"Attached scsi CD-ROM %s at scsi%d, channel %d, id %d, lun %d\n",
@@ -806,15 +771,10 @@
return cgc->stat;
}
-static void sr_detach(struct scsi_device * SDp)
+static int sr_remove(struct device *dev)
{
- struct scsi_cd *cd;
+ struct scsi_cd *cd = dev_get_drvdata(dev);
- cd = sr_find_by_sdev(SDp);
- if (!cd)
- return;
-
- sr_devlist_remove(cd);
del_gendisk(cd->disk);
spin_lock(&sr_index_lock);
@@ -824,6 +784,8 @@
put_disk(cd->disk);
unregister_cdrom(&cd->cdi);
kfree(cd);
+
+ return 0;
}
static int __init init_sr(void)
@@ -833,12 +795,12 @@
rc = register_blkdev(SCSI_CDROM_MAJOR, "sr");
if (rc)
return rc;
- return scsi_register_device(&sr_template);
+ return scsi_register_driver(&sr_template);
}
static void __exit exit_sr(void)
{
- scsi_unregister_device(&sr_template);
+ scsi_unregister_driver(&sr_template);
unregister_blkdev(SCSI_CDROM_MAJOR, "sr");
}
===== drivers/scsi/sr.h 1.9 vs edited =====
--- 1.9/drivers/scsi/sr.h Sun Nov 3 14:46:32 2002
+++ edited/drivers/scsi/sr.h Fri May 16 17:34:40 2003
@@ -25,8 +25,7 @@
#define IOCTL_TIMEOUT 30*HZ
typedef struct scsi_cd {
- struct Scsi_Device_Template *driver;
- struct list_head list;
+ struct scsi_driver *driver;
unsigned capacity; /* size in blocks */
Scsi_Device *device;
unsigned int vendor; /* vendor code, see sr_vendor.c */
===== drivers/scsi/st.c 1.61 vs edited =====
--- 1.61/drivers/scsi/st.c Wed May 7 16:15:41 2003
+++ edited/drivers/scsi/st.c Fri May 16 17:35:26 2003
@@ -170,22 +170,19 @@
unsigned long, size_t, int);
static int sgl_unmap_user_pages(struct scatterlist *, const unsigned int, int);
-static int st_attach(Scsi_Device *);
-static void st_detach(Scsi_Device *);
+static int st_probe(struct device *);
+static int st_remove(struct device *);
static void do_create_driverfs_files(void);
static void do_remove_driverfs_files(void);
-static struct Scsi_Device_Template st_template = {
- .module = THIS_MODULE,
- .list = LIST_HEAD_INIT(st_template.list),
- .name = "tape",
- .scsi_type = TYPE_TAPE,
- .attach = st_attach,
- .detach = st_detach,
- .scsi_driverfs_driver = {
- .name = "st",
+static struct scsi_driver st_template = {
+ .owner = THIS_MODULE,
+ .gendrv = {
+ .name = "st",
+ .probe = st_probe,
+ .remove = st_remove,
},
};
@@ -3704,8 +3701,9 @@
.release = st_release,
};
-static int st_attach(Scsi_Device * SDp)
+static int st_probe(struct device *dev)
{
+ struct scsi_device *SDp = to_scsi_device(dev);
struct gendisk *disk;
Scsi_Tape *tpnt;
ST_mode *STm;
@@ -3716,13 +3714,13 @@
u64 bounce_limit;
if (SDp->type != TYPE_TAPE)
- return 1;
+ return -ENODEV;
if ((stp = st_incompatible(SDp))) {
printk(KERN_INFO
"st: Found incompatible tape at scsi%d, channel %d, id %d, lun %d\n",
SDp->host->host_no, SDp->channel, SDp->id, SDp->lun);
printk(KERN_INFO "st: The suggested driver is %s.\n", stp);
- return 1;
+ return -ENODEV;
}
i = SDp->host->sg_tablesize;
@@ -3921,11 +3919,12 @@
out_buffer_free:
kfree(buffer);
out:
- return 1;
+ return -ENODEV;
};
-static void st_detach(Scsi_Device * SDp)
+static int st_remove(struct device *dev)
{
+ Scsi_Device *SDp = to_scsi_device(dev);
Scsi_Tape *tpnt;
int i, mode;
@@ -3960,12 +3959,12 @@
}
put_disk(tpnt->disk);
kfree(tpnt);
- return;
+ return 0;
}
}
write_unlock(&st_dev_arr_lock);
- return;
+ return 0;
}
static int __init init_st(void)
@@ -3977,7 +3976,7 @@
verstr, st_fixed_buffer_size, st_max_sg_segs);
if (register_chrdev(SCSI_TAPE_MAJOR, "st", &st_fops) >= 0) {
- if (scsi_register_device(&st_template) == 0) {
+ if (scsi_register_driver(&st_template) == 0) {
do_create_driverfs_files();
return 0;
}
@@ -3990,20 +3989,10 @@
static void __exit exit_st(void)
{
- int i;
-
do_remove_driverfs_files();
- scsi_unregister_device(&st_template);
+ scsi_unregister_driver(&st_template);
unregister_chrdev(SCSI_TAPE_MAJOR, "st");
- if (scsi_tapes != NULL) {
- for (i=0; i < st_dev_max; ++i)
- if (scsi_tapes[i]) {
- printk(KERN_WARNING "st: scsi_tapes[] not "
- "empty after scsi_unregister_device\n");
- st_detach(scsi_tapes[i]->device);
- }
- kfree(scsi_tapes);
- }
+ kfree(scsi_tapes);
printk(KERN_INFO "st: Unloaded.\n");
}
@@ -4038,7 +4027,7 @@
static void do_create_driverfs_files(void)
{
- struct device_driver *driverfs = &st_template.scsi_driverfs_driver;
+ struct device_driver *driverfs = &st_template.gendrv;
driver_create_file(driverfs, &driver_attr_try_direct_io);
driver_create_file(driverfs, &driver_attr_fixed_buffer_size);
@@ -4048,7 +4037,7 @@
static void do_remove_driverfs_files(void)
{
- struct device_driver *driverfs = &st_template.scsi_driverfs_driver;
+ struct device_driver *driverfs = &st_template.gendrv;
driver_remove_file(driverfs, &driver_attr_version);
driver_remove_file(driverfs, &driver_attr_max_sg_segs);
===== drivers/scsi/st.h 1.13 vs edited =====
--- 1.13/drivers/scsi/st.h Fri Apr 18 17:57:20 2003
+++ edited/drivers/scsi/st.h Fri May 16 17:34:37 2003
@@ -70,7 +70,7 @@
/* The tape drive descriptor */
typedef struct {
- struct Scsi_Device_Template *driver;
+ struct scsi_driver *driver;
Scsi_Device *device;
struct semaphore lock; /* For serialization */
struct completion wait; /* For SCSI commands */
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] driver model for scsi upper drivers, take 2
2003-05-27 7:32 [PATCH] driver model for scsi upper drivers, take 2 Christoph Hellwig
@ 2003-05-27 9:43 ` Christoph Hellwig
2003-05-29 9:23 ` Kai Makisara
[not found] ` <"from hch"@lst.de>
0 siblings, 2 replies; 4+ messages in thread
From: Christoph Hellwig @ 2003-05-27 9:43 UTC (permalink / raw)
To: James.Bottomley; +Cc: linux-scsi
On Tue, May 27, 2003 at 09:32:18AM +0200, Christoph Hellwig wrote:
> - removed the tape sysfs pseudodevice crap that caused hangs
> - switched sg to a class_interface. This means sg can be used
> on devices already claimed be an upper driver again. This
> also means I had to remove the sg sysfs attributes temporarily
> because the old mechanism is gone, but I'll restore them
> differently in a followon patch.
Yikes, this was the old patch again. Here's the right one:
--- 1.66/drivers/scsi/hosts.c Fri May 23 14:35:11 2003
+++ edited/drivers/scsi/hosts.c Mon May 26 11:29:03 2003
@@ -233,27 +233,18 @@
int scsi_add_host(struct Scsi_Host *shost, struct device *dev)
{
Scsi_Host_Template *sht = shost->hostt;
- struct scsi_device *sdev;
- int error = 0, saved_error = 0;
+ int error;
printk(KERN_INFO "scsi%d : %s\n", shost->host_no,
sht->info ? sht->info(shost) : sht->name);
error = scsi_sysfs_add_host(shost, dev);
- if (error)
- return error;
-
- scsi_proc_host_add(shost);
-
- scsi_scan_host(shost);
+ if (!error) {
+ scsi_proc_host_add(shost);
+ scsi_scan_host(shost);
+ };
- list_for_each_entry (sdev, &shost->my_devices, siblings) {
- error = scsi_attach_device(sdev);
- if (error)
- saved_error = error;
- }
-
- return saved_error;
+ return error;
}
/**
--- 1.66/drivers/scsi/hosts.h Mon May 26 23:47:09 2003
+++ edited/drivers/scsi/hosts.h Mon May 26 10:02:43 2003
@@ -542,25 +542,23 @@
return shost->host_gendev.parent;
}
-struct Scsi_Device_Template
-{
- struct list_head list;
- const char * name;
- struct module * module; /* Used for loadable modules */
- unsigned char scsi_type;
- int (*attach)(Scsi_Device *); /* Attach devices to arrays */
- void (*detach)(Scsi_Device *);
- int (*init_command)(Scsi_Cmnd *); /* Used by new queueing code.
- Selects command for blkdevs */
- void (*rescan)(Scsi_Device *);
- struct device_driver scsi_driverfs_driver;
+struct scsi_driver {
+ struct module *owner;
+ struct device_driver gendrv;
+
+ int (*init_command)(struct scsi_cmnd *);
+ void (*rescan)(struct device *);
};
+#define to_scsi_driver(drv) \
+ container_of((drv), struct scsi_driver, gendrv)
+
+extern int scsi_register_driver(struct device_driver *);
+#define scsi_unregister_driver(drv) \
+ driver_unregister(drv);
-/*
- * Highlevel driver registration/unregistration.
- */
-extern int scsi_register_device(struct Scsi_Device_Template *);
-extern int scsi_unregister_device(struct Scsi_Device_Template *);
+extern int scsi_register_interface(struct class_interface *);
+#define scsi_unregister_interface(intf) \
+ class_interface_unregister(intf)
/*
* HBA allocation/freeing.
--- 1.24/drivers/scsi/ide-scsi.c Thu May 15 04:55:52 2003
+++ edited/drivers/scsi/ide-scsi.c Mon May 26 10:12:22 2003
@@ -771,6 +771,10 @@
static inline int should_transform(ide_drive_t *drive, Scsi_Cmnd *cmd)
{
idescsi_scsi_t *scsi = drive_to_idescsi(drive);
+
+ /* this was a layering violation and we can't support it
+ anymore, sorry. */
+#if 0
struct gendisk *disk = cmd->request->rq_disk;
if (disk) {
@@ -778,6 +782,7 @@
if (strcmp((*p)->scsi_driverfs_driver.name, "sg") == 0)
return test_bit(IDESCSI_SG_TRANSFORM, &scsi->transform);
}
+#endif
return test_bit(IDESCSI_TRANSFORM, &scsi->transform);
}
--- 1.44/drivers/scsi/osst.c Tue May 13 05:52:55 2003
+++ edited/drivers/scsi/osst.c Mon May 26 11:17:35 2003
@@ -160,19 +160,15 @@
static int osst_copy_to_buffer(OSST_buffer *, unsigned char *);
static int osst_copy_from_buffer(OSST_buffer *, unsigned char *);
-static int osst_attach(Scsi_Device *);
-static void osst_detach(Scsi_Device *);
+static int osst_probe(struct device *);
+static int osst_remove(struct device *);
-struct Scsi_Device_Template osst_template =
-{
- .module = THIS_MODULE,
- .list = LIST_HEAD_INIT(osst_template.list),
- .name = "OnStream Tape",
- .scsi_type = TYPE_TAPE,
- .attach = osst_attach,
- .detach = osst_detach,
- .scsi_driverfs_driver = {
- .name = "osst",
+struct scsi_driver osst_template = {
+ .owner = THIS_MODULE,
+ .gendrv = {
+ .name = "osst",
+ .probe = osst_probe,
+ .remove = osst_remove,
}
};
@@ -5327,22 +5323,6 @@
#endif
-/* Driverfs file support */
-static ssize_t osst_device_kdev_read(struct device *driverfs_dev, char *page)
-{
- kdev_t kdev;
- kdev.value=(int)(long)driverfs_dev->driver_data;
- return sprintf(page, "%x\n",kdev.value);
-}
-static DEVICE_ATTR(kdev,S_IRUGO,osst_device_kdev_read,NULL);
-
-static ssize_t osst_device_type_read(struct device *driverfs_dev, char *page)
-{
- return sprintf (page, "CHR\n");
-}
-static DEVICE_ATTR(type,S_IRUGO,osst_device_type_read,NULL);
-
-
static struct file_operations osst_fops = {
.owner = THIS_MODULE,
.read = osst_read,
@@ -5385,8 +5365,9 @@
* osst startup / cleanup code
*/
-static int osst_attach(Scsi_Device * SDp)
+static int osst_probe(struct device *dev)
{
+ Scsi_Device * SDp = to_scsi_device(dev);
OS_Scsi_Tape * tpnt;
ST_mode * STm;
ST_partstat * STps;
@@ -5395,12 +5376,12 @@
int i, mode, dev_num;
if (SDp->type != TYPE_TAPE || !osst_supports(SDp))
- return 1;
+ return -ENODEV;
drive = alloc_disk(1);
if (!drive) {
printk(KERN_ERR "osst :E: Out of memory. Device not attached.\n");
- return 1;
+ return -ENODEV;
}
/* if this is the first attach, build the infrastructure */
@@ -5522,45 +5503,12 @@
write_unlock(&os_scsi_tapes_lock);
for (mode = 0; mode < ST_NBR_MODES; ++mode) {
- char name[8];
-
/* Rewind entry */
- sprintf(name, "ot%s", osst_formats[mode]);
-
- sprintf(tpnt->driverfs_dev_r[mode].bus_id, "%s:%s",
- SDp->sdev_driverfs_dev.bus_id, name);
- sprintf(tpnt->driverfs_dev_r[mode].name, "%s%s",
- SDp->sdev_driverfs_dev.name, name);
- tpnt->driverfs_dev_r[mode].parent = &SDp->sdev_driverfs_dev;
- tpnt->driverfs_dev_r[mode].bus = SDp->sdev_driverfs_dev.bus;
- tpnt->driverfs_dev_r[mode].driver_data =
- (void *)(long)__mkdev(OSST_MAJOR, dev_num + (mode << 5));
- device_register(&tpnt->driverfs_dev_r[mode]);
- device_create_file(&tpnt->driverfs_dev_r[mode],
- &dev_attr_type);
- device_create_file(&tpnt->driverfs_dev_r[mode], &dev_attr_kdev);
-
devfs_mk_cdev(MKDEV(OSST_MAJOR, dev_num + (mode << 5)),
S_IFCHR | S_IRUGO | S_IWUGO,
"%s/ot%s", SDp->devfs_name, osst_formats[mode]);
/* No-rewind entry */
- sprintf (name, "ot%sn", osst_formats[mode]);
-
- sprintf(tpnt->driverfs_dev_n[mode].bus_id, "%s:%s",
- SDp->sdev_driverfs_dev.bus_id, name);
- sprintf(tpnt->driverfs_dev_n[mode].name, "%s%s",
- SDp->sdev_driverfs_dev.name, name);
- tpnt->driverfs_dev_n[mode].parent= &SDp->sdev_driverfs_dev;
- tpnt->driverfs_dev_n[mode].bus = SDp->sdev_driverfs_dev.bus;
- tpnt->driverfs_dev_n[mode].driver_data =
- (void *)(long)__mkdev(OSST_MAJOR, dev_num + (mode << 5) + 128);
- device_register(&tpnt->driverfs_dev_n[mode]);
- device_create_file(&tpnt->driverfs_dev_n[mode],
- &dev_attr_type);
- device_create_file(&tpnt->driverfs_dev_n[mode],
- &dev_attr_kdev);
-
devfs_mk_cdev(MKDEV(OSST_MAJOR, dev_num + (mode << 5) + 128),
S_IFCHR | S_IRUGO | S_IWUGO,
"%s/ot%sn", SDp->devfs_name, osst_formats[mode]);
@@ -5575,16 +5523,17 @@
out_put_disk:
put_disk(drive);
- return 1;
+ return -ENODEV;
};
-static void osst_detach(Scsi_Device * SDp)
+static int osst_remove(struct device *dev)
{
+ Scsi_Device * SDp = to_scsi_device(dev);
OS_Scsi_Tape * tpnt;
int i, mode;
if ((SDp->type != TYPE_TAPE) || (osst_nr_dev <= 0))
- return;
+ return 0;
write_lock(&os_scsi_tapes_lock);
for(i=0; i < osst_max_dev; i++) {
@@ -5599,29 +5548,17 @@
os_scsi_tapes[i] = NULL;
osst_nr_dev--;
write_unlock(&os_scsi_tapes_lock);
- for (mode = 0; mode < ST_NBR_MODES; ++mode) {
- device_remove_file(&tpnt->driverfs_dev_r[mode],
- &dev_attr_type);
- device_remove_file(&tpnt->driverfs_dev_r[mode],
- &dev_attr_kdev);
- device_unregister(&tpnt->driverfs_dev_r[mode]);
- device_remove_file(&tpnt->driverfs_dev_n[mode],
- &dev_attr_type);
- device_remove_file(&tpnt->driverfs_dev_n[mode],
- &dev_attr_kdev);
- device_unregister(&tpnt->driverfs_dev_n[mode]);
- }
if (tpnt->header_cache != NULL) vfree(tpnt->header_cache);
if (tpnt->buffer) {
normalize_buffer(tpnt->buffer);
kfree(tpnt->buffer);
}
kfree(tpnt);
- return;
+ return 0;
}
}
write_unlock(&os_scsi_tapes_lock);
- return;
+ return 0;
}
static int __init init_osst(void)
@@ -5630,7 +5567,7 @@
validate_options();
- if ((register_chrdev(OSST_MAJOR,"osst", &osst_fops) < 0) || scsi_register_device(&osst_template)) {
+ if ((register_chrdev(OSST_MAJOR,"osst", &osst_fops) < 0) || scsi_register_driver(&osst_template.gendrv)) {
printk(KERN_ERR "osst :E: Unable to register major %d for OnStream tapes\n", OSST_MAJOR);
return 1;
}
@@ -5643,7 +5580,7 @@
int i;
OS_Scsi_Tape * STp;
- scsi_unregister_device(&osst_template);
+ scsi_unregister_driver(&osst_template.gendrv);
unregister_chrdev(OSST_MAJOR, "osst");
if (os_scsi_tapes) {
--- 1.9/drivers/scsi/osst.h Fri Apr 18 17:57:20 2003
+++ edited/drivers/scsi/osst.h Mon May 26 11:17:39 2003
@@ -530,7 +530,7 @@
/* The OnStream tape drive descriptor */
typedef struct {
- struct Scsi_Device_Template *driver;
+ struct scsi_driver *driver;
unsigned capacity;
Scsi_Device* device;
struct semaphore lock; /* for serialization */
@@ -555,8 +555,6 @@
/* Mode characteristics */
ST_mode modes[ST_NBR_MODES];
int current_mode;
- struct device driverfs_dev_r[ST_NBR_MODES];
- struct device driverfs_dev_n[ST_NBR_MODES];
/* Status variables */
int partition;
--- 1.112/drivers/scsi/scsi.c Thu May 8 20:31:08 2003
+++ edited/drivers/scsi/scsi.c Mon May 26 09:50:43 2003
@@ -86,12 +86,6 @@
static unsigned long serial_number;
/*
- * List of all highlevel drivers.
- */
-LIST_HEAD(scsi_devicelist);
-static DECLARE_RWSEM(scsi_devicelist_mutex);
-
-/*
* Note - the initial logging level can be set here to log events at boot time.
* After the system is up, you may enable logging via the /proc interface.
*/
@@ -931,50 +925,6 @@
return depth;
}
-int scsi_attach_device(struct scsi_device *sdev)
-{
- struct Scsi_Device_Template *sdt;
-
- down_read(&scsi_devicelist_mutex);
- list_for_each_entry(sdt, &scsi_devicelist, list) {
- if (!try_module_get(sdt->module))
- continue;
- (*sdt->attach)(sdev);
- module_put(sdt->module);
- }
- up_read(&scsi_devicelist_mutex);
- return 0;
-}
-
-void scsi_detach_device(struct scsi_device *sdev)
-{
- struct Scsi_Device_Template *sdt;
-
- down_read(&scsi_devicelist_mutex);
- list_for_each_entry(sdt, &scsi_devicelist, list) {
- if (!try_module_get(sdt->module))
- continue;
- (*sdt->detach)(sdev);
- module_put(sdt->module);
- }
- up_read(&scsi_devicelist_mutex);
-}
-
-void scsi_rescan_device(struct scsi_device *sdev)
-{
- struct Scsi_Device_Template *sdt;
-
- down_read(&scsi_devicelist_mutex);
- list_for_each_entry(sdt, &scsi_devicelist, list) {
- if (!try_module_get(sdt->module))
- continue;
- if (*sdt->rescan)
- (*sdt->rescan)(sdev);
- module_put(sdt->module);
- }
- up_read(&scsi_devicelist_mutex);
-}
-
int scsi_device_get(struct scsi_device *sdev)
{
if (!try_module_get(sdev->host->hostt->module))
@@ -1028,71 +978,6 @@
} else {
/* FIXME: Send online state change hotplug event */
}
-}
-
-/*
- * This entry point is called from the upper level module's module_init()
- * routine. That implies that when this function is called, the
- * scsi_mod module is locked down because of upper module layering and
- * that the high level driver module is locked down by being in it's
- * init routine. So, the *only* thing we have to do to protect adds
- * we perform in this function is to make sure that all call's
- * to the high level driver's attach() and detach() call in points, other
- * than via scsi_register_device and scsi_unregister_device which are in
- * the module_init and module_exit code respectively and therefore already
- * locked down by the kernel module loader, are wrapped by try_module_get()
- * and module_put() to avoid races on device adds and removes.
- */
-int scsi_register_device(struct Scsi_Device_Template *tpnt)
-{
- struct scsi_device *sdev;
- struct Scsi_Host *shpnt;
-
-#ifdef CONFIG_KMOD
- if (scsi_host_get_next(NULL) == NULL)
- request_module("scsi_hostadapter");
-#endif
-
- if (!list_empty(&tpnt->list))
- return 1;
-
- down_write(&scsi_devicelist_mutex);
- list_add_tail(&tpnt->list, &scsi_devicelist);
- up_write(&scsi_devicelist_mutex);
-
- scsi_upper_driver_register(tpnt);
-
- for (shpnt = scsi_host_get_next(NULL); shpnt;
- shpnt = scsi_host_get_next(shpnt))
- list_for_each_entry(sdev, &shpnt->my_devices, siblings)
- (*tpnt->attach)(sdev);
-
- return 0;
-}
-
-int scsi_unregister_device(struct Scsi_Device_Template *tpnt)
-{
- struct scsi_device *sdev;
- struct Scsi_Host *shpnt;
-
- /*
- * Next, detach the devices from the driver.
- */
- for (shpnt = scsi_host_get_next(NULL); shpnt;
- shpnt = scsi_host_get_next(shpnt)) {
- list_for_each_entry(sdev, &shpnt->my_devices, siblings)
- (*tpnt->detach)(sdev);
- }
-
- /*
- * Extract the template from the linked list.
- */
- down_write(&scsi_devicelist_mutex);
- list_del(&tpnt->list);
- up_write(&scsi_devicelist_mutex);
-
- scsi_upper_driver_unregister(tpnt);
- return 0;
}
MODULE_DESCRIPTION("SCSI core");
--- 1.82/drivers/scsi/scsi.h Mon May 26 23:53:23 2003
+++ edited/drivers/scsi/scsi.h Mon May 26 09:50:43 2003
@@ -316,6 +316,7 @@
*/
struct scsi_device {
+ struct class_device sdev_classdev;
/*
* This information is private to the scsi mid-layer.
*/
--- 1.91/drivers/scsi/scsi_lib.c Fri May 23 12:02:30 2003
+++ edited/drivers/scsi/scsi_lib.c Mon May 26 09:50:43 2003
@@ -613,29 +613,6 @@
}
/*
- * Function: scsi_get_request_dev()
- *
- * Purpose: Find the upper-level driver that is responsible for this
- * request
- *
- * Arguments: request - I/O request we are preparing to queue.
- *
- * Lock status: No locks assumed to be held, but as it happens the
- * q->queue_lock is held when this is called.
- *
- * Returns: Nothing
- *
- * Notes: The requests in the request queue may have originated
- * from any block device driver. We need to find out which
- * one so that we can later form the appropriate command.
- */
-static struct Scsi_Device_Template *scsi_get_request_dev(struct request *req)
-{
- struct gendisk *p = req->rq_disk;
- return p ? *(struct Scsi_Device_Template **)p->private_data : NULL;
-}
-
-/*
* Function: scsi_io_completion()
*
* Purpose: Completion processing for block device I/O requests.
@@ -849,11 +826,7 @@
return;
}
if (result) {
- struct Scsi_Device_Template *sdt;
-
- sdt = scsi_get_request_dev(cmd->request);
- printk("SCSI %s error : <%d %d %d %d> return code = 0x%x\n",
- (sdt ? sdt->name : "device"),
+ printk("SCSI error : <%d %d %d %d> return code = 0x%x\n",
cmd->device->host->host_no,
cmd->device->channel,
cmd->device->id,
@@ -947,7 +920,6 @@
static int scsi_prep_fn(struct request_queue *q, struct request *req)
{
- struct Scsi_Device_Template *sdt;
struct scsi_device *sdev = q->queuedata;
struct scsi_cmnd *cmd;
@@ -1003,6 +975,7 @@
* happening now.
*/
if (req->flags & (REQ_CMD | REQ_BLOCK_PC)) {
+ struct scsi_driver *drv;
int ret;
/*
@@ -1017,8 +990,6 @@
* some kinds of consistency checking may cause the
* request to be rejected immediately.
*/
- sdt = scsi_get_request_dev(req);
- BUG_ON(!sdt);
/*
* This sets up the scatter-gather table (allocating if
@@ -1031,7 +1002,8 @@
/*
* Initialize the actual SCSI command for this request.
*/
- if (unlikely(!sdt->init_command(cmd))) {
+ drv = *(struct scsi_driver **)req->rq_disk->private_data;
+ if (unlikely(!drv->init_command(cmd))) {
scsi_release_buffers(cmd);
scsi_put_command(cmd);
return BLKPREP_KILL;
--- 1.8/drivers/scsi/scsi_priv.h Fri May 23 14:35:11 2003
+++ edited/drivers/scsi/scsi_priv.h Mon May 26 09:50:43 2003
@@ -41,9 +41,6 @@
#define SCSI_SENSE_VALID(scmd) \
(((scmd)->sense_buffer[0] & 0x70) == 0x70)
-struct Scsi_Device_Template;
-
-
/*
* scsi_target: representation of a scsi target, for now, this is only
* used for single_lun devices. If no one has active IO to the target,
@@ -70,9 +67,6 @@
extern void scsi_done(struct scsi_cmnd *cmd);
extern void scsi_finish_command(struct scsi_cmnd *cmd);
extern int scsi_retry_command(struct scsi_cmnd *cmd);
-extern int scsi_attach_device(struct scsi_device *sdev);
-extern void scsi_detach_device(struct scsi_device *sdev);
-extern void scsi_rescan_device(struct scsi_device *sdev);
extern int scsi_insert_special_req(struct scsi_request *sreq, int);
extern void scsi_init_cmd_from_req(struct scsi_cmnd *cmd,
struct scsi_request *sreq);
@@ -119,12 +113,11 @@
extern void scsi_free_sdev(struct scsi_device *);
extern void scsi_free_shost(struct Scsi_Host *);
extern void scsi_host_get(struct Scsi_Host *);
+extern void scsi_rescan_device(struct device *dev);
/* scsi_sysfs.c */
extern int scsi_device_register(struct scsi_device *);
extern void scsi_device_unregister(struct scsi_device *);
-extern int scsi_upper_driver_register(struct Scsi_Device_Template *);
-extern void scsi_upper_driver_unregister(struct Scsi_Device_Template *);
extern void scsi_sysfs_init_host(struct Scsi_Host *);
extern int scsi_sysfs_add_host(struct Scsi_Host *, struct device *);
extern void scsi_sysfs_remove_host(struct Scsi_Host *);
--- 1.86/drivers/scsi/scsi_scan.c Fri May 23 13:01:50 2003
+++ edited/drivers/scsi/scsi_scan.c Mon May 26 09:50:43 2003
@@ -1098,22 +1098,29 @@
uint channel, uint id, uint lun)
{
struct scsi_device *sdev;
- int error = -ENODEV, res;
+ int res;
res = scsi_probe_and_add_lun(shost, channel, id, lun, NULL, &sdev);
- if (res == SCSI_SCAN_LUN_PRESENT)
- error = scsi_attach_device(sdev);
-
- if (error)
- sdev = ERR_PTR(error);
+ if (res != SCSI_SCAN_LUN_PRESENT)
+ sdev = ERR_PTR(-ENODEV);
return sdev;
}
int scsi_remove_device(struct scsi_device *sdev)
{
- scsi_detach_device(sdev);
scsi_device_unregister(sdev);
return 0;
+}
+
+void scsi_rescan_device(struct device *dev)
+{
+ struct scsi_driver *drv = to_scsi_driver(dev->driver);
+
+ if (try_module_get(drv->owner)) {
+ if (drv->rescan)
+ drv->rescan(dev);
+ module_put(drv->owner);
+ }
}
/**
--- 1.37/drivers/scsi/scsi_syms.c Mon May 12 16:26:15 2003
+++ edited/drivers/scsi/scsi_syms.c Mon May 26 10:03:34 2003
@@ -29,8 +29,8 @@
* This source file contains the symbol table used by scsi loadable
* modules.
*/
-EXPORT_SYMBOL(scsi_register_device);
-EXPORT_SYMBOL(scsi_unregister_device);
+EXPORT_SYMBOL(scsi_register_driver);
+EXPORT_SYMBOL(scsi_register_interface);
EXPORT_SYMBOL(scsi_register_host);
EXPORT_SYMBOL(scsi_unregister_host);
EXPORT_SYMBOL(scsi_add_host);
--- 1.18/drivers/scsi/scsi_sysfs.c Mon May 26 23:47:09 2003
+++ edited/drivers/scsi/scsi_sysfs.c Mon May 26 11:36:00 2003
@@ -58,32 +58,16 @@
.name = "scsi_host",
};
-/**
- * scsi_bus_match:
- * @dev:
- * @dev_driver:
- *
- * Return value:
- **/
-static int scsi_bus_match(struct device *dev,
- struct device_driver *dev_driver)
+static struct class sdev_class = {
+ .name = "scsi_device",
+};
+
+/* all probing is done in the individual ->probe routines */
+static int scsi_bus_match(struct device *dev, struct device_driver *gendrv)
{
- if (!strcmp("sg", dev_driver->name)) {
- if (strstr(dev->bus_id, ":gen"))
- return 1;
- } else if (!strcmp("st",dev_driver->name)) {
- if (strstr(dev->bus_id,":mt"))
- return 1;
- } else if (!strcmp("sd", dev_driver->name)) {
- if ((!strstr(dev->bus_id, ":gen")) &&
- (!strstr(dev->bus_id, ":mt"))) {
- return 1;
- }
- }
- return 0;
+ return 1;
}
-
static struct bus_type scsi_bus_type = {
.name = "scsi",
.match = scsi_bus_match,
@@ -99,45 +83,26 @@
return error;
error = class_register(&shost_class);
if (error)
- return error;
+ goto bus_unregister;
+ error = class_register(&sdev_class);
+ if (error)
+ goto class_unregister;
+ return 0;
+ class_unregister:
+ class_unregister(&shost_class);
+ bus_unregister:
+ bus_unregister(&scsi_bus_type);
return error;
}
void scsi_sysfs_unregister(void)
{
+ class_unregister(&sdev_class);
class_unregister(&shost_class);
bus_unregister(&scsi_bus_type);
}
-/**
- * scsi_upper_driver_register - register upper level driver.
- * @sdev_tp: Upper level driver to register with the scsi bus.
- *
- * Return value:
- * 0 on Success / non-zero on Failure
- **/
-int scsi_upper_driver_register(struct Scsi_Device_Template *sdev_tp)
-{
- int error = 0;
-
- sdev_tp->scsi_driverfs_driver.bus = &scsi_bus_type;
- error = driver_register(&sdev_tp->scsi_driverfs_driver);
-
- return error;
-}
-
-/**
- * scsi_upper_driver_unregister - unregister upper level driver
- * @sdev_tp: Upper level driver to unregister with the scsi bus.
- *
- **/
-void scsi_upper_driver_unregister(struct Scsi_Device_Template *sdev_tp)
-{
- driver_unregister(&sdev_tp->scsi_driverfs_driver);
-}
-
-
/*
* sdev_show_function: macro to create an attr function that can be used to
* show a non-bit field.
@@ -238,7 +203,7 @@
static ssize_t
store_rescan_field (struct device *dev, const char *buf, size_t count)
{
- scsi_rescan_device(to_scsi_device(dev));
+ scsi_rescan_device(dev);
return 0;
}
@@ -280,15 +245,30 @@
{
int error = 0, i;
+ device_initialize(&sdev->sdev_driverfs_dev);
sprintf(sdev->sdev_driverfs_dev.bus_id,"%d:%d:%d:%d",
sdev->host->host_no, sdev->channel, sdev->id, sdev->lun);
sdev->sdev_driverfs_dev.parent = &sdev->host->host_gendev;
sdev->sdev_driverfs_dev.bus = &scsi_bus_type;
sdev->sdev_driverfs_dev.release = scsi_device_release;
- error = device_register(&sdev->sdev_driverfs_dev);
- if (error)
+ class_device_initialize(&sdev->sdev_classdev);
+ sdev->sdev_classdev.dev = &sdev->sdev_driverfs_dev;
+ sdev->sdev_classdev.class = &sdev_class;
+ snprintf(sdev->sdev_classdev.class_id, BUS_ID_SIZE, "%d:%d:%d:%d",
+ sdev->host->host_no, sdev->channel, sdev->id, sdev->lun);
+
+ error = device_add(&sdev->sdev_driverfs_dev);
+ if (error) {
+ printk(KERN_INFO "error 1\n");
return error;
+ }
+ error = class_device_add(&sdev->sdev_classdev);
+ if (error) {
+ printk(KERN_INFO "error 2\n");
+ device_unregister(&sdev->sdev_driverfs_dev);
+ return error;
+ }
for (i = 0; !error && sdev->host->hostt->sdev_attrs[i] != NULL; i++)
error = device_create_file(&sdev->sdev_driverfs_dev,
@@ -310,9 +290,24 @@
for (i = 0; sdev->host->hostt->sdev_attrs[i] != NULL; i++)
device_remove_file(&sdev->sdev_driverfs_dev, sdev->host->hostt->sdev_attrs[i]);
+ class_device_unregister(&sdev->sdev_classdev);
device_unregister(&sdev->sdev_driverfs_dev);
}
+int scsi_register_driver(struct device_driver *drv)
+{
+ drv->bus = &scsi_bus_type;
+
+ return driver_register(drv);
+}
+
+int scsi_register_interface(struct class_interface *intf)
+{
+ intf->class = &sdev_class;
+
+ return class_interface_register(intf);
+}
+
static void scsi_host_release(struct device *dev)
{
struct Scsi_Host *shost;
@@ -350,7 +345,7 @@
int i, error;
if (!shost->host_gendev.parent)
- shost->host_gendev.parent = (dev) ? dev : &legacy_bus;
+ shost->host_gendev.parent = dev ? dev : &legacy_bus;
error = device_add(&shost->host_gendev);
if (error)
--- 1.116/drivers/scsi/sd.c Fri May 23 13:01:50 2003
+++ edited/drivers/scsi/sd.c Mon May 26 11:28:14 2003
@@ -73,8 +73,7 @@
#define SD_MAX_RETRIES 5
struct scsi_disk {
- struct list_head list; /* list of all scsi_disks */
- struct Scsi_Device_Template *driver; /* always &sd_template */
+ struct scsi_driver *driver; /* always &sd_template */
struct scsi_device *device;
struct gendisk *disk;
sector_t capacity; /* size in 512-byte sectors */
@@ -85,37 +84,31 @@
unsigned RCD : 1; /* state of disk RCD bit, unused */
};
-static LIST_HEAD(sd_devlist);
-static spinlock_t sd_devlist_lock = SPIN_LOCK_UNLOCKED;
-
static unsigned long sd_index_bits[SD_DISKS / BITS_PER_LONG];
static spinlock_t sd_index_lock = SPIN_LOCK_UNLOCKED;
static void sd_init_onedisk(struct scsi_disk * sdkp, struct gendisk *disk);
static void sd_rw_intr(struct scsi_cmnd * SCpnt);
-static int sd_attach(struct scsi_device *);
-static void sd_detach(struct scsi_device *);
-static void sd_rescan(struct scsi_device *);
+static int sd_probe(struct device *);
+static int sd_remove(struct device *);
+static void sd_shutdown(struct device *dev);
+static void sd_rescan(struct device *);
static int sd_init_command(struct scsi_cmnd *);
static int sd_synchronize_cache(struct scsi_disk *, int);
-static int sd_notifier(struct notifier_block *, unsigned long, void *);
static void sd_read_capacity(struct scsi_disk *sdkp, char *diskname,
struct scsi_request *SRpnt, unsigned char *buffer);
-static struct notifier_block sd_notifier_block = {sd_notifier, NULL, 0};
-static struct Scsi_Device_Template sd_template = {
- .module = THIS_MODULE,
- .list = LIST_HEAD_INIT(sd_template.list),
- .name = "disk",
- .scsi_type = TYPE_DISK,
- .attach = sd_attach,
- .detach = sd_detach,
- .rescan = sd_rescan,
- .init_command = sd_init_command,
- .scsi_driverfs_driver = {
- .name = "sd",
+static struct scsi_driver sd_template = {
+ .owner = THIS_MODULE,
+ .gendrv = {
+ .name = "sd",
+ .probe = sd_probe,
+ .remove = sd_remove,
+ .shutdown = sd_shutdown,
},
+ .rescan = sd_rescan,
+ .init_command = sd_init_command,
};
static int sd_major(int major_idx)
@@ -133,36 +126,6 @@
}
}
-static struct scsi_disk *sd_find_by_sdev(Scsi_Device *sd)
-{
- struct scsi_disk *sdkp;
-
- spin_lock(&sd_devlist_lock);
- list_for_each_entry(sdkp, &sd_devlist, list) {
- if (sdkp->device == sd) {
- spin_unlock(&sd_devlist_lock);
- return sdkp;
- }
- }
-
- spin_unlock(&sd_devlist_lock);
- return NULL;
-}
-
-static inline void sd_devlist_insert(struct scsi_disk *sdkp)
-{
- spin_lock(&sd_devlist_lock);
- list_add(&sdkp->list, &sd_devlist);
- spin_unlock(&sd_devlist_lock);
-}
-
-static inline void sd_devlist_remove(struct scsi_disk *sdkp)
-{
- spin_lock(&sd_devlist_lock);
- list_del(&sdkp->list);
- spin_unlock(&sd_devlist_lock);
-}
-
static inline struct scsi_disk *scsi_disk(struct gendisk *disk)
{
return container_of(disk->private_data, struct scsi_disk, driver);
@@ -636,12 +599,13 @@
return 1;
}
-static void sd_rescan(struct scsi_device * sdp)
+static void sd_rescan(struct device *dev)
{
- unsigned char *buffer;
- struct scsi_disk *sdkp = sd_find_by_sdev(sdp);
+ struct scsi_device *sdp = to_scsi_device(dev);
+ struct scsi_disk *sdkp = dev_get_drvdata(dev);
struct gendisk *gd;
struct scsi_request *SRpnt;
+ unsigned char *buffer;
if (!sdkp || sdp->online == FALSE || !sdkp->media_present)
return;
@@ -1312,10 +1276,10 @@
}
/**
- * sd_attach - called during driver initialization and whenever a
+ * sd_probe - called during driver initialization and whenever a
* new scsi device is attached to the system. It is called once
* for each scsi device (not just disks) present.
- * @sdp: pointer to mid level scsi device object
+ * @dev: pointer to device object
*
* Returns 0 if successful (or not interested in this scsi device
* (e.g. scanner)); 1 when there is an error.
@@ -1327,17 +1291,19 @@
* and minor number that is chosen here.
*
* Assume sd_attach is not re-entrant (for time being)
- * Also think about sd_attach() and sd_detach() running coincidentally.
+ * Also think about sd_attach() and sd_remove() running coincidentally.
**/
-static int sd_attach(struct scsi_device * sdp)
+static int sd_probe(struct device *dev)
{
+ struct scsi_device *sdp = to_scsi_device(dev);
struct scsi_disk *sdkp;
struct gendisk *gd;
u32 index;
int error;
+ error = -ENODEV;
if ((sdp->type != TYPE_DISK) && (sdp->type != TYPE_MOD))
- return 1;
+ goto out;
SCSI_LOG_HLQUEUE(3, printk("sd_attach: scsi device: <%d,%d,%d,%d>\n",
sdp->host->host_no, sdp->channel, sdp->id, sdp->lun));
@@ -1389,8 +1355,8 @@
gd->private_data = &sdkp->driver;
gd->queue = sdkp->device->request_queue;
- sd_devlist_insert(sdkp);
set_capacity(gd, sdkp->capacity);
+ dev_set_drvdata(dev, sdkp);
add_disk(gd);
printk(KERN_NOTICE "Attached scsi %sdisk %s at scsi%d, channel %d, "
@@ -1409,44 +1375,42 @@
}
/**
- * sd_detach - called whenever a scsi disk (previously recognized by
- * sd_attach) is detached from the system. It is called (potentially
+ * sd_remove - called whenever a scsi disk (previously recognized by
+ * sd_probe) is detached from the system. It is called (potentially
* multiple times) during sd module unload.
* @sdp: pointer to mid level scsi device object
*
* Note: this function is invoked from the scsi mid-level.
* This function potentially frees up a device name (e.g. /dev/sdc)
- * that could be re-used by a subsequent sd_attach().
+ * that could be re-used by a subsequent sd_probe().
* This function is not called when the built-in sd driver is "exit-ed".
**/
-static void sd_detach(struct scsi_device * sdp)
+static int sd_remove(struct device *dev)
{
- struct scsi_disk *sdkp;
-
- SCSI_LOG_HLQUEUE(3, printk("sd_detach: <%d,%d,%d,%d>\n",
- sdp->host->host_no, sdp->channel, sdp->id,
- sdp->lun));
-
- sdkp = sd_find_by_sdev(sdp);
- if (!sdkp)
- return;
+ struct scsi_disk *sdkp = dev_get_drvdata(dev);
- /* check that we actually have a write back cache to synchronize */
- if (sdkp->WCE) {
- printk(KERN_NOTICE "Synchronizing SCSI cache: ");
- sd_synchronize_cache(sdkp, 1);
- printk("\n");
- }
-
- sd_devlist_remove(sdkp);
del_gendisk(sdkp->disk);
spin_lock(&sd_index_lock);
clear_bit(sdkp->index, sd_index_bits);
spin_unlock(&sd_index_lock);
+ sd_shutdown(dev);
put_disk(sdkp->disk);
kfree(sdkp);
+
+ return 0;
+}
+
+static void sd_shutdown(struct device *dev)
+{
+ struct scsi_disk *sdkp = dev_get_drvdata(dev);
+
+ if (sdkp->WCE) {
+ printk(KERN_NOTICE "Synchronizing SCSI cache: ");
+ sd_synchronize_cache(sdkp, 1);
+ printk("\n");
+ }
}
/**
@@ -1457,7 +1421,7 @@
**/
static int __init init_sd(void)
{
- int majors = 0, rc = -ENODEV, i;
+ int majors = 0, i;
SCSI_LOG_HLQUEUE(3, printk("init_sd: sd driver entry point\n"));
@@ -1468,11 +1432,7 @@
if (!majors)
return -ENODEV;
- rc = scsi_register_device(&sd_template);
- if (rc)
- return rc;
- register_reboot_notifier(&sd_notifier_block);
- return rc;
+ return scsi_register_driver(&sd_template.gendrv);
}
/**
@@ -1486,35 +1446,9 @@
SCSI_LOG_HLQUEUE(3, printk("exit_sd: exiting sd driver\n"));
- unregister_reboot_notifier(&sd_notifier_block);
- scsi_unregister_device(&sd_template);
+ scsi_unregister_driver(&sd_template.gendrv);
for (i = 0; i < SD_MAJORS; i++)
unregister_blkdev(sd_major(i), "sd");
-}
-
-/*
- * XXX: this function does not take sd_devlist_lock to synchronize
- * access to sd_devlist. This should be safe as no other reboot
- * notifier can access it.
- */
-static int sd_notifier(struct notifier_block *n, unsigned long event, void *p)
-{
- if (event != SYS_RESTART &&
- event != SYS_HALT &&
- event != SYS_POWER_OFF)
- return NOTIFY_DONE;
-
- if (!list_empty(&sd_devlist)) {
- struct scsi_disk *sdkp;
-
- printk(KERN_NOTICE "Synchronizing SCSI caches: ");
- list_for_each_entry(sdkp, &sd_devlist, list)
- if (sdkp->WCE)
- sd_synchronize_cache(sdkp, 1);
- printk("\n");
- }
-
- return NOTIFY_OK;
}
/* send a SYNCHRONIZE CACHE instruction down to the device through the
--- 1.55/drivers/scsi/sg.c Tue May 13 05:52:57 2003
+++ edited/drivers/scsi/sg.c Mon May 26 11:38:00 2003
@@ -112,24 +112,17 @@
#define SG_DEV_ARR_LUMP 6 /* amount to over allocate sg_dev_arr by */
-static int sg_attach(Scsi_Device *);
-static void sg_detach(Scsi_Device *);
+static int sg_add(struct class_device *);
+static void sg_remove(struct class_device *);
static Scsi_Request *dummy_cmdp; /* only used for sizeof */
static rwlock_t sg_dev_arr_lock = RW_LOCK_UNLOCKED; /* Also used to lock
file descriptor list for device */
-static struct Scsi_Device_Template sg_template = {
- .module = THIS_MODULE,
- .list = LIST_HEAD_INIT(sg_template.list),
- .name = "generic",
- .scsi_type = 0xff,
- .attach = sg_attach,
- .detach = sg_detach,
- .scsi_driverfs_driver = {
- .name = "sg",
- },
+static struct class_interface sg_interface = {
+ .add = sg_add,
+ .remove = sg_remove,
};
typedef struct sg_scatter_hold { /* holding area for scsi scatter gather info */
@@ -180,15 +173,13 @@
} Sg_fd;
typedef struct sg_device { /* holds the state of each scsi generic device */
- struct Scsi_Device_Template *driver;
- Scsi_Device *device;
+ struct scsi_device *device;
wait_queue_head_t o_excl_wait; /* queue open() when O_EXCL in use */
int sg_tablesize; /* adapter's max scatter-gather table size */
Sg_fd *headfp; /* first open fd belonging to this device */
volatile char detached; /* 0->attached, 1->detached pending removal */
volatile char exclude; /* opened for exclusive access */
char sgdebug; /* 0->off, 1->sense, 9->dump dev, 10-> all devs */
- struct device sg_driverfs_dev;
struct gendisk *disk;
} Sg_device;
@@ -1328,27 +1319,10 @@
.fasync = sg_fasync,
};
-/* Driverfs file support */
-static ssize_t
-sg_device_kdev_read(struct device *driverfs_dev, char *page)
-{
- Sg_device *sdp = list_entry(driverfs_dev, Sg_device, sg_driverfs_dev);
- return sprintf(page, "%x\n", MKDEV(sdp->disk->major,
- sdp->disk->first_minor));
-}
-static DEVICE_ATTR(kdev,S_IRUGO,sg_device_kdev_read,NULL);
-
-static ssize_t
-sg_device_type_read(struct device *driverfs_dev, char *page)
-{
- return sprintf(page, "CHR\n");
-}
-
-static DEVICE_ATTR(type,S_IRUGO,sg_device_type_read,NULL);
-
static int
-sg_attach(Scsi_Device * scsidp)
+sg_add(struct class_device *cdev)
{
+ struct scsi_device *scsidp = to_scsi_device(cdev->dev);
struct gendisk *disk;
Sg_device *sdp = NULL;
unsigned long iflags;
@@ -1416,8 +1390,6 @@
SCSI_LOG_TIMEOUT(3, printk("sg_attach: dev=%d \n", k));
memset(sdp, 0, sizeof(*sdp));
- sdp->driver = &sg_template;
- disk->private_data = &sdp->driver;
sprintf(disk->disk_name, "sg%d", k);
disk->major = SCSI_GENERIC_MAJOR;
disk->first_minor = k;
@@ -1430,40 +1402,20 @@
sdp->detached = 0;
sdp->sg_tablesize = scsidp->host ? scsidp->host->sg_tablesize : 0;
- memset(&sdp->sg_driverfs_dev, 0, sizeof (struct device));
- snprintf(sdp->sg_driverfs_dev.bus_id, BUS_ID_SIZE, "%s:gen",
- scsidp->sdev_driverfs_dev.bus_id);
- snprintf(sdp->sg_driverfs_dev.name, DEVICE_NAME_SIZE, "%sgeneric",
- scsidp->sdev_driverfs_dev.name);
- sdp->sg_driverfs_dev.parent = &scsidp->sdev_driverfs_dev;
- sdp->sg_driverfs_dev.bus = scsidp->sdev_driverfs_dev.bus;
-
sg_nr_dev++;
sg_dev_arr[k] = sdp;
write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
- device_register(&sdp->sg_driverfs_dev);
- device_create_file(&sdp->sg_driverfs_dev, &dev_attr_type);
- device_create_file(&sdp->sg_driverfs_dev, &dev_attr_kdev);
-
devfs_mk_cdev(MKDEV(SCSI_GENERIC_MAJOR, k),
S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP,
"%s/generic", scsidp->devfs_name);
- switch (scsidp->type) {
- case TYPE_DISK:
- case TYPE_MOD:
- case TYPE_ROM:
- case TYPE_WORM:
- case TYPE_TAPE:
- break;
- default:
- printk(KERN_NOTICE
- "Attached scsi generic sg%d at scsi%d, channel"
- " %d, id %d, lun %d, type %d\n", k,
- scsidp->host->host_no, scsidp->channel, scsidp->id,
- scsidp->lun, scsidp->type);
- }
+ printk(KERN_NOTICE
+ "Attached scsi generic sg%d at scsi%d, channel"
+ " %d, id %d, lun %d, type %d\n", k,
+ scsidp->host->host_no, scsidp->channel, scsidp->id,
+ scsidp->lun, scsidp->type);
+
return 0;
out:
@@ -1472,8 +1424,9 @@
}
static void
-sg_detach(Scsi_Device * scsidp)
+sg_remove(struct class_device *cdev)
{
+ struct scsi_device *scsidp = to_scsi_device(cdev->dev);
Sg_device *sdp = NULL;
unsigned long iflags;
Sg_fd *sfp;
@@ -1524,9 +1477,6 @@
if (sdp) {
devfs_remove("%s/generic", scsidp->devfs_name);
- device_remove_file(&sdp->sg_driverfs_dev, &dev_attr_type);
- device_remove_file(&sdp->sg_driverfs_dev, &dev_attr_kdev);
- device_unregister(&sdp->sg_driverfs_dev);
put_disk(sdp->disk);
sdp->disk = NULL;
if (NULL == sdp->headfp)
@@ -1550,64 +1500,6 @@
MODULE_PARM_DESC(def_reserved_size, "size of buffer reserved for each fd");
-static ssize_t sg_allow_dio_show(struct device_driver * ddp, char * buf)
-{
- return snprintf(buf, PAGE_SIZE, "%d\n", sg_allow_dio);
-}
-static ssize_t sg_allow_dio_store(struct device_driver * ddp,
- const char * buf, size_t count)
-{
- if (1 == sscanf(buf, "%d", &sg_allow_dio)) {
- sg_allow_dio = sg_allow_dio ? 1 : 0;
- return count;
- }
- return -EINVAL;
-}
-DRIVER_ATTR(allow_dio, S_IRUGO | S_IWUSR, sg_allow_dio_show,
- sg_allow_dio_store)
-
-static ssize_t sg_def_reserved_show(struct device_driver * ddp, char * buf)
-{
- return snprintf(buf, PAGE_SIZE, "%d\n", sg_big_buff);
-}
-static ssize_t sg_def_reserved_store(struct device_driver * ddp,
- const char * buf, size_t count)
-{
- if (1 == sscanf(buf, "%d", &def_reserved_size)) {
- if (def_reserved_size >= 0) {
- sg_big_buff = def_reserved_size;
- return count;
- }
- }
- return -EINVAL;
-}
-DRIVER_ATTR(def_reserved_size, S_IRUGO | S_IWUSR, sg_def_reserved_show,
- sg_def_reserved_store)
-
-static ssize_t sg_version_show(struct device_driver * ddp, char * buf)
-{
- return snprintf(buf, PAGE_SIZE, "%s\n", sg_version_str);
-}
-DRIVER_ATTR(version, S_IRUGO, sg_version_show, NULL)
-
-static void do_create_driverfs_files(void)
-{
- struct device_driver * driverfs = &sg_template.scsi_driverfs_driver;
-
- driver_create_file(driverfs, &driver_attr_allow_dio);
- driver_create_file(driverfs, &driver_attr_def_reserved_size);
- driver_create_file(driverfs, &driver_attr_version);
-}
-
-static void do_remove_driverfs_files(void)
-{
- struct device_driver * driverfs = &sg_template.scsi_driverfs_driver;
-
- driver_remove_file(driverfs, &driver_attr_version);
- driver_remove_file(driverfs, &driver_attr_def_reserved_size);
- driver_remove_file(driverfs, &driver_attr_allow_dio);
-}
-
static int __init
init_sg(void)
{
@@ -1619,24 +1511,22 @@
rc = register_chrdev(SCSI_GENERIC_MAJOR, "sg", &sg_fops);
if (rc)
return rc;
- rc = scsi_register_device(&sg_template);
+ rc = scsi_register_interface(&sg_interface);
if (rc)
return rc;
#ifdef CONFIG_PROC_FS
sg_proc_init();
#endif /* CONFIG_PROC_FS */
- do_create_driverfs_files();
return 0;
}
static void __exit
exit_sg(void)
{
- do_remove_driverfs_files();
#ifdef CONFIG_PROC_FS
sg_proc_cleanup();
#endif /* CONFIG_PROC_FS */
- scsi_unregister_device(&sg_template);
+ scsi_unregister_interface(&sg_interface);
unregister_chrdev(SCSI_GENERIC_MAJOR, "sg");
if (sg_dev_arr != NULL) {
vfree((char *) sg_dev_arr);
--- 1.79/drivers/scsi/sr.c Fri May 23 12:02:30 2003
+++ edited/drivers/scsi/sr.c Mon May 26 11:24:25 2003
@@ -67,26 +67,20 @@
CDC_PLAY_AUDIO|CDC_RESET|CDC_IOCTLS|CDC_DRIVE_STATUS| \
CDC_CD_R|CDC_CD_RW|CDC_DVD|CDC_DVD_R|CDC_GENERIC_PACKET)
-static int sr_attach(struct scsi_device *);
-static void sr_detach(struct scsi_device *);
+static int sr_probe(struct device *);
+static int sr_remove(struct device *);
static int sr_init_command(struct scsi_cmnd *);
-static struct Scsi_Device_Template sr_template = {
- .module = THIS_MODULE,
- .list = LIST_HEAD_INIT(sr_template.list),
- .name = "cdrom",
- .scsi_type = TYPE_ROM,
- .attach = sr_attach,
- .detach = sr_detach,
- .init_command = sr_init_command,
- .scsi_driverfs_driver = {
- .name = "sr",
+static struct scsi_driver sr_template = {
+ .owner = THIS_MODULE,
+ .gendrv = {
+ .name = "sr",
+ .probe = sr_probe,
+ .remove = sr_remove,
},
+ .init_command = sr_init_command,
};
-static LIST_HEAD(sr_devlist);
-static spinlock_t sr_devlist_lock = SPIN_LOCK_UNLOCKED;
-
static unsigned long sr_index_bits[SR_DISKS / BITS_PER_LONG];
static spinlock_t sr_index_lock = SPIN_LOCK_UNLOCKED;
@@ -99,37 +93,6 @@
static int sr_media_change(struct cdrom_device_info *, int);
static int sr_packet(struct cdrom_device_info *, struct cdrom_generic_command *);
-static Scsi_CD *sr_find_by_sdev(Scsi_Device *sd)
-{
- struct list_head *p;
- Scsi_CD *cd;
-
- spin_lock(&sr_devlist_lock);
- list_for_each(p, &sr_devlist) {
- cd = list_entry(p, Scsi_CD, list);
- if (cd->device == sd) {
- spin_unlock(&sr_devlist_lock);
- return cd;
- }
- }
- spin_unlock(&sr_devlist_lock);
- return NULL;
-}
-
-static inline void sr_devlist_insert(Scsi_CD *cd)
-{
- spin_lock(&sr_devlist_lock);
- list_add(&cd->list, &sr_devlist);
- spin_unlock(&sr_devlist_lock);
-}
-
-static inline void sr_devlist_remove(Scsi_CD *cd)
-{
- spin_lock(&sr_devlist_lock);
- list_del(&cd->list);
- spin_unlock(&sr_devlist_lock);
-}
-
static struct cdrom_device_ops sr_dops = {
.open = sr_open,
.release = sr_release,
@@ -506,14 +469,16 @@
scsi_device_put(cd->device);
}
-static int sr_attach(struct scsi_device *sdev)
+static int sr_probe(struct device *dev)
{
+ struct scsi_device *sdev = to_scsi_device(dev);
struct gendisk *disk;
struct scsi_cd *cd;
int minor, error;
+ error = -ENODEV;
if (sdev->type != TYPE_ROM && sdev->type != TYPE_WORM)
- return 1;
+ goto fail;
error = -ENOMEM;
cd = kmalloc(sizeof(*cd), GFP_KERNEL);
@@ -575,8 +540,8 @@
disk->private_data = &cd->driver;
disk->queue = sdev->request_queue;
+ dev_set_drvdata(dev, cd);
add_disk(disk);
- sr_devlist_insert(cd);
printk(KERN_DEBUG
"Attached scsi CD-ROM %s at scsi%d, channel %d, id %d, lun %d\n",
@@ -807,15 +772,10 @@
return cgc->stat;
}
-static void sr_detach(struct scsi_device * SDp)
+static int sr_remove(struct device *dev)
{
- struct scsi_cd *cd;
+ struct scsi_cd *cd = dev_get_drvdata(dev);
- cd = sr_find_by_sdev(SDp);
- if (!cd)
- return;
-
- sr_devlist_remove(cd);
del_gendisk(cd->disk);
spin_lock(&sr_index_lock);
@@ -825,6 +785,8 @@
put_disk(cd->disk);
unregister_cdrom(&cd->cdi);
kfree(cd);
+
+ return 0;
}
static int __init init_sr(void)
@@ -834,12 +796,12 @@
rc = register_blkdev(SCSI_CDROM_MAJOR, "sr");
if (rc)
return rc;
- return scsi_register_device(&sr_template);
+ return scsi_register_driver(&sr_template.gendrv);
}
static void __exit exit_sr(void)
{
- scsi_unregister_device(&sr_template);
+ scsi_unregister_driver(&sr_template.gendrv);
unregister_blkdev(SCSI_CDROM_MAJOR, "sr");
}
--- 1.9/drivers/scsi/sr.h Sun Nov 3 14:46:32 2002
+++ edited/drivers/scsi/sr.h Mon May 26 09:50:43 2003
@@ -25,8 +25,7 @@
#define IOCTL_TIMEOUT 30*HZ
typedef struct scsi_cd {
- struct Scsi_Device_Template *driver;
- struct list_head list;
+ struct scsi_driver *driver;
unsigned capacity; /* size in blocks */
Scsi_Device *device;
unsigned int vendor; /* vendor code, see sr_vendor.c */
--- 1.62/drivers/scsi/st.c Tue May 13 05:52:58 2003
+++ edited/drivers/scsi/st.c Mon May 26 11:18:14 2003
@@ -170,22 +170,19 @@
unsigned long, size_t, int);
static int sgl_unmap_user_pages(struct scatterlist *, const unsigned int, int);
-static int st_attach(Scsi_Device *);
-static void st_detach(Scsi_Device *);
+static int st_probe(struct device *);
+static int st_remove(struct device *);
static void do_create_driverfs_files(void);
static void do_remove_driverfs_files(void);
-static struct Scsi_Device_Template st_template = {
- .module = THIS_MODULE,
- .list = LIST_HEAD_INIT(st_template.list),
- .name = "tape",
- .scsi_type = TYPE_TAPE,
- .attach = st_attach,
- .detach = st_detach,
- .scsi_driverfs_driver = {
- .name = "st",
+static struct scsi_driver st_template = {
+ .owner = THIS_MODULE,
+ .gendrv = {
+ .name = "st",
+ .probe = st_probe,
+ .remove = st_remove,
},
};
@@ -3704,8 +3701,9 @@
.release = st_release,
};
-static int st_attach(Scsi_Device * SDp)
+static int st_probe(struct device *dev)
{
+ struct scsi_device *SDp = to_scsi_device(dev);
struct gendisk *disk;
Scsi_Tape *tpnt;
ST_mode *STm;
@@ -3716,13 +3714,13 @@
u64 bounce_limit;
if (SDp->type != TYPE_TAPE)
- return 1;
+ return -ENODEV;
if ((stp = st_incompatible(SDp))) {
printk(KERN_INFO
"st: Found incompatible tape at scsi%d, channel %d, id %d, lun %d\n",
SDp->host->host_no, SDp->channel, SDp->id, SDp->lun);
printk(KERN_INFO "st: The suggested driver is %s.\n", stp);
- return 1;
+ return -ENODEV;
}
i = SDp->host->sg_tablesize;
@@ -3862,43 +3860,11 @@
write_unlock(&st_dev_arr_lock);
for (mode = 0; mode < ST_NBR_MODES; ++mode) {
- char name[8];
-
/* Rewind entry */
- sprintf(name, "mt%s", st_formats[mode]);
-
- sprintf(tpnt->driverfs_dev_r[mode].bus_id, "%s:%s",
- SDp->sdev_driverfs_dev.bus_id, name);
- sprintf(tpnt->driverfs_dev_r[mode].name, "%s%s",
- SDp->sdev_driverfs_dev.name, name);
- tpnt->driverfs_dev_r[mode].parent = &SDp->sdev_driverfs_dev;
- tpnt->driverfs_dev_r[mode].bus = SDp->sdev_driverfs_dev.bus;
- tpnt->driverfs_dev_r[mode].driver_data =
- (void *)(long)__mkdev(SCSI_TAPE_MAJOR, dev_num + (mode << 5));
- device_register(&tpnt->driverfs_dev_r[mode]);
- device_create_file(&tpnt->driverfs_dev_r[mode],
- &dev_attr_type);
- device_create_file(&tpnt->driverfs_dev_r[mode], &dev_attr_kdev);
devfs_mk_cdev(MKDEV(SCSI_TAPE_MAJOR, dev_num + (mode << 5)),
S_IFCHR | S_IRUGO | S_IWUGO,
"%s/mt%s", SDp->devfs_name, st_formats[mode]);
-
/* No-rewind entry */
- sprintf (name, "mt%sn", st_formats[mode]);
-
- sprintf(tpnt->driverfs_dev_n[mode].bus_id, "%s:%s",
- SDp->sdev_driverfs_dev.bus_id, name);
- sprintf(tpnt->driverfs_dev_n[mode].name, "%s%s",
- SDp->sdev_driverfs_dev.name, name);
- tpnt->driverfs_dev_n[mode].parent= &SDp->sdev_driverfs_dev;
- tpnt->driverfs_dev_n[mode].bus = SDp->sdev_driverfs_dev.bus;
- tpnt->driverfs_dev_n[mode].driver_data =
- (void *)(long)__mkdev(SCSI_TAPE_MAJOR, dev_num + (mode << 5) + 128);
- device_register(&tpnt->driverfs_dev_n[mode]);
- device_create_file(&tpnt->driverfs_dev_n[mode],
- &dev_attr_type);
- device_create_file(&tpnt->driverfs_dev_n[mode],
- &dev_attr_kdev);
devfs_mk_cdev(MKDEV(SCSI_TAPE_MAJOR, dev_num + (mode << 5) + 128),
S_IFCHR | S_IRUGO | S_IWUGO,
"%s/mt%sn", SDp->devfs_name, st_formats[mode]);
@@ -3918,11 +3884,12 @@
out_buffer_free:
kfree(buffer);
out:
- return 1;
+ return -ENODEV;
};
-static void st_detach(Scsi_Device * SDp)
+static int st_remove(struct device *dev)
{
+ Scsi_Device *SDp = to_scsi_device(dev);
Scsi_Tape *tpnt;
int i, mode;
@@ -3937,16 +3904,6 @@
for (mode = 0; mode < ST_NBR_MODES; ++mode) {
devfs_remove("%s/mt%s", SDp->devfs_name, st_formats[mode]);
devfs_remove("%s/mt%sn", SDp->devfs_name, st_formats[mode]);
- device_remove_file(&tpnt->driverfs_dev_r[mode],
- &dev_attr_type);
- device_remove_file(&tpnt->driverfs_dev_r[mode],
- &dev_attr_kdev);
- device_unregister(&tpnt->driverfs_dev_r[mode]);
- device_remove_file(&tpnt->driverfs_dev_n[mode],
- &dev_attr_type);
- device_remove_file(&tpnt->driverfs_dev_n[mode],
- &dev_attr_kdev);
- device_unregister(&tpnt->driverfs_dev_n[mode]);
}
tpnt->device = NULL;
@@ -3957,12 +3914,12 @@
}
put_disk(tpnt->disk);
kfree(tpnt);
- return;
+ return 0;
}
}
write_unlock(&st_dev_arr_lock);
- return;
+ return 0;
}
static int __init init_st(void)
@@ -3974,7 +3931,7 @@
verstr, st_fixed_buffer_size, st_max_sg_segs);
if (register_chrdev(SCSI_TAPE_MAJOR, "st", &st_fops) >= 0) {
- if (scsi_register_device(&st_template) == 0) {
+ if (scsi_register_driver(&st_template.gendrv) == 0) {
do_create_driverfs_files();
return 0;
}
@@ -3987,20 +3944,10 @@
static void __exit exit_st(void)
{
- int i;
-
do_remove_driverfs_files();
- scsi_unregister_device(&st_template);
+ scsi_unregister_driver(&st_template.gendrv);
unregister_chrdev(SCSI_TAPE_MAJOR, "st");
- if (scsi_tapes != NULL) {
- for (i=0; i < st_dev_max; ++i)
- if (scsi_tapes[i]) {
- printk(KERN_WARNING "st: scsi_tapes[] not "
- "empty after scsi_unregister_device\n");
- st_detach(scsi_tapes[i]->device);
- }
- kfree(scsi_tapes);
- }
+ kfree(scsi_tapes);
printk(KERN_INFO "st: Unloaded.\n");
}
@@ -4035,7 +3982,7 @@
static void do_create_driverfs_files(void)
{
- struct device_driver *driverfs = &st_template.scsi_driverfs_driver;
+ struct device_driver *driverfs = &st_template.gendrv;
driver_create_file(driverfs, &driver_attr_try_direct_io);
driver_create_file(driverfs, &driver_attr_fixed_buffer_size);
@@ -4045,7 +3992,7 @@
static void do_remove_driverfs_files(void)
{
- struct device_driver *driverfs = &st_template.scsi_driverfs_driver;
+ struct device_driver *driverfs = &st_template.gendrv;
driver_remove_file(driverfs, &driver_attr_version);
driver_remove_file(driverfs, &driver_attr_max_sg_segs);
===== drivers/scsi/st.h 1.13 vs edited =====
--- 1.13/drivers/scsi/st.h Fri Apr 18 17:57:20 2003
+++ edited/drivers/scsi/st.h Mon May 26 11:17:05 2003
@@ -70,7 +70,7 @@
/* The tape drive descriptor */
typedef struct {
- struct Scsi_Device_Template *driver;
+ struct scsi_driver *driver;
Scsi_Device *device;
struct semaphore lock; /* For serialization */
struct completion wait; /* For SCSI commands */
@@ -103,8 +103,6 @@
/* Mode characteristics */
ST_mode modes[ST_NBR_MODES];
int current_mode;
- struct device driverfs_dev_r[ST_NBR_MODES];
- struct device driverfs_dev_n[ST_NBR_MODES];
/* Status variables */
int partition;
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] driver model for scsi upper drivers, take 2
2003-05-27 9:43 ` Christoph Hellwig
@ 2003-05-29 9:23 ` Kai Makisara
[not found] ` <"from hch"@lst.de>
1 sibling, 0 replies; 4+ messages in thread
From: Kai Makisara @ 2003-05-29 9:23 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: James.Bottomley, linux-scsi
On Tue, 27 May 2003, Christoph Hellwig wrote:
> On Tue, May 27, 2003 at 09:32:18AM +0200, Christoph Hellwig wrote:
> > - removed the tape sysfs pseudodevice crap that caused hangs
> > - switched sg to a class_interface. This means sg can be used
> > on devices already claimed be an upper driver again. This
> > also means I had to remove the sg sysfs attributes temporarily
> > because the old mechanism is gone, but I'll restore them
> > differently in a followon patch.
>
> Yikes, this was the old patch again. Here's the right one:
>
I have done some tests with a disk, a tape, and different combinations
(in kernel/module) of the sd, st, sg, aic7xxx, and sym53c8xx_2
drivers. Looks good: devices are found and seem to work, no oopses
when loading/unloading modules. sysfs contents look correct (except
for the missing sg entries you said will re-appear in future).
--
Kai
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] driver model for scsi upper drivers, take 2
[not found] ` <"from hch"@lst.de>
@ 2003-06-18 9:04 ` Willem Riede
0 siblings, 0 replies; 4+ messages in thread
From: Willem Riede @ 2003-06-18 9:04 UTC (permalink / raw)
To: linux-scsi
On 2003.05.27 05:43, Christoph Hellwig wrote:
> On Tue, May 27, 2003 at 09:32:18AM +0200, Christoph Hellwig wrote:
> > - removed the tape sysfs pseudodevice crap that caused hangs
> > - switched sg to a class_interface. This means sg can be used
> > on devices already claimed be an upper driver again. This
> > also means I had to remove the sg sysfs attributes temporarily
> > because the old mechanism is gone, but I'll restore them
> > differently in a followon patch.
>
> Yikes, this was the old patch again. Here's the right one:
>
> --- 1.24/drivers/scsi/ide-scsi.c Thu May 15 04:55:52 2003
> +++ edited/drivers/scsi/ide-scsi.c Mon May 26 10:12:22 2003
> @@ -771,6 +771,10 @@
> static inline int should_transform(ide_drive_t *drive, Scsi_Cmnd *cmd)
> {
> idescsi_scsi_t *scsi = drive_to_idescsi(drive);
> +
> + /* this was a layering violation and we can't support it
> + anymore, sorry. */
> +#if 0
> struct gendisk *disk = cmd->request->rq_disk;
>
> if (disk) {
> @@ -778,6 +782,7 @@
> if (strcmp((*p)->scsi_driverfs_driver.name, "sg") == 0)
> return test_bit(IDESCSI_SG_TRANSFORM, &scsi->transform);
> }
> +#endif
You removed whatever capability was provided by IDESCSI_SG_TRANSFORM.
Just curious, what did that do? And, does that capability need to be
replaced, and if so, any suggestions how to do so?
Thanks, Willem Riede.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2003-06-18 8:50 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-05-27 7:32 [PATCH] driver model for scsi upper drivers, take 2 Christoph Hellwig
2003-05-27 9:43 ` Christoph Hellwig
2003-05-29 9:23 ` Kai Makisara
[not found] ` <"from hch"@lst.de>
2003-06-18 9:04 ` Willem Riede
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox