Commit 1b75d964 authored by James Bottomley's avatar James Bottomley

Merge mulgrave.(none):/home/jejb/BK/scsi-misc-2.5

into mulgrave.(none):/home/jejb/BK/scsi-misc-new-2.5
parents c9e54010 45f841b0
...@@ -124,8 +124,6 @@ ...@@ -124,8 +124,6 @@
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/init.h>
#include <linux/mca.h>
#include <asm/dma.h> #include <asm/dma.h>
#include <asm/system.h> #include <asm/system.h>
#include <asm/io.h> #include <asm/io.h>
...@@ -236,7 +234,7 @@ static __u8 NCR_700_SDTR_msg[] = { ...@@ -236,7 +234,7 @@ static __u8 NCR_700_SDTR_msg[] = {
NCR_700_MAX_OFFSET NCR_700_MAX_OFFSET
}; };
struct Scsi_Host * __init struct Scsi_Host *
NCR_700_detect(Scsi_Host_Template *tpnt, NCR_700_detect(Scsi_Host_Template *tpnt,
struct NCR_700_Host_Parameters *hostdata) struct NCR_700_Host_Parameters *hostdata)
{ {
...@@ -2020,3 +2018,5 @@ NCR_700_slave_destroy(Scsi_Device *SDp) ...@@ -2020,3 +2018,5 @@ NCR_700_slave_destroy(Scsi_Device *SDp)
EXPORT_SYMBOL(NCR_700_detect); EXPORT_SYMBOL(NCR_700_detect);
EXPORT_SYMBOL(NCR_700_release); EXPORT_SYMBOL(NCR_700_release);
EXPORT_SYMBOL(NCR_700_intr); EXPORT_SYMBOL(NCR_700_intr);
no_module_init;
...@@ -22,11 +22,11 @@ static int D700_release(struct Scsi_Host *host); ...@@ -22,11 +22,11 @@ static int D700_release(struct Scsi_Host *host);
* remaining parameters shown below must be filled in. The 53c700 * remaining parameters shown below must be filled in. The 53c700
* routine NCR_700_detect will fill in all of the missing routines */ * routine NCR_700_detect will fill in all of the missing routines */
#define NCR_D700_SCSI { \ #define NCR_D700_SCSI { \
name: "NCR Dual 700 MCA", \ .name = "NCR Dual 700 MCA", \
proc_name: "NCR_D700", \ .proc_name = "NCR_D700", \
detect: D700_detect, \ .detect = D700_detect, \
release: D700_release, \ .release = D700_release, \
this_id: 7, \ .this_id = 7, \
} }
......
...@@ -36,7 +36,6 @@ ...@@ -36,7 +36,6 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/smp_lock.h>
#define __KERNEL_SYSCALLS__ #define __KERNEL_SYSCALLS__
...@@ -50,7 +49,6 @@ static LIST_HEAD(scsi_host_list); ...@@ -50,7 +49,6 @@ static LIST_HEAD(scsi_host_list);
static spinlock_t scsi_host_list_lock = SPIN_LOCK_UNLOCKED; static spinlock_t scsi_host_list_lock = SPIN_LOCK_UNLOCKED;
static int scsi_host_next_hn; /* host_no for next new host */ static int scsi_host_next_hn; /* host_no for next new host */
static int scsi_hosts_registered; /* cnt of registered scsi hosts */
static char *scsihosts; static char *scsihosts;
MODULE_PARM(scsihosts, "s"); MODULE_PARM(scsihosts, "s");
...@@ -192,7 +190,7 @@ static void scsi_host_legacy_release(struct Scsi_Host *shost) ...@@ -192,7 +190,7 @@ static void scsi_host_legacy_release(struct Scsi_Host *shost)
static int scsi_remove_legacy_host(struct Scsi_Host *shost) static int scsi_remove_legacy_host(struct Scsi_Host *shost)
{ {
int error, pcount = scsi_hosts_registered; int error;
error = scsi_remove_host(shost); error = scsi_remove_host(shost);
if (error) if (error)
...@@ -203,8 +201,6 @@ static int scsi_remove_legacy_host(struct Scsi_Host *shost) ...@@ -203,8 +201,6 @@ static int scsi_remove_legacy_host(struct Scsi_Host *shost)
else else
scsi_host_legacy_release(shost); scsi_host_legacy_release(shost);
if (pcount == scsi_hosts_registered)
scsi_unregister(shost);
return 0; return 0;
} }
...@@ -260,7 +256,6 @@ static int scsi_check_device_busy(struct scsi_device *sdev) ...@@ -260,7 +256,6 @@ static int scsi_check_device_busy(struct scsi_device *sdev)
int scsi_remove_host(struct Scsi_Host *shost) int scsi_remove_host(struct Scsi_Host *shost)
{ {
struct scsi_device *sdev; struct scsi_device *sdev;
struct list_head *le, *lh;
/* /*
* FIXME Do ref counting. We force all of the devices offline to * FIXME Do ref counting. We force all of the devices offline to
...@@ -287,16 +282,9 @@ int scsi_remove_host(struct Scsi_Host *shost) ...@@ -287,16 +282,9 @@ int scsi_remove_host(struct Scsi_Host *shost)
sdev->attached); sdev->attached);
return 1; return 1;
} }
devfs_unregister(sdev->de);
device_unregister(&sdev->sdev_driverfs_dev);
}
/* Next we free up the Scsi_Cmnd structures for this host */
list_for_each_safe(le, lh, &shost->my_devices) {
scsi_free_sdev(list_entry(le, Scsi_Device, siblings));
} }
scsi_forget_host(shost);
return 0; return 0;
} }
...@@ -343,7 +331,6 @@ void scsi_unregister(struct Scsi_Host *shost) ...@@ -343,7 +331,6 @@ void scsi_unregister(struct Scsi_Host *shost)
shost->eh_notify = NULL; shost->eh_notify = NULL;
} }
scsi_hosts_registered--;
shost->hostt->present--; shost->hostt->present--;
/* Cleanup proc and driverfs */ /* Cleanup proc and driverfs */
...@@ -395,7 +382,6 @@ struct Scsi_Host * scsi_register(Scsi_Host_Template *shost_tp, int xtr_bytes) ...@@ -395,7 +382,6 @@ struct Scsi_Host * scsi_register(Scsi_Host_Template *shost_tp, int xtr_bytes)
memset(shost, 0, sizeof(struct Scsi_Host) + xtr_bytes); memset(shost, 0, sizeof(struct Scsi_Host) + xtr_bytes);
shost->host_no = scsi_alloc_host_num(shost_tp->proc_name); shost->host_no = scsi_alloc_host_num(shost_tp->proc_name);
scsi_hosts_registered++;
spin_lock_init(&shost->default_lock); spin_lock_init(&shost->default_lock);
scsi_assign_lock(shost, &shost->default_lock); scsi_assign_lock(shost, &shost->default_lock);
...@@ -491,7 +477,6 @@ struct Scsi_Host * scsi_register(Scsi_Host_Template *shost_tp, int xtr_bytes) ...@@ -491,7 +477,6 @@ struct Scsi_Host * scsi_register(Scsi_Host_Template *shost_tp, int xtr_bytes)
int scsi_register_host(Scsi_Host_Template *shost_tp) int scsi_register_host(Scsi_Host_Template *shost_tp)
{ {
struct Scsi_Host *shost; struct Scsi_Host *shost;
int cur_cnt;
/* /*
* Check no detect routine. * Check no detect routine.
...@@ -503,8 +488,6 @@ int scsi_register_host(Scsi_Host_Template *shost_tp) ...@@ -503,8 +488,6 @@ int scsi_register_host(Scsi_Host_Template *shost_tp)
if (!shost_tp->max_sectors) if (!shost_tp->max_sectors)
shost_tp->max_sectors = 1024; shost_tp->max_sectors = 1024;
cur_cnt = scsi_hosts_registered;
/* /*
* The detect routine must carefully spinunlock/spinlock if it * The detect routine must carefully spinunlock/spinlock if it
* enables interrupts, since all interrupt handlers do spinlock as * enables interrupts, since all interrupt handlers do spinlock as
...@@ -520,28 +503,6 @@ int scsi_register_host(Scsi_Host_Template *shost_tp) ...@@ -520,28 +503,6 @@ int scsi_register_host(Scsi_Host_Template *shost_tp)
if (!shost_tp->present) if (!shost_tp->present)
return 0; return 0;
if (cur_cnt == scsi_hosts_registered) {
if (shost_tp->present > 1) {
printk(KERN_ERR "scsi: Failure to register"
"low-level scsi driver");
scsi_unregister_host(shost_tp);
return 1;
}
/*
* The low-level driver failed to register a driver.
* We can do this now.
*
* XXX Who needs manual registration and why???
*/
if (!scsi_register(shost_tp, 0)) {
printk(KERN_ERR "scsi: register failed.\n");
scsi_unregister_host(shost_tp);
return 1;
}
}
/* /*
* XXX(hch) use scsi_tp_for_each_host() once it propagates * XXX(hch) use scsi_tp_for_each_host() once it propagates
* error returns properly. * error returns properly.
...@@ -575,20 +536,7 @@ int scsi_register_host(Scsi_Host_Template *shost_tp) ...@@ -575,20 +536,7 @@ int scsi_register_host(Scsi_Host_Template *shost_tp)
**/ **/
int scsi_unregister_host(Scsi_Host_Template *shost_tp) int scsi_unregister_host(Scsi_Host_Template *shost_tp)
{ {
int pcount;
/* get the big kernel lock, so we don't race with open() */
lock_kernel();
pcount = scsi_hosts_registered;
scsi_tp_for_each_host(shost_tp, scsi_remove_legacy_host); scsi_tp_for_each_host(shost_tp, scsi_remove_legacy_host);
if (pcount != scsi_hosts_registered)
printk(KERN_INFO "scsi : %d host%s left.\n", scsi_hosts_registered,
(scsi_hosts_registered == 1) ? "" : "s");
unlock_kernel();
return 0; return 0;
} }
...@@ -668,64 +616,6 @@ void __init scsi_host_init(void) ...@@ -668,64 +616,6 @@ void __init scsi_host_init(void)
} }
} }
/*
* Function: scsi_get_host_dev()
*
* Purpose: Create a Scsi_Device that points to the host adapter itself.
*
* Arguments: SHpnt - Host that needs a Scsi_Device
*
* Lock status: None assumed.
*
* Returns: The Scsi_Device or NULL
*
* Notes:
* Attach a single Scsi_Device to the Scsi_Host - this should
* be made to look like a "pseudo-device" that points to the
* HA itself.
*
* Note - this device is not accessible from any high-level
* drivers (including generics), which is probably not
* optimal. We can add hooks later to attach
*/
struct scsi_device *scsi_get_host_dev(struct Scsi_Host *shost)
{
struct scsi_device *sdev;
sdev = scsi_alloc_sdev(shost, 0, shost->this_id, 0);
if (sdev) {
scsi_build_commandblocks(sdev);
if (sdev->current_queue_depth == 0)
goto fail;
sdev->borken = 0;
}
return sdev;
fail:
kfree(sdev);
return NULL;
}
/*
* Function: scsi_free_host_dev()
*
* Purpose: Free a scsi_device that points to the host adapter itself.
*
* Arguments: SHpnt - Host that needs a Scsi_Device
*
* Lock status: None assumed.
*
* Returns: Nothing
*
* Notes:
*/
void scsi_free_host_dev(struct scsi_device *sdev)
{
BUG_ON(sdev->id != sdev->host->this_id);
scsi_free_sdev(sdev);
}
void scsi_host_busy_inc(struct Scsi_Host *shost, Scsi_Device *sdev) void scsi_host_busy_inc(struct Scsi_Host *shost, Scsi_Device *sdev)
{ {
unsigned long flags; unsigned long flags;
...@@ -765,22 +655,3 @@ void scsi_host_failed_inc_and_test(struct Scsi_Host *shost) ...@@ -765,22 +655,3 @@ void scsi_host_failed_inc_and_test(struct Scsi_Host *shost)
} }
spin_unlock_irqrestore(shost->host_lock, flags); spin_unlock_irqrestore(shost->host_lock, flags);
} }
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
* adjust the settings for this buffer only. This must remain at the end
* of the file.
* ---------------------------------------------------------------------------
* Local variables:
* c-indent-level: 4
* c-brace-imaginary-offset: 0
* c-brace-offset: -4
* c-argdecl-indent: 4
* c-label-offset: -4
* c-continued-statement-offset: 4
* c-continued-brace-offset: 0
* indent-tabs-mode: nil
* tab-width: 8
* End:
*/
...@@ -532,6 +532,8 @@ static inline void scsi_set_pci_device(struct Scsi_Host *shost, ...@@ -532,6 +532,8 @@ static inline void scsi_set_pci_device(struct Scsi_Host *shost,
* Prototypes for functions/data in scsi_scan.c * Prototypes for functions/data in scsi_scan.c
*/ */
extern void scsi_scan_host(struct Scsi_Host *); extern void scsi_scan_host(struct Scsi_Host *);
extern void scsi_forget_host(struct Scsi_Host *);
struct Scsi_Device_Template struct Scsi_Device_Template
{ {
......
This diff is collapsed.
...@@ -510,7 +510,7 @@ typedef struct os_header_s { ...@@ -510,7 +510,7 @@ typedef struct os_header_s {
#define OS_AUX_SIZE (512) #define OS_AUX_SIZE (512)
//#define OSST_MAX_SG 2 //#define OSST_MAX_SG 2
/* The tape buffer descriptor. */ /* The OnStream tape buffer descriptor. */
typedef struct { typedef struct {
unsigned char in_use; unsigned char in_use;
unsigned char dma; /* DMA-able buffer */ unsigned char dma; /* DMA-able buffer */
...@@ -524,13 +524,13 @@ typedef struct { ...@@ -524,13 +524,13 @@ typedef struct {
Scsi_Request *last_SRpnt; Scsi_Request *last_SRpnt;
unsigned char *b_data; unsigned char *b_data;
os_aux_t *aux; /* onstream AUX structure at end of each block */ os_aux_t *aux; /* onstream AUX structure at end of each block */
unsigned short use_sg; /* zero or number of segments for this adapter */ unsigned short use_sg; /* zero or number of s/g segments for this adapter */
unsigned short sg_segs; /* total number of allocated segments */ unsigned short sg_segs; /* number of segments in s/g list */
unsigned short orig_sg_segs; /* number of segments allocated at first try */ unsigned short orig_sg_segs; /* number of segments allocated at first try */
struct scatterlist sg[1]; /* MUST BE last item */ struct scatterlist sg[1]; /* MUST BE last item */
} OSST_buffer; } OSST_buffer;
/* The tape drive descriptor */ /* The OnStream tape drive descriptor */
typedef struct { typedef struct {
struct Scsi_Device_Template *driver; struct Scsi_Device_Template *driver;
unsigned capacity; unsigned capacity;
...@@ -549,6 +549,7 @@ typedef struct { ...@@ -549,6 +549,7 @@ typedef struct {
unsigned char restr_dma; unsigned char restr_dma;
unsigned char scsi2_logical; unsigned char scsi2_logical;
unsigned char default_drvbuffer; /* 0xff = don't touch, value 3 bits */ unsigned char default_drvbuffer; /* 0xff = don't touch, value 3 bits */
unsigned char pos_unknown; /* after reset position unknown */
int write_threshold; int write_threshold;
int timeout; /* timeout for normal commands */ int timeout; /* timeout for normal commands */
int long_timeout; /* timeout for commands known to take long time*/ int long_timeout; /* timeout for commands known to take long time*/
...@@ -556,10 +557,10 @@ typedef struct { ...@@ -556,10 +557,10 @@ typedef struct {
/* Mode characteristics */ /* Mode characteristics */
ST_mode modes[ST_NBR_MODES]; ST_mode modes[ST_NBR_MODES];
int current_mode; int current_mode;
#ifdef CONFIG_DEVFS_FS
devfs_handle_t de_r[ST_NBR_MODES]; /* Rewind entries */ devfs_handle_t de_r[ST_NBR_MODES]; /* Rewind entries */
devfs_handle_t de_n[ST_NBR_MODES]; /* No-rewind entries */ devfs_handle_t de_n[ST_NBR_MODES]; /* No-rewind entries */
#endif struct device driverfs_dev_r[ST_NBR_MODES];
struct device driverfs_dev_n[ST_NBR_MODES];
/* Status variables */ /* Status variables */
int partition; int partition;
...@@ -628,7 +629,7 @@ typedef struct { ...@@ -628,7 +629,7 @@ typedef struct {
unsigned char last_cmnd[6]; unsigned char last_cmnd[6];
unsigned char last_sense[16]; unsigned char last_sense[16];
#endif #endif
struct gendisk *disk; struct gendisk *drive;
} OS_Scsi_Tape; } OS_Scsi_Tape;
/* Values of write_type */ /* Values of write_type */
......
...@@ -169,30 +169,13 @@ void scsi_build_commandblocks(Scsi_Device * SDpnt); ...@@ -169,30 +169,13 @@ void scsi_build_commandblocks(Scsi_Device * SDpnt);
/* /*
* Function: scsi_initialize_queue() * Function: scsi_initialize_queue()
* *
* Purpose: Selects queue handler function for a device. * Purpose: Sets up the block queue for a device.
* *
* Arguments: SDpnt - device for which we need a handler function. * Arguments: SDpnt - device for which we need a handler function.
* *
* Returns: Nothing * Returns: Nothing
* *
* Lock status: No locking assumed or required. * Lock status: No locking assumed or required.
*
* Notes: Most devices will end up using scsi_request_fn for the
* handler function (at least as things are done now).
* The "block" feature basically ensures that only one of
* the blocked hosts is active at one time, mainly to work around
* buggy DMA chipsets where the memory gets starved.
* For this case, we have a special handler function, which
* does some checks and ultimately calls scsi_request_fn.
*
* The single_lun feature is a similar special case.
*
* We handle these things by stacking the handlers. The
* special case handlers simply check a few conditions,
* and return if they are not supposed to do anything.
* In the event that things are OK, then they call the next
* handler in the list - ultimately they call scsi_request_fn
* to do the dirty deed.
*/ */
void scsi_initialize_queue(Scsi_Device * SDpnt, struct Scsi_Host * SHpnt) void scsi_initialize_queue(Scsi_Device * SDpnt, struct Scsi_Host * SHpnt)
{ {
...@@ -793,7 +776,6 @@ int scsi_dispatch_cmd(Scsi_Cmnd * SCpnt) ...@@ -793,7 +776,6 @@ int scsi_dispatch_cmd(Scsi_Cmnd * SCpnt)
rtn = host->hostt->queuecommand(SCpnt, scsi_done); rtn = host->hostt->queuecommand(SCpnt, scsi_done);
spin_unlock_irqrestore(host->host_lock, flags); spin_unlock_irqrestore(host->host_lock, flags);
if (rtn != 0) { if (rtn != 0) {
scsi_delete_timer(SCpnt);
scsi_mlqueue_insert(SCpnt, rtn == SCSI_MLQUEUE_DEVICE_BUSY ? rtn : SCSI_MLQUEUE_HOST_BUSY); scsi_mlqueue_insert(SCpnt, rtn == SCSI_MLQUEUE_DEVICE_BUSY ? rtn : SCSI_MLQUEUE_HOST_BUSY);
SCSI_LOG_MLQUEUE(3, SCSI_LOG_MLQUEUE(3,
printk("queuecommand : request rejected\n")); printk("queuecommand : request rejected\n"));
......
...@@ -509,9 +509,6 @@ static inline void scsi_proc_host_rm(struct Scsi_Host *); ...@@ -509,9 +509,6 @@ static inline void scsi_proc_host_rm(struct Scsi_Host *);
/* /*
* Prototypes for functions in scsi_scan.c * Prototypes for functions in scsi_scan.c
*/ */
extern struct scsi_device *scsi_alloc_sdev(struct Scsi_Host *,
uint, uint, uint);
extern void scsi_free_sdev(struct scsi_device *);
extern int scsi_add_single_device(uint, uint, uint, uint); extern int scsi_add_single_device(uint, uint, uint, uint);
extern int scsi_remove_single_device(uint, uint, uint, uint); extern int scsi_remove_single_device(uint, uint, uint, uint);
......
...@@ -7,18 +7,15 @@ ...@@ -7,18 +7,15 @@
* of people at Linux Expo. * of people at Linux Expo.
*/ */
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/bio.h> #include <linux/bio.h>
#include <linux/kernel.h>
#include <linux/blk.h> #include <linux/blk.h>
#include <asm/hardirq.h>
#include <linux/smp_lock.h>
#include <linux/completion.h> #include <linux/completion.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include "scsi.h" #include "scsi.h"
#include "hosts.h" #include "hosts.h"
#include <scsi/scsi_ioctl.h>
/* /*
* Function: scsi_insert_special_cmd() * Function: scsi_insert_special_cmd()
...@@ -665,7 +662,7 @@ static int scsi_init_io(Scsi_Cmnd *SCpnt) ...@@ -665,7 +662,7 @@ static int scsi_init_io(Scsi_Cmnd *SCpnt)
{ {
struct request *req = SCpnt->request; struct request *req = SCpnt->request;
struct scatterlist *sgpnt; struct scatterlist *sgpnt;
int count, gfp_mask, ret = 0; int count, ret = 0;
/* /*
* if this is a rq->data based REQ_BLOCK_PC, setup for a non-sg xfer * if this is a rq->data based REQ_BLOCK_PC, setup for a non-sg xfer
...@@ -685,16 +682,10 @@ static int scsi_init_io(Scsi_Cmnd *SCpnt) ...@@ -685,16 +682,10 @@ static int scsi_init_io(Scsi_Cmnd *SCpnt)
*/ */
SCpnt->use_sg = req->nr_phys_segments; SCpnt->use_sg = req->nr_phys_segments;
gfp_mask = GFP_NOIO;
if (likely(in_atomic())) {
gfp_mask &= ~__GFP_WAIT;
gfp_mask |= __GFP_HIGH;
}
/* /*
* if sg table allocation fails, requeue request later. * if sg table allocation fails, requeue request later.
*/ */
sgpnt = scsi_alloc_sgtable(SCpnt, gfp_mask); sgpnt = scsi_alloc_sgtable(SCpnt, GFP_ATOMIC);
if (unlikely(!sgpnt)) { if (unlikely(!sgpnt)) {
req->flags |= REQ_SPECIAL; req->flags |= REQ_SPECIAL;
ret = BLKPREP_DEFER; ret = BLKPREP_DEFER;
......
...@@ -472,8 +472,8 @@ static void scsi_initialize_merge_fn(struct scsi_device *sd) ...@@ -472,8 +472,8 @@ static void scsi_initialize_merge_fn(struct scsi_device *sd)
* Return value: * Return value:
* Scsi_Device pointer, or NULL on failure. * Scsi_Device pointer, or NULL on failure.
**/ **/
struct scsi_device *scsi_alloc_sdev(struct Scsi_Host *shost, uint channel, static struct scsi_device *scsi_alloc_sdev(struct Scsi_Host *shost,
uint id, uint lun) uint channel, uint id, uint lun)
{ {
struct scsi_device *sdev, *device; struct scsi_device *sdev, *device;
...@@ -542,7 +542,7 @@ struct scsi_device *scsi_alloc_sdev(struct Scsi_Host *shost, uint channel, ...@@ -542,7 +542,7 @@ struct scsi_device *scsi_alloc_sdev(struct Scsi_Host *shost, uint channel,
* Undo the actions in scsi_alloc_sdev, including removing @sdev from * Undo the actions in scsi_alloc_sdev, including removing @sdev from
* the list, and freeing @sdev. * the list, and freeing @sdev.
**/ **/
void scsi_free_sdev(struct scsi_device *sdev) static void scsi_free_sdev(struct scsi_device *sdev)
{ {
list_del(&sdev->siblings); list_del(&sdev->siblings);
list_del(&sdev->same_target_siblings); list_del(&sdev->same_target_siblings);
...@@ -1419,6 +1419,14 @@ static int scsi_add_lun(Scsi_Device *sdevscan, Scsi_Device **sdevnew, ...@@ -1419,6 +1419,14 @@ static int scsi_add_lun(Scsi_Device *sdevscan, Scsi_Device **sdevnew,
return SCSI_SCAN_LUN_PRESENT; return SCSI_SCAN_LUN_PRESENT;
} }
static int scsi_remove_lun(struct scsi_device *sdev)
{
devfs_unregister(sdev->de);
device_unregister(&sdev->sdev_driverfs_dev);
scsi_free_sdev(sdev);
}
/** /**
* scsi_probe_and_add_lun - probe a LUN, if a LUN is found add it * scsi_probe_and_add_lun - probe a LUN, if a LUN is found add it
* @sdevscan: probe the LUN corresponding to this Scsi_Device * @sdevscan: probe the LUN corresponding to this Scsi_Device
...@@ -1941,8 +1949,7 @@ int scsi_remove_single_device(uint host, uint channel, uint id, uint lun) ...@@ -1941,8 +1949,7 @@ int scsi_remove_single_device(uint host, uint channel, uint id, uint lun)
if (sdev->attached) if (sdev->attached)
goto out; goto out;
devfs_unregister(sdev->de); scsi_remove_lun(sdev);
scsi_free_sdev(sdev);
error = 0; error = 0;
out: out:
...@@ -2068,3 +2075,69 @@ void scsi_scan_host(struct Scsi_Host *shost) ...@@ -2068,3 +2075,69 @@ void scsi_scan_host(struct Scsi_Host *shost)
} }
scsi_free_sdev(sdevscan); scsi_free_sdev(sdevscan);
} }
void scsi_forget_host(struct Scsi_Host *shost)
{
struct list_head *le, *lh;
list_for_each_safe(le, lh, &shost->my_devices)
scsi_remove_lun(list_entry(le, struct scsi_device, siblings));
}
/*
* Function: scsi_get_host_dev()
*
* Purpose: Create a Scsi_Device that points to the host adapter itself.
*
* Arguments: SHpnt - Host that needs a Scsi_Device
*
* Lock status: None assumed.
*
* Returns: The Scsi_Device or NULL
*
* Notes:
* Attach a single Scsi_Device to the Scsi_Host - this should
* be made to look like a "pseudo-device" that points to the
* HA itself.
*
* Note - this device is not accessible from any high-level
* drivers (including generics), which is probably not
* optimal. We can add hooks later to attach
*/
struct scsi_device *scsi_get_host_dev(struct Scsi_Host *shost)
{
struct scsi_device *sdev;
sdev = scsi_alloc_sdev(shost, 0, shost->this_id, 0);
if (sdev) {
scsi_build_commandblocks(sdev);
if (sdev->current_queue_depth == 0)
goto fail;
sdev->borken = 0;
}
return sdev;
fail:
kfree(sdev);
return NULL;
}
/*
* Function: scsi_free_host_dev()
*
* Purpose: Free a scsi_device that points to the host adapter itself.
*
* Arguments: SHpnt - Host that needs a Scsi_Device
*
* Lock status: None assumed.
*
* Returns: Nothing
*
* Notes:
*/
void scsi_free_host_dev(struct scsi_device *sdev)
{
BUG_ON(sdev->id != sdev->host->this_id);
scsi_free_sdev(sdev);
}
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