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)
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_priv *priv;
......@@ -420,7 +420,7 @@ static void eth1394_update(struct unit_directory *ud)
hi = hpsb_get_hostinfo(&eth1394_highlevel, ud->ne->host);
if (!hi)
return;
return -ENOENT;
priv = (struct eth1394_priv *)hi->dev->priv;
......@@ -430,7 +430,7 @@ static void eth1394_update(struct unit_directory *ud)
node = kmalloc(sizeof(struct eth1394_node_ref),
in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
if (!node)
return;
return -ENOMEM;
node_info = kmalloc(sizeof(struct eth1394_node_info),
......@@ -446,6 +446,8 @@ static void eth1394_update(struct unit_directory *ud)
priv = (struct eth1394_priv *)hi->dev->priv;
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)
if (ud->device.driver) {
pdrv = container_of(ud->device.driver, struct hpsb_protocol_driver, driver);
if (pdrv->update)
pdrv->update(ud);
if (pdrv->update && 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);
......
......@@ -128,9 +128,11 @@ struct hpsb_protocol_driver {
* The update function is called when the node has just
* survived a bus reset, i.e. it is still present on the bus.
* 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 */
struct device_driver driver;
......
......@@ -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_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 = {
.name = SBP2_DEVICE_NAME,
.remove_host = sbp2_remove_host,
......@@ -638,28 +642,26 @@ static int sbp2_remove(struct device *dev)
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 sbp2scsi_host_info *hi = scsi_id->hi;
SBP2_DEBUG("sbp2_update");
hi = scsi_id->hi;
if (sbp2_reconnect_device(scsi_id)) {
/*
* 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);
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_remove_device(scsi_id);
return;
return -EBUSY;
}
}
......@@ -676,6 +678,8 @@ static void sbp2_update(struct unit_directory *ud)
* retried) and remove them from our queue
*/
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
......
......@@ -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,
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 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