* cleanup function.
*/
return 0;
- error_out:
- unlock_kernel();
- return -1;
}
-#ifdef CONFIG_PROC_FS
-/*
- * Function: scsi_dump_status
- *
- * Purpose: Brain dump of scsi system, used for problem solving.
- *
- * Arguments: level - used to indicate level of detail.
- *
- * Notes: The level isn't used at all yet, but we need to find some way
- * of sensibly logging varying degrees of information. A quick one-line
- * display of each command, plus the status would be most useful.
- *
- * This does depend upon CONFIG_SCSI_LOGGING - I do want some way of turning
- * it all off if the user wants a lean and mean kernel. It would probably
- * also be useful to allow the user to specify one single host to be dumped.
- * A second argument to the function would be useful for that purpose.
- *
- * FIXME - some formatting of the output into tables would be very handy.
- */
-static void scsi_dump_status(int level)
-{
-#ifdef CONFIG_SCSI_LOGGING /* { */
- int i;
- struct Scsi_Host *shpnt;
- Scsi_Cmnd *SCpnt;
- Scsi_Device *SDpnt;
- printk(KERN_INFO "Dump of scsi host parameters:\n");
- i = 0;
- for (shpnt = scsi_host_get_next(NULL); shpnt;
- shpnt = scsi_host_get_next(shpnt)) {
- printk(KERN_INFO " %d %d %d : %d %d\n",
- shpnt->host_failed,
- shpnt->host_busy,
- atomic_read(&shpnt->host_active),
- shpnt->host_blocked,
- shpnt->host_self_blocked);
- }
-
- printk(KERN_INFO "\n\n");
- printk(KERN_INFO "Dump of scsi command parameters:\n");
- for (shpnt = scsi_host_get_next(NULL); shpnt;
- shpnt = scsi_host_get_next(shpnt)) {
- printk(KERN_INFO "h:c:t:l (dev sect nsect cnumsec sg) (ret all flg) (to/cmd to ito) cmd snse result\n");
- for (SDpnt = shpnt->host_queue; SDpnt; SDpnt = SDpnt->next) {
- for (SCpnt = SDpnt->device_queue; SCpnt; SCpnt = SCpnt->next) {
- /* (0) h:c:t:l (dev sect nsect cnumsec sg) (ret all flg) (to/cmd to ito) cmd snse result %d %x */
- printk(KERN_INFO "(%3d) %2d:%1d:%2d:%2d (%6s %4llu %4ld %4ld %4x %1d) (%1d %1d 0x%2x) (%4d %4d %4d) 0x%2.2x 0x%2.2x 0x%8.8x\n",
- i++,
-
- SCpnt->host->host_no,
- SCpnt->channel,
- SCpnt->target,
- SCpnt->lun,
-
- SCpnt->request->rq_disk ?
- SCpnt->request->rq_disk->disk_name : "?",
- (unsigned long long)SCpnt->request->sector,
- SCpnt->request->nr_sectors,
- (long)SCpnt->request->current_nr_sectors,
- SCpnt->request->rq_status,
- SCpnt->use_sg,
-
- SCpnt->retries,
- SCpnt->allowed,
- SCpnt->flags,
-
- SCpnt->timeout_per_command,
- SCpnt->timeout,
- SCpnt->internal_timeout,
-
- SCpnt->cmnd[0],
- SCpnt->sense_buffer[2],
- SCpnt->result);
- }
- }
- }
-#endif /* CONFIG_SCSI_LOGGING */ /* } */
-}
-#endif /* CONFIG_PROC_FS */
-
static char *scsi_dev_flags;
MODULE_PARM(scsi_dev_flags, "s");
MODULE_PARM_DESC(scsi_dev_flags,
sgp->pool = mempool_create(SG_MEMPOOL_SIZE, scsi_pool_alloc, scsi_pool_free, sgp->slab);
if (!sgp->pool)
- panic("SCSI: can't init sg mempool\n");
+ printk(KERN_ERR "SCSI: can't init sg mempool %s\n", sgp->name);
}
- scsi_init_procfs();
- scsi_devfs_handle = devfs_mk_dir(NULL, "scsi", NULL);
- /*
- * This makes /proc/scsi and /proc/scsi/scsi visible.
- */
-#ifdef CONFIG_PROC_FS
- proc_scsi = proc_mkdir("scsi", 0);
- if (!proc_scsi) {
- printk (KERN_ERR "cannot init /proc/scsi\n");
- goto out_error;
- }
- generic = create_proc_info_entry ("scsi/scsi", 0, 0, scsi_proc_info);
- if (!generic) {
- printk (KERN_ERR "cannot init /proc/scsi/scsi\n");
- goto out_proc_error;
- }
- generic->write_proc = proc_scsi_gen_write;
-
- generic = create_proc_info_entry ("scsi/device_info", 0, 0,
- proc_scsi_dev_info_read);
- if (!generic) {
- printk (KERN_ERR "cannot init /proc/scsi/device_info\n");
- remove_proc_entry("scsi/scsi", 0);
- remove_proc_entry("scsi", 0);
- return -ENOMEM;
- }
- generic->write_proc = proc_scsi_dev_info_write;
-#endif
-
- 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);
-
- /* Where we handle work queued by scsi_done */
open_softirq(SCSI_SOFTIRQ, scsi_softirq, NULL);
-
return 0;
+ #ifdef CONFIG_PROC_FS
+ out_proc_error:
+ remove_proc_entry("scsi", 0);
+ #endif
+ out_error:
+ for (i = 0; i < SG_MEMPOOL_NR; i++) {
+ struct scsi_host_sg_pool *sgp = scsi_sg_pools + i;
+ mempool_destroy(sgp->pool);
+ kmem_cache_destroy(sgp->slab);
+ sgp->pool = NULL;
+ sgp->slab = NULL;
+ }
+ return -ENOMEM;
}
static void __exit exit_scsi(void)