Commit c5afd81e authored by Christof Schmitt's avatar Christof Schmitt Committed by James Bottomley

[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: default avatarFelix Beck <felix.beck@de.ibm.com>
Signed-off-by: default avatarChristof Schmitt <christof.schmitt@de.ibm.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@suse.de>
parent b1a58985
...@@ -80,28 +80,35 @@ int zfcp_reqlist_isempty(struct zfcp_adapter *adapter) ...@@ -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); if (ccw_device_set_online(ccwdev))
read_unlock_irq(&zfcp_data.config_lock); 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: ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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); ...@@ -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;
......
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