[SCSI] zfcp: Fix initial device and cfdc for delayed adapter allocation
With the change for delaying the allocation of zfcp_adapter, the initial device parameter function has to first call ccw_device_set_online which allocates the zfcp_adapter structure. Change this and adapt the cfdc part accordingly. Reviewed-by: Felix Beck <felix.beck@de.ibm.com> Signed-off-by: Christof Schmitt <christof.schmitt@de.ibm.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
This commit is contained in:
committed by
James Bottomley
parent
b1a5898585
commit
c5afd81e5d
@@ -80,28 +80,35 @@ int zfcp_reqlist_isempty(struct zfcp_adapter *adapter)
|
|||||||
|
|
||||||
static void __init zfcp_init_device_configure(char *busid, u64 wwpn, u64 lun)
|
static void __init zfcp_init_device_configure(char *busid, u64 wwpn, u64 lun)
|
||||||
{
|
{
|
||||||
|
struct ccw_device *ccwdev;
|
||||||
struct zfcp_adapter *adapter;
|
struct zfcp_adapter *adapter;
|
||||||
struct zfcp_port *port;
|
struct zfcp_port *port;
|
||||||
struct zfcp_unit *unit;
|
struct zfcp_unit *unit;
|
||||||
|
|
||||||
mutex_lock(&zfcp_data.config_mutex);
|
ccwdev = get_ccwdev_by_busid(&zfcp_ccw_driver, busid);
|
||||||
read_lock_irq(&zfcp_data.config_lock);
|
if (!ccwdev)
|
||||||
adapter = zfcp_get_adapter_by_busid(busid);
|
return;
|
||||||
if (adapter)
|
|
||||||
zfcp_adapter_get(adapter);
|
|
||||||
read_unlock_irq(&zfcp_data.config_lock);
|
|
||||||
|
|
||||||
|
if (ccw_device_set_online(ccwdev))
|
||||||
|
goto out_ccwdev;
|
||||||
|
|
||||||
|
mutex_lock(&zfcp_data.config_mutex);
|
||||||
|
adapter = dev_get_drvdata(&ccwdev->dev);
|
||||||
if (!adapter)
|
if (!adapter)
|
||||||
goto out_adapter;
|
goto out_unlock;
|
||||||
port = zfcp_port_enqueue(adapter, wwpn, 0, 0);
|
zfcp_adapter_get(adapter);
|
||||||
if (IS_ERR(port))
|
|
||||||
|
port = zfcp_get_port_by_wwpn(adapter, wwpn);
|
||||||
|
if (!port)
|
||||||
goto out_port;
|
goto out_port;
|
||||||
|
|
||||||
|
zfcp_port_get(port);
|
||||||
unit = zfcp_unit_enqueue(port, lun);
|
unit = zfcp_unit_enqueue(port, lun);
|
||||||
if (IS_ERR(unit))
|
if (IS_ERR(unit))
|
||||||
goto out_unit;
|
goto out_unit;
|
||||||
mutex_unlock(&zfcp_data.config_mutex);
|
mutex_unlock(&zfcp_data.config_mutex);
|
||||||
ccw_device_set_online(adapter->ccw_device);
|
|
||||||
|
|
||||||
|
zfcp_erp_unit_reopen(unit, 0, "auidc_1", NULL);
|
||||||
zfcp_erp_wait(adapter);
|
zfcp_erp_wait(adapter);
|
||||||
flush_work(&unit->scsi_work);
|
flush_work(&unit->scsi_work);
|
||||||
|
|
||||||
@@ -111,8 +118,10 @@ out_unit:
|
|||||||
zfcp_port_put(port);
|
zfcp_port_put(port);
|
||||||
out_port:
|
out_port:
|
||||||
zfcp_adapter_put(adapter);
|
zfcp_adapter_put(adapter);
|
||||||
out_adapter:
|
out_unlock:
|
||||||
mutex_unlock(&zfcp_data.config_mutex);
|
mutex_unlock(&zfcp_data.config_mutex);
|
||||||
|
out_ccwdev:
|
||||||
|
put_device(&ccwdev->dev);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -259,7 +259,7 @@ static void zfcp_ccw_shutdown(struct ccw_device *cdev)
|
|||||||
mutex_unlock(&zfcp_data.config_mutex);
|
mutex_unlock(&zfcp_data.config_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct ccw_driver zfcp_ccw_driver = {
|
struct ccw_driver zfcp_ccw_driver = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.name = "zfcp",
|
.name = "zfcp",
|
||||||
.ids = zfcp_ccw_device_id,
|
.ids = zfcp_ccw_device_id,
|
||||||
@@ -284,20 +284,3 @@ int __init zfcp_ccw_register(void)
|
|||||||
{
|
{
|
||||||
return ccw_driver_register(&zfcp_ccw_driver);
|
return ccw_driver_register(&zfcp_ccw_driver);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* zfcp_get_adapter_by_busid - find zfcp_adapter struct
|
|
||||||
* @busid: bus id string of zfcp adapter to find
|
|
||||||
*/
|
|
||||||
struct zfcp_adapter *zfcp_get_adapter_by_busid(char *busid)
|
|
||||||
{
|
|
||||||
struct ccw_device *ccw_device;
|
|
||||||
struct zfcp_adapter *adapter = NULL;
|
|
||||||
|
|
||||||
ccw_device = get_ccwdev_by_busid(&zfcp_ccw_driver, busid);
|
|
||||||
if (ccw_device) {
|
|
||||||
adapter = dev_get_drvdata(&ccw_device->dev);
|
|
||||||
put_device(&ccw_device->dev);
|
|
||||||
}
|
|
||||||
return adapter;
|
|
||||||
}
|
|
||||||
|
@@ -86,8 +86,23 @@ static int zfcp_cfdc_copy_to_user(void __user *user_buffer,
|
|||||||
static struct zfcp_adapter *zfcp_cfdc_get_adapter(u32 devno)
|
static struct zfcp_adapter *zfcp_cfdc_get_adapter(u32 devno)
|
||||||
{
|
{
|
||||||
char busid[9];
|
char busid[9];
|
||||||
|
struct ccw_device *ccwdev;
|
||||||
|
struct zfcp_adapter *adapter = NULL;
|
||||||
|
|
||||||
snprintf(busid, sizeof(busid), "0.0.%04x", devno);
|
snprintf(busid, sizeof(busid), "0.0.%04x", devno);
|
||||||
return zfcp_get_adapter_by_busid(busid);
|
ccwdev = get_ccwdev_by_busid(&zfcp_ccw_driver, busid);
|
||||||
|
if (!ccwdev)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
adapter = dev_get_drvdata(&ccwdev->dev);
|
||||||
|
if (!adapter)
|
||||||
|
goto out_put;
|
||||||
|
|
||||||
|
zfcp_adapter_get(adapter);
|
||||||
|
out_put:
|
||||||
|
put_device(&ccwdev->dev);
|
||||||
|
out:
|
||||||
|
return adapter;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int zfcp_cfdc_set_fsf(struct zfcp_fsf_cfdc *fsf_cfdc, int command)
|
static int zfcp_cfdc_set_fsf(struct zfcp_fsf_cfdc *fsf_cfdc, int command)
|
||||||
|
@@ -28,7 +28,7 @@ extern int zfcp_sg_setup_table(struct scatterlist *, int);
|
|||||||
/* zfcp_ccw.c */
|
/* zfcp_ccw.c */
|
||||||
extern int zfcp_ccw_register(void);
|
extern int zfcp_ccw_register(void);
|
||||||
extern int zfcp_ccw_priv_sch(struct zfcp_adapter *);
|
extern int zfcp_ccw_priv_sch(struct zfcp_adapter *);
|
||||||
extern struct zfcp_adapter *zfcp_get_adapter_by_busid(char *);
|
extern struct ccw_driver zfcp_ccw_driver;
|
||||||
|
|
||||||
/* zfcp_cfdc.c */
|
/* zfcp_cfdc.c */
|
||||||
extern struct miscdevice zfcp_cfdc_misc;
|
extern struct miscdevice zfcp_cfdc_misc;
|
||||||
|
Reference in New Issue
Block a user