Commit e9167d31 authored by Mike Anderson's avatar Mike Anderson Committed by James Bottomley

scsi sysfs update 3

I have attached an updated combined patch of my previously posted sysfs
changes. 

This patch is against linux-scsi.bkbits.net/scsi-misc-2.5

This patch contains these updates:
	- update to osst.c to support sysfs cleanups.
	- oops fix in osst.c detach if no device attached. A better
	  method than this quick fix is needed.
	- removed scsi_bus_hotplug function do to bug and not really
	  needed now as default gives path data. If needed in future can
	  be added with better definition.

-andmike
parent 1b75d964
......@@ -3051,7 +3051,7 @@ acornscsi_probe(struct expansion_card *ec, const struct ecard_id *id)
acornscsi_resetcard(ashost);
ret = scsi_add_host(host);
ret = scsi_add_host(host, &ec->dev);
if (ret == 0)
goto out;
......
......@@ -398,7 +398,7 @@ arxescsi_probe(struct expansion_card *ec, const struct ecard_id *id)
fas216_init(host);
ret = scsi_add_host(host);
ret = scsi_add_host(host, &ec->dev);
if (ret == 0)
goto out;
......
......@@ -299,7 +299,7 @@ cumanascsi1_probe(struct expansion_card *ec, const struct ecard_id *id)
NCR5380_print_options(host);
printk("\n");
ret = scsi_add_host(host);
ret = scsi_add_host(host, &ec->dev);
if (ret == 0)
goto out;
......
......@@ -503,7 +503,7 @@ cumanascsi2_probe(struct expansion_card *ec, const struct ecard_id *id)
fas216_init(host);
ret = scsi_add_host(host);
ret = scsi_add_host(host, &ec->dev);
if (ret == 0)
goto out;
......
......@@ -502,7 +502,7 @@ eesoxscsi_probe(struct expansion_card *ec, const struct ecard_id *id)
}
fas216_init(host);
ret = scsi_add_host(host);
ret = scsi_add_host(host, &ec->dev);
if (ret == 0)
goto out;
......
......@@ -160,7 +160,7 @@ oakscsi_probe(struct expansion_card *ec, const struct ecard_id *id)
NCR5380_print_options(host);
printk("\n");
ret = scsi_add_host(host);
ret = scsi_add_host(host, &ec->dev);
if (ret == 0)
goto out;
......
......@@ -376,7 +376,7 @@ powertecscsi_probe(struct expansion_card *ec, const struct ecard_id *id)
fas216_init(host);
ret = scsi_add_host(host);
ret = scsi_add_host(host, &ec->dev);
if (ret == 0)
goto out;
......
......@@ -123,7 +123,8 @@ obj-$(CONFIG_BLK_DEV_SR) += sr_mod.o
obj-$(CONFIG_CHR_DEV_SG) += sg.o
scsi_mod-objs := scsi.o hosts.o scsi_ioctl.o constants.o scsicam.o \
scsi_error.o scsi_lib.o scsi_scan.o scsi_syms.o
scsi_error.o scsi_lib.o scsi_scan.o scsi_syms.o \
scsi_sysfs.o
ifdef CONFIG_PROC_FS
scsi_mod-objs += scsi_proc.o
......
......@@ -288,7 +288,7 @@ int scsi_remove_host(struct Scsi_Host *shost)
return 0;
}
int scsi_add_host(struct Scsi_Host *shost)
int __scsi_add_host(struct Scsi_Host *shost)
{
Scsi_Host_Template *sht = shost->hostt;
struct scsi_device *sdev;
......@@ -297,7 +297,6 @@ int scsi_add_host(struct Scsi_Host *shost)
printk(KERN_INFO "scsi%d : %s\n", shost->host_no,
sht->info ? sht->info(shost) : sht->name);
device_register(&shost->host_driverfs_dev);
scsi_scan_host(shost);
list_for_each_entry (sdev, &shost->my_devices, siblings) {
......@@ -309,6 +308,22 @@ int scsi_add_host(struct Scsi_Host *shost)
return saved_error;
}
/**
* scsi_add_host - add a scsi host
* @shost: scsi host pointer to add
* @dev: a struct device of type scsi class
*
* Return value:
* 0 on success / != 0 for error
**/
int scsi_add_host(struct Scsi_Host *shost, struct device *dev)
{
dev->class_data = shost;
shost->host_gendev = dev;
return __scsi_add_host(shost);
}
/**
* scsi_unregister - unregister a scsi host
* @shost: scsi host to be unregistered
......@@ -333,9 +348,8 @@ void scsi_unregister(struct Scsi_Host *shost)
shost->hostt->present--;
/* Cleanup proc and driverfs */
/* Cleanup proc */
scsi_proc_host_rm(shost);
device_unregister(&shost->host_driverfs_dev);
kfree(shost);
}
......@@ -448,11 +462,6 @@ struct Scsi_Host * scsi_register(Scsi_Host_Template *shost_tp, int xtr_bytes)
scsi_proc_host_add(shost);
strncpy(shost->host_driverfs_dev.name, shost_tp->proc_name,
DEVICE_NAME_SIZE-1);
sprintf(shost->host_driverfs_dev.bus_id, "scsi%d",
shost->host_no);
shost->eh_notify = &sem;
kernel_thread((int (*)(void *)) scsi_error_handler, (void *) shost, 0);
/*
......@@ -509,7 +518,7 @@ int scsi_register_host(Scsi_Host_Template *shost_tp)
*/
list_for_each_entry(shost, &scsi_host_list, sh_list)
if (shost->hostt == shost_tp)
if (scsi_add_host(shost))
if (__scsi_add_host(shost))
goto out_of_space;
return 0;
......
......@@ -488,7 +488,7 @@ struct Scsi_Host
/*
* Support for driverfs filesystem
*/
struct device host_driverfs_dev;
struct device *host_gendev;
/*
* We should ensure that this is aligned, both for better performance
......@@ -499,6 +499,8 @@ struct Scsi_Host
__attribute__ ((aligned (sizeof(unsigned long))));
};
#define to_scsi_host(d) d->class_data
/*
* These two functions are used to allocate and free a pseudo device
* which will connect to the host adapter itself rather than any
......@@ -524,7 +526,7 @@ static inline void scsi_set_pci_device(struct Scsi_Host *shost,
struct pci_dev *pdev)
{
shost->pci_dev = pdev;
shost->host_driverfs_dev.parent=&pdev->dev;
shost->host_gendev = &pdev->dev;
}
......@@ -539,7 +541,6 @@ struct Scsi_Device_Template
{
struct list_head list;
const char * name;
const char * tag;
struct module * module; /* Used for loadable modules */
unsigned char scsi_type;
int (*attach)(Scsi_Device *); /* Attach devices to arrays */
......@@ -567,7 +568,7 @@ extern void scsi_unregister(struct Scsi_Host *);
/*
* HBA registration/unregistration.
*/
extern int scsi_add_host(struct Scsi_Host *);
extern int scsi_add_host(struct Scsi_Host *, struct device *);
extern int scsi_remove_host(struct Scsi_Host *);
/*
......@@ -606,6 +607,14 @@ static inline Scsi_Device *scsi_find_device(struct Scsi_Host *shost,
return sdev;
}
/*
* sysfs support
*/
extern int scsi_upper_driver_register(struct Scsi_Device_Template *);
extern void scsi_upper_driver_unregister(struct Scsi_Device_Template *);
extern struct device_class shost_devclass;
#endif
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
......
......@@ -167,10 +167,12 @@ struct Scsi_Device_Template osst_template =
.module = THIS_MODULE,
.list = LIST_HEAD_INIT(osst_template.list),
.name = "OnStream Tape",
.tag = "osst",
.scsi_type = TYPE_TAPE,
.attach = osst_attach,
.detach = osst_detach
.detach = osst_detach,
.scsi_driverfs_driver = {
.name = "osst",
},
};
static int osst_int_ioctl(OS_Scsi_Tape *STp, Scsi_Request ** aSRpnt, unsigned int cmd_in,unsigned long arg);
......@@ -5585,7 +5587,7 @@ static int osst_attach(Scsi_Device * SDp)
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 = &scsi_driverfs_bus_type;
tpnt->driverfs_dev_r[mode].bus = SDp->sdev_driverfs_dev.bus;
tpnt->driverfs_dev_r[mode].driver_data =
(void *)(long)__mkdev(MAJOR_NR, dev_num + (mode << 5));
device_register(&tpnt->driverfs_dev_r[mode]);
......@@ -5604,7 +5606,7 @@ static int osst_attach(Scsi_Device * SDp)
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 = &scsi_driverfs_bus_type;
tpnt->driverfs_dev_n[mode].bus = SDp->sdev_driverfs_dev.bus;
tpnt->driverfs_dev_n[mode].driver_data =
(void *)(long)__mkdev(MAJOR_NR, dev_num + (mode << 5) + 128);
device_register(&tpnt->driverfs_dev_n[mode]);
......@@ -5633,6 +5635,7 @@ static void osst_detach(Scsi_Device * SDp)
int i, mode;
write_lock(&os_scsi_tapes_lock);
if (os_scsi_tapes != NULL) {
for(i=0; i<osst_max_dev; i++) {
tpnt = os_scsi_tapes[i];
if(tpnt != NULL && tpnt->device == SDp) {
......@@ -5661,15 +5664,18 @@ static void osst_detach(Scsi_Device * SDp)
&dev_attr_kdev);
device_unregister(&tpnt->driverfs_dev_n[mode]);
}
if (tpnt->header_cache != NULL) vfree(tpnt->header_cache);
if (tpnt->header_cache != NULL)
vfree(tpnt->header_cache);
if (tpnt->buffer) {
normalize_buffer(tpnt->buffer);
kfree(tpnt->buffer);
}
kfree(tpnt);
return;
break;
}
}
}
write_unlock(&os_scsi_tapes_lock);
return;
}
......@@ -5687,9 +5693,6 @@ static int __init init_osst(void)
printk(KERN_ERR "osst :E: Unable to register major %d for OnStream tapes\n",MAJOR_NR);
return 1;
}
osst_template.scsi_driverfs_driver.name = (char *)osst_template.tag;
osst_template.scsi_driverfs_driver.bus = &scsi_driverfs_bus_type;
driver_register(&osst_template.scsi_driverfs_driver);
return 0;
}
......@@ -5701,7 +5704,6 @@ static void __exit exit_osst (void)
scsi_unregister_device(&osst_template);
unregister_chrdev(MAJOR_NR, "osst");
driver_unregister(&osst_template.scsi_driverfs_driver);
if (os_scsi_tapes) {
for (i=0; i < osst_max_dev; ++i) {
......
......@@ -2001,10 +2001,7 @@ int scsi_register_device(struct Scsi_Device_Template *tpnt)
list_add_tail(&tpnt->list, &scsi_devicelist);
up_write(&scsi_devicelist_mutex);
tpnt->scsi_driverfs_driver.name = (char *)tpnt->tag;
tpnt->scsi_driverfs_driver.bus = &scsi_driverfs_bus_type;
driver_register(&tpnt->scsi_driverfs_driver);
scsi_upper_driver_register(tpnt);
for (shpnt = scsi_host_get_next(NULL); shpnt;
shpnt = scsi_host_get_next(shpnt))
......@@ -2019,7 +2016,6 @@ int scsi_unregister_device(struct Scsi_Device_Template *tpnt)
Scsi_Device *SDpnt;
struct Scsi_Host *shpnt;
driver_unregister(&tpnt->scsi_driverfs_driver);
/*
* Next, detach the devices from the driver.
......@@ -2037,6 +2033,8 @@ int scsi_unregister_device(struct Scsi_Device_Template *tpnt)
list_del(&tpnt->list);
up_write(&scsi_devicelist_mutex);
scsi_upper_driver_unregister(tpnt);
/*
* Final cleanup for the driver is done in the driver sources in the
* cleanup function.
......@@ -2135,34 +2133,6 @@ void scsi_free_sgtable(struct scatterlist *sgl, int index)
mempool_free(sgl, sgp->pool);
}
static int scsi_bus_match(struct device *scsi_driverfs_dev,
struct device_driver *scsi_driverfs_drv)
{
char *p=0;
if (!strcmp("sd", scsi_driverfs_drv->name)) {
if ((p = strstr(scsi_driverfs_dev->bus_id, ":disc")) ||
(p = strstr(scsi_driverfs_dev->bus_id, ":p"))) {
return 1;
}
} else if (!strcmp("sg", scsi_driverfs_drv->name)) {
if (strstr(scsi_driverfs_dev->bus_id, ":gen"))
return 1;
} else if (!strcmp("sr",scsi_driverfs_drv->name)) {
if (strstr(scsi_driverfs_dev->bus_id,":cd"))
return 1;
} else if (!strcmp("st",scsi_driverfs_drv->name)) {
if (strstr(scsi_driverfs_dev->bus_id,":mt"))
return 1;
}
return 0;
}
struct bus_type scsi_driverfs_bus_type = {
.name = "scsi",
.match = scsi_bus_match,
};
static int __init init_scsi(void)
{
int i;
......@@ -2189,7 +2159,7 @@ static int __init init_scsi(void)
scsi_devfs_handle = devfs_mk_dir(NULL, "scsi", NULL);
scsi_host_init();
scsi_dev_info_list_init(scsi_dev_flags);
bus_register(&scsi_driverfs_bus_type);
scsi_sysfs_register();
open_softirq(SCSI_SOFTIRQ, scsi_softirq, NULL);
return 0;
}
......@@ -2198,7 +2168,7 @@ static void __exit exit_scsi(void)
{
int i;
bus_unregister(&scsi_driverfs_bus_type);
scsi_sysfs_unregister();
scsi_dev_info_list_delete();
devfs_unregister(scsi_devfs_handle);
scsi_exit_procfs();
......@@ -2212,5 +2182,5 @@ static void __exit exit_scsi(void)
}
}
module_init(init_scsi);
subsys_initcall(init_scsi);
module_exit(exit_scsi);
......@@ -401,9 +401,6 @@ typedef struct scsi_request Scsi_Request;
extern unsigned int scsi_logging_level; /* What do we log? */
extern struct bus_type scsi_driverfs_bus_type;
/*
* These are the error handling functions defined in scsi_error.c
*/
......@@ -989,4 +986,10 @@ static inline Scsi_Cmnd *scsi_find_tag(Scsi_Device *SDpnt, int tag) {
int scsi_set_medium_removal(Scsi_Device *dev, char state);
extern int scsi_device_register(struct scsi_device *);
extern void scsi_device_unregister(struct scsi_device *);
extern int scsi_sysfs_register(void);
extern void scsi_sysfs_unregister(void);
#endif
......@@ -155,6 +155,7 @@ static rwlock_t atomic_rw = RW_LOCK_UNLOCKED;
static char sdebug_proc_name[] = "scsi_debug";
static struct device_driver sdebug_driverfs_driver = {
.name = sdebug_proc_name,
.devclass = &shost_devclass,
};
/* function declarations */
......@@ -1501,7 +1502,7 @@ static void sdebug_add_shost(int num)
printk(KERN_ERR "sdebug_add_shost: scsi_register failed\n");
return;
}
err = scsi_add_host(hpnt);
err = scsi_add_host(hpnt, scsi_debug_hosts[num].dev);
if (err) {
printk(KERN_ERR "sdebug_add_shost: scsi_add_host failed\n");
scsi_unregister(hpnt);
......
......@@ -312,73 +312,6 @@ static void scsi_unlock_floptical(Scsi_Request *sreq, unsigned char *result)
SCSI_TIMEOUT, 3);
}
/**
* scsi_device_type_read - copy out the SCSI type
* @driverfs_dev: driverfs device to check
* @page: copy data into this area
* @count: number of bytes to copy
* @off: start at this offset in page
*
* Description:
* Called via driverfs when the "type" (in scsi_device_type_file)
* field is read. Copy the appropriate SCSI type string into @page,
* followed by a newline and a '\0'. Go through gyrations so we don't
* write more than @count, and we don't write past @off.
*
* Notes:
* This is for the top-most scsi entry in driverfs, the upper-level
* drivers have their own type file. XXX This is not part of scanning,
* other than we reference the attr struct in this file, move to
* scsi.c or scsi_lib.c.
*
* Return:
* number of bytes written into page.
**/
static ssize_t scsi_device_type_read(struct device *driverfs_dev, char *page,
size_t count, loff_t off)
{
struct scsi_device *sdev = to_scsi_device(driverfs_dev);
const char *type;
size_t size, len;
if ((sdev->type > MAX_SCSI_DEVICE_CODE) ||
(scsi_device_types[(int)sdev->type] == NULL))
type = "Unknown";
else
type = scsi_device_types[(int)sdev->type];
size = strlen(type);
/*
* Check if off is past size + 1 for newline + 1 for a '\0'.
*/
if (off >= (size + 2))
return 0;
if (size > off) {
len = min((size_t) (size - off), count);
memcpy(page + off, type + off, len);
} else
len = 0;
if (((len + off) == size) && (len < count))
/*
* We are at the end of the string and have space, add a
* new line.
*/
*(page + off + len++) = '\n';
if (((len + off) == (size + 1)) && (len < count))
/*
* We are past the newline and have space, add a
* terminating '\0'.
*/
*(page + off + len++) = '\0';
return len;
}
/*
* Create dev_attr_type. This is different from the dev_attr_type in scsi
* upper level drivers.
*/
static DEVICE_ATTR(type,S_IRUGO,scsi_device_type_read,NULL);
/**
* print_inquiry - printk the inquiry information
* @inq_result: printk this SCSI INQUIRY
......@@ -1366,19 +1299,7 @@ static int scsi_add_lun(Scsi_Device *sdevscan, Scsi_Device **sdevnew,
*/
scsi_load_identifier(sdev, sreq);
/*
* create driverfs files
*/
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_driverfs_dev;
sdev->sdev_driverfs_dev.bus = &scsi_driverfs_bus_type;
device_register(&sdev->sdev_driverfs_dev);
/*
* Create driverfs file entries
*/
device_create_file(&sdev->sdev_driverfs_dev, &dev_attr_type);
scsi_device_register(sdev);
sprintf(devname, "scsi/host%d/bus%d/target%d/lun%d",
sdev->host->host_no, sdev->channel, sdev->id, sdev->lun);
......@@ -1422,7 +1343,7 @@ static int scsi_add_lun(Scsi_Device *sdevscan, Scsi_Device **sdevnew,
static int scsi_remove_lun(struct scsi_device *sdev)
{
devfs_unregister(sdev->de);
device_unregister(&sdev->sdev_driverfs_dev);
scsi_device_unregister(sdev);
scsi_free_sdev(sdev);
}
......
......@@ -104,6 +104,6 @@ EXPORT_SYMBOL(scsi_add_timer);
EXPORT_SYMBOL(scsi_delete_timer);
/*
* driverfs support for determining driver types
* sysfs support
*/
EXPORT_SYMBOL(scsi_driverfs_bus_type);
EXPORT_SYMBOL(shost_devclass);
......@@ -105,11 +105,13 @@ static struct Scsi_Device_Template sd_template = {
.module = THIS_MODULE,
.list = LIST_HEAD_INIT(sd_template.list),
.name = "disk",
.tag = "sd",
.scsi_type = TYPE_DISK,
.attach = sd_attach,
.detach = sd_detach,
.init_command = sd_init_command,
.scsi_driverfs_driver = {
.name = "sd",
},
};
static struct scsi_disk *sd_find_by_sdev(Scsi_Device *sd)
......@@ -1343,7 +1345,6 @@ static void __exit exit_sd(void)
scsi_unregister_device(&sd_template);
for (i = 0; i < SD_MAJORS; i++)
unregister_blkdev(SD_MAJOR(i), "sd");
driver_unregister(&sd_template.scsi_driverfs_driver);
}
/*
......
......@@ -122,10 +122,12 @@ static struct Scsi_Device_Template sg_template = {
.module = THIS_MODULE,
.list = LIST_HEAD_INIT(sg_template.list),
.name = "generic",
.tag = "sg",
.scsi_type = 0xff,
.attach = sg_attach,
.detach = sg_detach
.detach = sg_detach,
.scsi_driverfs_driver = {
.name = "sg",
},
};
typedef struct sg_scatter_hold { /* holding area for scsi scatter gather info */
......@@ -1462,7 +1464,7 @@ sg_attach(Scsi_Device * scsidp)
sprintf(sdp->sg_driverfs_dev.name, "%sgeneric",
scsidp->sdev_driverfs_dev.name);
sdp->sg_driverfs_dev.parent = &scsidp->sdev_driverfs_dev;
sdp->sg_driverfs_dev.bus = &scsi_driverfs_bus_type;
sdp->sg_driverfs_dev.bus = scsidp->sdev_driverfs_dev.bus;
sg_nr_dev++;
sg_dev_arr[k] = sdp;
......
......@@ -73,11 +73,13 @@ static struct Scsi_Device_Template sr_template = {
.module = THIS_MODULE,
.list = LIST_HEAD_INIT(sr_template.list),
.name = "cdrom",
.tag = "sr",
.scsi_type = TYPE_ROM,
.attach = sr_attach,
.detach = sr_detach,
.init_command = sr_init_command
.init_command = sr_init_command,
.scsi_driverfs_driver = {
.name = "sr",
},
};
static int sr_nr_dev; /* XXX(hch) bad hack, we want a bitmap instead */
......
......@@ -176,10 +176,12 @@ static struct Scsi_Device_Template st_template = {
.module = THIS_MODULE,
.list = LIST_HEAD_INIT(st_template.list),
.name = "tape",
.tag = "st",
.scsi_type = TYPE_TAPE,
.attach = st_attach,
.detach = st_detach
.detach = st_detach,
.scsi_driverfs_driver = {
.name = "st",
},
};
static int st_compression(Scsi_Tape *, int);
......@@ -3826,7 +3828,7 @@ static int st_attach(Scsi_Device * SDp)
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 = &scsi_driverfs_bus_type;
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]);
......@@ -3845,7 +3847,7 @@ static int st_attach(Scsi_Device * SDp)
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 = &scsi_driverfs_bus_type;
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]);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment