Commit 0b33a176 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Doug Ledford

[PATCH] more sdev freeing rationalization

(1) new helper in scsi_scan.c: scsi_forget_host.  it's the counterpart to
    scsi_scan_host.  it shares code with scsi_remove_single_device
    through a common subroutine, scsi_forget_host.
(2) move scsi_get_host_dev/scsi_free_host_dev (again).  Having them in
    scsi_scan.c allows to make scsi_alloc_sdev/scsi_free_sdev static.
parent 5678448a
...@@ -260,7 +260,6 @@ static int scsi_check_device_busy(struct scsi_device *sdev) ...@@ -260,7 +260,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 +286,9 @@ int scsi_remove_host(struct Scsi_Host *shost) ...@@ -287,16 +286,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;
} }
...@@ -668,64 +660,6 @@ void __init scsi_host_init(void) ...@@ -668,64 +660,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 +699,3 @@ void scsi_host_failed_inc_and_test(struct Scsi_Host *shost) ...@@ -765,22 +699,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
{ {
......
...@@ -507,9 +507,6 @@ static inline void scsi_proc_host_rm(struct Scsi_Host *); ...@@ -507,9 +507,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);
......
...@@ -465,8 +465,8 @@ static void scsi_initialize_merge_fn(struct scsi_device *sd) ...@@ -465,8 +465,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;
...@@ -535,7 +535,7 @@ struct scsi_device *scsi_alloc_sdev(struct Scsi_Host *shost, uint channel, ...@@ -535,7 +535,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);
...@@ -1412,6 +1412,14 @@ static int scsi_add_lun(Scsi_Device *sdevscan, Scsi_Device **sdevnew, ...@@ -1412,6 +1412,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
...@@ -1934,8 +1942,7 @@ int scsi_remove_single_device(uint host, uint channel, uint id, uint lun) ...@@ -1934,8 +1942,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:
...@@ -2061,3 +2068,69 @@ void scsi_scan_host(struct Scsi_Host *shost) ...@@ -2061,3 +2068,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