Commit 228beab6 authored by Ben Collins's avatar Ben Collins

IEEE1394(r1146): Make the probe callback return an error if problems, and...

IEEE1394(r1146): Make the probe callback return an error if problems, and unbind drivers on failure.
parent 861f069a
...@@ -411,7 +411,7 @@ static int eth1394_remove(struct device *dev) ...@@ -411,7 +411,7 @@ static int eth1394_remove(struct device *dev)
return 0; return 0;
} }
static void eth1394_update(struct unit_directory *ud) static int eth1394_update(struct unit_directory *ud)
{ {
struct eth1394_host_info *hi; struct eth1394_host_info *hi;
struct eth1394_priv *priv; struct eth1394_priv *priv;
...@@ -420,7 +420,7 @@ static void eth1394_update(struct unit_directory *ud) ...@@ -420,7 +420,7 @@ static void eth1394_update(struct unit_directory *ud)
hi = hpsb_get_hostinfo(&eth1394_highlevel, ud->ne->host); hi = hpsb_get_hostinfo(&eth1394_highlevel, ud->ne->host);
if (!hi) if (!hi)
return; return -ENOENT;
priv = (struct eth1394_priv *)hi->dev->priv; priv = (struct eth1394_priv *)hi->dev->priv;
...@@ -430,7 +430,7 @@ static void eth1394_update(struct unit_directory *ud) ...@@ -430,7 +430,7 @@ static void eth1394_update(struct unit_directory *ud)
node = kmalloc(sizeof(struct eth1394_node_ref), node = kmalloc(sizeof(struct eth1394_node_ref),
in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
if (!node) if (!node)
return; return -ENOMEM;
node_info = kmalloc(sizeof(struct eth1394_node_info), node_info = kmalloc(sizeof(struct eth1394_node_info),
...@@ -446,6 +446,8 @@ static void eth1394_update(struct unit_directory *ud) ...@@ -446,6 +446,8 @@ static void eth1394_update(struct unit_directory *ud)
priv = (struct eth1394_priv *)hi->dev->priv; priv = (struct eth1394_priv *)hi->dev->priv;
list_add_tail(&node->list, &priv->ip_node_list); list_add_tail(&node->list, &priv->ip_node_list);
} }
return 0;
} }
......
...@@ -1364,8 +1364,11 @@ static void nodemgr_ud_update_pdrv(struct unit_directory *ud) ...@@ -1364,8 +1364,11 @@ static void nodemgr_ud_update_pdrv(struct unit_directory *ud)
if (ud->device.driver) { if (ud->device.driver) {
pdrv = container_of(ud->device.driver, struct hpsb_protocol_driver, driver); pdrv = container_of(ud->device.driver, struct hpsb_protocol_driver, driver);
if (pdrv->update) if (pdrv->update && pdrv->update(ud)) {
pdrv->update(ud); down_write(&ud->device.bus->subsys.rwsem);
device_release_driver(&ud->device);
up_write(&ud->device.bus->subsys.rwsem);
}
} }
put_device(&ud->device); put_device(&ud->device);
......
...@@ -128,9 +128,11 @@ struct hpsb_protocol_driver { ...@@ -128,9 +128,11 @@ struct hpsb_protocol_driver {
* The update function is called when the node has just * The update function is called when the node has just
* survived a bus reset, i.e. it is still present on the bus. * survived a bus reset, i.e. it is still present on the bus.
* However, it may be necessary to reestablish the connection * However, it may be necessary to reestablish the connection
* or login into the node again, depending on the protocol. * or login into the node again, depending on the protocol. If the
* probe fails (returns non-zero), we unbind the driver from this
* device.
*/ */
void (*update)(struct unit_directory *ud); int (*update)(struct unit_directory *ud);
/* Our LDM structure */ /* Our LDM structure */
struct device_driver driver; struct device_driver driver;
......
...@@ -234,6 +234,10 @@ const u8 sbp2_speedto_max_payload[] = { 0x7, 0x8, 0x9, 0xA, 0xB, 0xC }; ...@@ -234,6 +234,10 @@ const u8 sbp2_speedto_max_payload[] = { 0x7, 0x8, 0x9, 0xA, 0xB, 0xC };
static void sbp2_remove_host(struct hpsb_host *host); static void sbp2_remove_host(struct hpsb_host *host);
static void sbp2_host_reset(struct hpsb_host *host); static void sbp2_host_reset(struct hpsb_host *host);
static int sbp2_probe(struct device *dev);
static int sbp2_remove(struct device *dev);
static int sbp2_update(struct unit_directory *ud);
static struct hpsb_highlevel sbp2_highlevel = { static struct hpsb_highlevel sbp2_highlevel = {
.name = SBP2_DEVICE_NAME, .name = SBP2_DEVICE_NAME,
.remove_host = sbp2_remove_host, .remove_host = sbp2_remove_host,
...@@ -638,28 +642,26 @@ static int sbp2_remove(struct device *dev) ...@@ -638,28 +642,26 @@ static int sbp2_remove(struct device *dev)
return 0; return 0;
} }
static void sbp2_update(struct unit_directory *ud) static int sbp2_update(struct unit_directory *ud)
{ {
struct scsi_id_instance_data *scsi_id = ud->device.driver_data; struct scsi_id_instance_data *scsi_id = ud->device.driver_data;
struct sbp2scsi_host_info *hi = scsi_id->hi;
SBP2_DEBUG("sbp2_update"); SBP2_DEBUG("sbp2_update");
hi = scsi_id->hi;
if (sbp2_reconnect_device(scsi_id)) { if (sbp2_reconnect_device(scsi_id)) {
/* /*
* Ok, reconnect has failed. Perhaps we didn't * Ok, reconnect has failed. Perhaps we didn't
* reconnect fast enough. Try doing a regular login. * reconnect fast enough. Try doing a regular login, but
* first do a logout just in case of any weirdness.
*/ */
sbp2_logout_device(scsi_id); sbp2_logout_device(scsi_id);
if (sbp2_login_device(scsi_id)) { if (sbp2_login_device(scsi_id)) {
/* Login failed too, just remove the device. */ /* Login failed too, just fail, and the backend
* will call our sbp2_remove for us */
SBP2_ERR("sbp2_reconnect_device failed!"); SBP2_ERR("sbp2_reconnect_device failed!");
sbp2_remove_device(scsi_id); return -EBUSY;
return;
} }
} }
...@@ -676,6 +678,8 @@ static void sbp2_update(struct unit_directory *ud) ...@@ -676,6 +678,8 @@ static void sbp2_update(struct unit_directory *ud)
* retried) and remove them from our queue * retried) and remove them from our queue
*/ */
sbp2scsi_complete_all_commands(scsi_id, DID_BUS_BUSY); sbp2scsi_complete_all_commands(scsi_id, DID_BUS_BUSY);
return 0;
} }
/* This functions is called by the sbp2_probe, for each new device. We now /* This functions is called by the sbp2_probe, for each new device. We now
......
...@@ -439,12 +439,6 @@ static struct sbp2_command_info *sbp2util_allocate_command_orb(struct scsi_id_in ...@@ -439,12 +439,6 @@ static struct sbp2_command_info *sbp2util_allocate_command_orb(struct scsi_id_in
static void sbp2util_mark_command_completed(struct scsi_id_instance_data *scsi_id, static void sbp2util_mark_command_completed(struct scsi_id_instance_data *scsi_id,
struct sbp2_command_info *command); struct sbp2_command_info *command);
/*
* IEEE-1394 core driver related prototypes
*/
static int sbp2_probe(struct device *dev);
static int sbp2_remove(struct device *dev);
static void sbp2_update(struct unit_directory *ud);
static int sbp2_start_device(struct scsi_id_instance_data *scsi_id); static int sbp2_start_device(struct scsi_id_instance_data *scsi_id);
static void sbp2_remove_device(struct scsi_id_instance_data *scsi_id); static void sbp2_remove_device(struct scsi_id_instance_data *scsi_id);
......
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