/* * scsi_dh_handler_attach - Attach a device handler to a device * @sdev - SCSI device the device handler should attach to * @scsi_dh - The device handler to attach
*/ staticint scsi_dh_handler_attach(struct scsi_device *sdev, struct scsi_device_handler *scsi_dh)
{ int error, ret = 0;
if (!try_module_get(scsi_dh->module)) return -EINVAL;
error = scsi_dh->attach(sdev); if (error != SCSI_DH_OK) { switch (error) { case SCSI_DH_NOMEM:
ret = -ENOMEM; break; case SCSI_DH_RES_TEMP_UNAVAIL:
ret = -EAGAIN; break; case SCSI_DH_DEV_UNSUPP: case SCSI_DH_NOSYS:
ret = -ENODEV; break; default:
ret = -EINVAL; break;
} if (ret != -ENODEV)
sdev_printk(KERN_ERR, sdev, "%s: Attach failed (%d)\n",
scsi_dh->name, error);
module_put(scsi_dh->module);
} else
sdev->handler = scsi_dh;
return ret;
}
/* * scsi_dh_handler_detach - Detach a device handler from a device * @sdev - SCSI device the device handler should be detached from
*/ staticvoid scsi_dh_handler_detach(struct scsi_device *sdev)
{
sdev->handler->detach(sdev);
sdev_printk(KERN_NOTICE, sdev, "%s: Detached\n", sdev->handler->name);
module_put(sdev->handler->module);
}
drv = scsi_dh_find_driver(sdev); if (drv)
devinfo = __scsi_dh_lookup(drv); /* * device_handler is optional, so ignore errors * from scsi_dh_handler_attach()
*/ if (devinfo)
(void)scsi_dh_handler_attach(sdev, devinfo);
}
void scsi_dh_release_device(struct scsi_device *sdev)
{ if (sdev->handler)
scsi_dh_handler_detach(sdev);
}
/* * scsi_register_device_handler - register a device handler personality * module. * @scsi_dh - device handler to be registered. * * Returns 0 on success, -EBUSY if handler already registered.
*/ int scsi_register_device_handler(struct scsi_device_handler *scsi_dh)
{ if (__scsi_dh_lookup(scsi_dh->name)) return -EBUSY;
if (!scsi_dh->attach || !scsi_dh->detach) return -EINVAL;
/* * scsi_unregister_device_handler - register a device handler personality * module. * @scsi_dh - device handler to be unregistered. * * Returns 0 on success, -ENODEV if handler not registered.
*/ int scsi_unregister_device_handler(struct scsi_device_handler *scsi_dh)
{ if (!__scsi_dh_lookup(scsi_dh->name)) return -ENODEV;
/* * scsi_dh_activate - activate the path associated with the scsi_device * corresponding to the given request queue. * Returns immediately without waiting for activation to be completed. * @q - Request queue that is associated with the scsi_device to be * activated. * @fn - Function to be called upon completion of the activation. * Function fn is called with data (below) and the error code. * Function fn may be called from the same calling context. So, * do not hold the lock in the caller which may be needed in fn. * @data - data passed to the function fn upon completion. *
*/ int scsi_dh_activate(struct request_queue *q, activate_complete fn, void *data)
{ struct scsi_device *sdev; int err = SCSI_DH_NOSYS;
sdev = scsi_device_from_queue(q); if (!sdev) { if (fn)
fn(data, err); return err;
}
if (!sdev->handler) goto out_fn;
err = SCSI_DH_NOTCONN; if (sdev->sdev_state == SDEV_CANCEL ||
sdev->sdev_state == SDEV_DEL) goto out_fn;
err = SCSI_DH_DEV_OFFLINED; if (sdev->sdev_state == SDEV_OFFLINE) goto out_fn;
if (sdev->handler->activate)
err = sdev->handler->activate(sdev, fn, data);
out_fn: if (fn)
fn(data, err); goto out_put_device;
}
EXPORT_SYMBOL_GPL(scsi_dh_activate);
/* * scsi_dh_set_params - set the parameters for the device as per the * string specified in params. * @q - Request queue that is associated with the scsi_device for * which the parameters to be set. * @params - parameters in the following format * "no_of_params\0param1\0param2\0param3\0...\0" * for example, string for 2 parameters with value 10 and 21 * is specified as "2\010\021\0".
*/ int scsi_dh_set_params(struct request_queue *q, constchar *params)
{ struct scsi_device *sdev; int err = -SCSI_DH_NOSYS;
sdev = scsi_device_from_queue(q); if (!sdev) return err;
/* * scsi_dh_attach - Attach device handler * @q - Request queue that is associated with the scsi_device * the handler should be attached to * @name - name of the handler to attach
*/ int scsi_dh_attach(struct request_queue *q, constchar *name)
{ struct scsi_device *sdev; struct scsi_device_handler *scsi_dh; int err = 0;
sdev = scsi_device_from_queue(q); if (!sdev) return -ENODEV;
/* * scsi_dh_attached_handler_name - Get attached device handler's name * @q - Request queue that is associated with the scsi_device * that may have a device handler attached * @gfp - the GFP mask used in the kmalloc() call when allocating memory * * Returns name of attached handler, NULL if no handler is attached. * Caller must take care to free the returned string.
*/ constchar *scsi_dh_attached_handler_name(struct request_queue *q, gfp_t gfp)
{ struct scsi_device *sdev; constchar *handler_name = NULL;
sdev = scsi_device_from_queue(q); if (!sdev) return NULL;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.