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)
int scsi_remove_host(struct Scsi_Host *shost)
{
struct scsi_device *sdev;
struct list_head *le, *lh;
/*
* FIXME Do ref counting. We force all of the devices offline to
......@@ -287,16 +286,9 @@ int scsi_remove_host(struct Scsi_Host *shost)
sdev->attached);
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;
}
......@@ -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)
{
unsigned long flags;
......@@ -765,22 +699,3 @@ void scsi_host_failed_inc_and_test(struct Scsi_Host *shost)
}
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,
* Prototypes for functions/data in scsi_scan.c
*/
extern void scsi_scan_host(struct Scsi_Host *);
extern void scsi_forget_host(struct Scsi_Host *);
struct Scsi_Device_Template
{
......
......@@ -507,9 +507,6 @@ static inline void scsi_proc_host_rm(struct Scsi_Host *);
/*
* 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_remove_single_device(uint, uint, uint, uint);
......
......@@ -465,8 +465,8 @@ static void scsi_initialize_merge_fn(struct scsi_device *sd)
* Return value:
* Scsi_Device pointer, or NULL on failure.
**/
struct scsi_device *scsi_alloc_sdev(struct Scsi_Host *shost, uint channel,
uint id, uint lun)
static struct scsi_device *scsi_alloc_sdev(struct Scsi_Host *shost,
uint channel, uint id, uint lun)
{
struct scsi_device *sdev, *device;
......@@ -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
* 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->same_target_siblings);
......@@ -1412,6 +1412,14 @@ static int scsi_add_lun(Scsi_Device *sdevscan, Scsi_Device **sdevnew,
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
* @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)
if (sdev->attached)
goto out;
devfs_unregister(sdev->de);
scsi_free_sdev(sdev);
scsi_remove_lun(sdev);
error = 0;
out:
......@@ -2061,3 +2068,69 @@ void scsi_scan_host(struct Scsi_Host *shost)
}
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