Linux Audio

Check our new training course

Loading...
v6.8
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2/*
  3 * SCSI device handler infrastructure.
  4 *
  5 * Copyright IBM Corporation, 2007
  6 *      Authors:
  7 *               Chandra Seetharaman <sekharan@us.ibm.com>
  8 *               Mike Anderson <andmike@linux.vnet.ibm.com>
  9 */
 10
 11#include <linux/slab.h>
 12#include <linux/module.h>
 13#include <scsi/scsi_dh.h>
 14#include "scsi_priv.h"
 15
 16static DEFINE_SPINLOCK(list_lock);
 17static LIST_HEAD(scsi_dh_list);
 18
 19struct scsi_dh_blist {
 20	const char *vendor;
 21	const char *model;
 22	const char *driver;
 23};
 24
 25static const struct scsi_dh_blist scsi_dh_blist[] = {
 26	{"DGC", "RAID",			"emc" },
 27	{"DGC", "DISK",			"emc" },
 28	{"DGC", "VRAID",		"emc" },
 29
 30	{"COMPAQ", "MSA1000 VOLUME",	"hp_sw" },
 31	{"COMPAQ", "HSV110",		"hp_sw" },
 32	{"HP", "HSV100",		"hp_sw"},
 33	{"DEC", "HSG80",		"hp_sw"},
 34
 35	{"IBM", "1722",			"rdac", },
 36	{"IBM", "1724",			"rdac", },
 37	{"IBM", "1726",			"rdac", },
 38	{"IBM", "1742",			"rdac", },
 39	{"IBM", "1745",			"rdac", },
 40	{"IBM", "1746",			"rdac", },
 41	{"IBM", "1813",			"rdac", },
 42	{"IBM", "1814",			"rdac", },
 43	{"IBM", "1815",			"rdac", },
 44	{"IBM", "1818",			"rdac", },
 45	{"IBM", "3526",			"rdac", },
 46	{"IBM", "3542",			"rdac", },
 47	{"IBM", "3552",			"rdac", },
 48	{"SGI", "TP9300",		"rdac", },
 49	{"SGI", "TP9400",		"rdac", },
 50	{"SGI", "TP9500",		"rdac", },
 51	{"SGI", "TP9700",		"rdac", },
 52	{"SGI", "IS",			"rdac", },
 53	{"STK", "OPENstorage",		"rdac", },
 54	{"STK", "FLEXLINE 380",		"rdac", },
 55	{"STK", "BladeCtlr",		"rdac", },
 56	{"SUN", "CSM",			"rdac", },
 57	{"SUN", "LCSM100",		"rdac", },
 58	{"SUN", "STK6580_6780",		"rdac", },
 59	{"SUN", "SUN_6180",		"rdac", },
 60	{"SUN", "ArrayStorage",		"rdac", },
 61	{"DELL", "MD3",			"rdac", },
 62	{"NETAPP", "INF-01-00",		"rdac", },
 63	{"LSI", "INF-01-00",		"rdac", },
 64	{"ENGENIO", "INF-01-00",	"rdac", },
 65	{"LENOVO", "DE_Series",		"rdac", },
 66	{"FUJITSU", "ETERNUS_AHB",	"rdac", },
 67	{NULL, NULL,			NULL },
 68};
 69
 70static const char *
 71scsi_dh_find_driver(struct scsi_device *sdev)
 72{
 73	const struct scsi_dh_blist *b;
 74
 75	if (scsi_device_tpgs(sdev))
 76		return "alua";
 77
 78	for (b = scsi_dh_blist; b->vendor; b++) {
 79		if (!strncmp(sdev->vendor, b->vendor, strlen(b->vendor)) &&
 80		    !strncmp(sdev->model, b->model, strlen(b->model))) {
 81			return b->driver;
 82		}
 83	}
 84	return NULL;
 85}
 86
 87
 88static struct scsi_device_handler *__scsi_dh_lookup(const char *name)
 89{
 90	struct scsi_device_handler *tmp, *found = NULL;
 91
 92	spin_lock(&list_lock);
 93	list_for_each_entry(tmp, &scsi_dh_list, list) {
 94		if (!strncmp(tmp->name, name, strlen(tmp->name))) {
 95			found = tmp;
 96			break;
 97		}
 98	}
 99	spin_unlock(&list_lock);
100	return found;
101}
102
103static struct scsi_device_handler *scsi_dh_lookup(const char *name)
104{
105	struct scsi_device_handler *dh;
106
107	if (!name || strlen(name) == 0)
108		return NULL;
109
110	dh = __scsi_dh_lookup(name);
111	if (!dh) {
112		request_module("scsi_dh_%s", name);
113		dh = __scsi_dh_lookup(name);
114	}
115
116	return dh;
117}
118
119/*
120 * scsi_dh_handler_attach - Attach a device handler to a device
121 * @sdev - SCSI device the device handler should attach to
122 * @scsi_dh - The device handler to attach
123 */
124static int scsi_dh_handler_attach(struct scsi_device *sdev,
125				  struct scsi_device_handler *scsi_dh)
126{
127	int error, ret = 0;
128
129	if (!try_module_get(scsi_dh->module))
130		return -EINVAL;
131
132	error = scsi_dh->attach(sdev);
133	if (error != SCSI_DH_OK) {
134		switch (error) {
135		case SCSI_DH_NOMEM:
136			ret = -ENOMEM;
137			break;
138		case SCSI_DH_RES_TEMP_UNAVAIL:
139			ret = -EAGAIN;
140			break;
141		case SCSI_DH_DEV_UNSUPP:
142		case SCSI_DH_NOSYS:
143			ret = -ENODEV;
144			break;
145		default:
146			ret = -EINVAL;
147			break;
148		}
149		if (ret != -ENODEV)
150			sdev_printk(KERN_ERR, sdev, "%s: Attach failed (%d)\n",
151				    scsi_dh->name, error);
152		module_put(scsi_dh->module);
153	} else
154		sdev->handler = scsi_dh;
155
156	return ret;
157}
158
159/*
160 * scsi_dh_handler_detach - Detach a device handler from a device
161 * @sdev - SCSI device the device handler should be detached from
162 */
163static void scsi_dh_handler_detach(struct scsi_device *sdev)
164{
165	sdev->handler->detach(sdev);
166	sdev_printk(KERN_NOTICE, sdev, "%s: Detached\n", sdev->handler->name);
167	module_put(sdev->handler->module);
168}
169
170void scsi_dh_add_device(struct scsi_device *sdev)
171{
172	struct scsi_device_handler *devinfo = NULL;
173	const char *drv;
174
175	drv = scsi_dh_find_driver(sdev);
176	if (drv)
177		devinfo = __scsi_dh_lookup(drv);
178	/*
179	 * device_handler is optional, so ignore errors
180	 * from scsi_dh_handler_attach()
181	 */
182	if (devinfo)
183		(void)scsi_dh_handler_attach(sdev, devinfo);
184}
185
186void scsi_dh_release_device(struct scsi_device *sdev)
187{
188	if (sdev->handler)
189		scsi_dh_handler_detach(sdev);
190}
191
192/*
193 * scsi_register_device_handler - register a device handler personality
194 *      module.
195 * @scsi_dh - device handler to be registered.
196 *
197 * Returns 0 on success, -EBUSY if handler already registered.
198 */
199int scsi_register_device_handler(struct scsi_device_handler *scsi_dh)
200{
201	if (__scsi_dh_lookup(scsi_dh->name))
202		return -EBUSY;
203
204	if (!scsi_dh->attach || !scsi_dh->detach)
205		return -EINVAL;
206
207	spin_lock(&list_lock);
208	list_add(&scsi_dh->list, &scsi_dh_list);
209	spin_unlock(&list_lock);
210
211	printk(KERN_INFO "%s: device handler registered\n", scsi_dh->name);
212
213	return SCSI_DH_OK;
214}
215EXPORT_SYMBOL_GPL(scsi_register_device_handler);
216
217/*
218 * scsi_unregister_device_handler - register a device handler personality
219 *      module.
220 * @scsi_dh - device handler to be unregistered.
221 *
222 * Returns 0 on success, -ENODEV if handler not registered.
223 */
224int scsi_unregister_device_handler(struct scsi_device_handler *scsi_dh)
225{
226	if (!__scsi_dh_lookup(scsi_dh->name))
227		return -ENODEV;
228
229	spin_lock(&list_lock);
230	list_del(&scsi_dh->list);
231	spin_unlock(&list_lock);
232	printk(KERN_INFO "%s: device handler unregistered\n", scsi_dh->name);
233
234	return SCSI_DH_OK;
235}
236EXPORT_SYMBOL_GPL(scsi_unregister_device_handler);
237
238/*
239 * scsi_dh_activate - activate the path associated with the scsi_device
240 *      corresponding to the given request queue.
241 *     Returns immediately without waiting for activation to be completed.
242 * @q    - Request queue that is associated with the scsi_device to be
243 *         activated.
244 * @fn   - Function to be called upon completion of the activation.
245 *         Function fn is called with data (below) and the error code.
246 *         Function fn may be called from the same calling context. So,
247 *         do not hold the lock in the caller which may be needed in fn.
248 * @data - data passed to the function fn upon completion.
249 *
250 */
251int scsi_dh_activate(struct request_queue *q, activate_complete fn, void *data)
252{
253	struct scsi_device *sdev;
254	int err = SCSI_DH_NOSYS;
255
256	sdev = scsi_device_from_queue(q);
257	if (!sdev) {
258		if (fn)
259			fn(data, err);
260		return err;
261	}
262
263	if (!sdev->handler)
264		goto out_fn;
265	err = SCSI_DH_NOTCONN;
266	if (sdev->sdev_state == SDEV_CANCEL ||
267	    sdev->sdev_state == SDEV_DEL)
268		goto out_fn;
269
270	err = SCSI_DH_DEV_OFFLINED;
271	if (sdev->sdev_state == SDEV_OFFLINE)
272		goto out_fn;
273
274	if (sdev->handler->activate)
275		err = sdev->handler->activate(sdev, fn, data);
276
277out_put_device:
278	put_device(&sdev->sdev_gendev);
279	return err;
280
281out_fn:
282	if (fn)
283		fn(data, err);
284	goto out_put_device;
285}
286EXPORT_SYMBOL_GPL(scsi_dh_activate);
287
288/*
289 * scsi_dh_set_params - set the parameters for the device as per the
290 *      string specified in params.
291 * @q - Request queue that is associated with the scsi_device for
292 *      which the parameters to be set.
293 * @params - parameters in the following format
294 *      "no_of_params\0param1\0param2\0param3\0...\0"
295 *      for example, string for 2 parameters with value 10 and 21
296 *      is specified as "2\010\021\0".
297 */
298int scsi_dh_set_params(struct request_queue *q, const char *params)
299{
300	struct scsi_device *sdev;
301	int err = -SCSI_DH_NOSYS;
302
303	sdev = scsi_device_from_queue(q);
304	if (!sdev)
305		return err;
306
307	if (sdev->handler && sdev->handler->set_params)
308		err = sdev->handler->set_params(sdev, params);
309	put_device(&sdev->sdev_gendev);
310	return err;
311}
312EXPORT_SYMBOL_GPL(scsi_dh_set_params);
313
314/*
315 * scsi_dh_attach - Attach device handler
316 * @q - Request queue that is associated with the scsi_device
317 *      the handler should be attached to
318 * @name - name of the handler to attach
319 */
320int scsi_dh_attach(struct request_queue *q, const char *name)
321{
322	struct scsi_device *sdev;
323	struct scsi_device_handler *scsi_dh;
324	int err = 0;
325
326	sdev = scsi_device_from_queue(q);
327	if (!sdev)
328		return -ENODEV;
329
330	scsi_dh = scsi_dh_lookup(name);
331	if (!scsi_dh) {
332		err = -EINVAL;
333		goto out_put_device;
334	}
335
336	if (sdev->handler) {
337		if (sdev->handler != scsi_dh)
338			err = -EBUSY;
339		goto out_put_device;
340	}
341
342	err = scsi_dh_handler_attach(sdev, scsi_dh);
343
344out_put_device:
345	put_device(&sdev->sdev_gendev);
346	return err;
347}
348EXPORT_SYMBOL_GPL(scsi_dh_attach);
349
350/*
351 * scsi_dh_attached_handler_name - Get attached device handler's name
352 * @q - Request queue that is associated with the scsi_device
353 *      that may have a device handler attached
354 * @gfp - the GFP mask used in the kmalloc() call when allocating memory
355 *
356 * Returns name of attached handler, NULL if no handler is attached.
357 * Caller must take care to free the returned string.
358 */
359const char *scsi_dh_attached_handler_name(struct request_queue *q, gfp_t gfp)
360{
361	struct scsi_device *sdev;
362	const char *handler_name = NULL;
363
364	sdev = scsi_device_from_queue(q);
365	if (!sdev)
366		return NULL;
367
368	if (sdev->handler)
369		handler_name = kstrdup(sdev->handler->name, gfp);
370	put_device(&sdev->sdev_gendev);
371	return handler_name;
372}
373EXPORT_SYMBOL_GPL(scsi_dh_attached_handler_name);
v6.2
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2/*
  3 * SCSI device handler infrastructure.
  4 *
  5 * Copyright IBM Corporation, 2007
  6 *      Authors:
  7 *               Chandra Seetharaman <sekharan@us.ibm.com>
  8 *               Mike Anderson <andmike@linux.vnet.ibm.com>
  9 */
 10
 11#include <linux/slab.h>
 12#include <linux/module.h>
 13#include <scsi/scsi_dh.h>
 14#include "scsi_priv.h"
 15
 16static DEFINE_SPINLOCK(list_lock);
 17static LIST_HEAD(scsi_dh_list);
 18
 19struct scsi_dh_blist {
 20	const char *vendor;
 21	const char *model;
 22	const char *driver;
 23};
 24
 25static const struct scsi_dh_blist scsi_dh_blist[] = {
 26	{"DGC", "RAID",			"emc" },
 27	{"DGC", "DISK",			"emc" },
 28	{"DGC", "VRAID",		"emc" },
 29
 30	{"COMPAQ", "MSA1000 VOLUME",	"hp_sw" },
 31	{"COMPAQ", "HSV110",		"hp_sw" },
 32	{"HP", "HSV100",		"hp_sw"},
 33	{"DEC", "HSG80",		"hp_sw"},
 34
 35	{"IBM", "1722",			"rdac", },
 36	{"IBM", "1724",			"rdac", },
 37	{"IBM", "1726",			"rdac", },
 38	{"IBM", "1742",			"rdac", },
 39	{"IBM", "1745",			"rdac", },
 40	{"IBM", "1746",			"rdac", },
 41	{"IBM", "1813",			"rdac", },
 42	{"IBM", "1814",			"rdac", },
 43	{"IBM", "1815",			"rdac", },
 44	{"IBM", "1818",			"rdac", },
 45	{"IBM", "3526",			"rdac", },
 46	{"IBM", "3542",			"rdac", },
 47	{"IBM", "3552",			"rdac", },
 48	{"SGI", "TP9300",		"rdac", },
 49	{"SGI", "TP9400",		"rdac", },
 50	{"SGI", "TP9500",		"rdac", },
 51	{"SGI", "TP9700",		"rdac", },
 52	{"SGI", "IS",			"rdac", },
 53	{"STK", "OPENstorage",		"rdac", },
 54	{"STK", "FLEXLINE 380",		"rdac", },
 55	{"STK", "BladeCtlr",		"rdac", },
 56	{"SUN", "CSM",			"rdac", },
 57	{"SUN", "LCSM100",		"rdac", },
 58	{"SUN", "STK6580_6780",		"rdac", },
 59	{"SUN", "SUN_6180",		"rdac", },
 60	{"SUN", "ArrayStorage",		"rdac", },
 61	{"DELL", "MD3",			"rdac", },
 62	{"NETAPP", "INF-01-00",		"rdac", },
 63	{"LSI", "INF-01-00",		"rdac", },
 64	{"ENGENIO", "INF-01-00",	"rdac", },
 65	{"LENOVO", "DE_Series",		"rdac", },
 66	{"FUJITSU", "ETERNUS_AHB",	"rdac", },
 67	{NULL, NULL,			NULL },
 68};
 69
 70static const char *
 71scsi_dh_find_driver(struct scsi_device *sdev)
 72{
 73	const struct scsi_dh_blist *b;
 74
 75	if (scsi_device_tpgs(sdev))
 76		return "alua";
 77
 78	for (b = scsi_dh_blist; b->vendor; b++) {
 79		if (!strncmp(sdev->vendor, b->vendor, strlen(b->vendor)) &&
 80		    !strncmp(sdev->model, b->model, strlen(b->model))) {
 81			return b->driver;
 82		}
 83	}
 84	return NULL;
 85}
 86
 87
 88static struct scsi_device_handler *__scsi_dh_lookup(const char *name)
 89{
 90	struct scsi_device_handler *tmp, *found = NULL;
 91
 92	spin_lock(&list_lock);
 93	list_for_each_entry(tmp, &scsi_dh_list, list) {
 94		if (!strncmp(tmp->name, name, strlen(tmp->name))) {
 95			found = tmp;
 96			break;
 97		}
 98	}
 99	spin_unlock(&list_lock);
100	return found;
101}
102
103static struct scsi_device_handler *scsi_dh_lookup(const char *name)
104{
105	struct scsi_device_handler *dh;
106
107	if (!name || strlen(name) == 0)
108		return NULL;
109
110	dh = __scsi_dh_lookup(name);
111	if (!dh) {
112		request_module("scsi_dh_%s", name);
113		dh = __scsi_dh_lookup(name);
114	}
115
116	return dh;
117}
118
119/*
120 * scsi_dh_handler_attach - Attach a device handler to a device
121 * @sdev - SCSI device the device handler should attach to
122 * @scsi_dh - The device handler to attach
123 */
124static int scsi_dh_handler_attach(struct scsi_device *sdev,
125				  struct scsi_device_handler *scsi_dh)
126{
127	int error, ret = 0;
128
129	if (!try_module_get(scsi_dh->module))
130		return -EINVAL;
131
132	error = scsi_dh->attach(sdev);
133	if (error != SCSI_DH_OK) {
134		switch (error) {
135		case SCSI_DH_NOMEM:
136			ret = -ENOMEM;
137			break;
138		case SCSI_DH_RES_TEMP_UNAVAIL:
139			ret = -EAGAIN;
140			break;
141		case SCSI_DH_DEV_UNSUPP:
142		case SCSI_DH_NOSYS:
143			ret = -ENODEV;
144			break;
145		default:
146			ret = -EINVAL;
147			break;
148		}
149		if (ret != -ENODEV)
150			sdev_printk(KERN_ERR, sdev, "%s: Attach failed (%d)\n",
151				    scsi_dh->name, error);
152		module_put(scsi_dh->module);
153	} else
154		sdev->handler = scsi_dh;
155
156	return ret;
157}
158
159/*
160 * scsi_dh_handler_detach - Detach a device handler from a device
161 * @sdev - SCSI device the device handler should be detached from
162 */
163static void scsi_dh_handler_detach(struct scsi_device *sdev)
164{
165	sdev->handler->detach(sdev);
166	sdev_printk(KERN_NOTICE, sdev, "%s: Detached\n", sdev->handler->name);
167	module_put(sdev->handler->module);
168}
169
170void scsi_dh_add_device(struct scsi_device *sdev)
171{
172	struct scsi_device_handler *devinfo = NULL;
173	const char *drv;
174
175	drv = scsi_dh_find_driver(sdev);
176	if (drv)
177		devinfo = __scsi_dh_lookup(drv);
178	/*
179	 * device_handler is optional, so ignore errors
180	 * from scsi_dh_handler_attach()
181	 */
182	if (devinfo)
183		(void)scsi_dh_handler_attach(sdev, devinfo);
184}
185
186void scsi_dh_release_device(struct scsi_device *sdev)
187{
188	if (sdev->handler)
189		scsi_dh_handler_detach(sdev);
190}
191
192/*
193 * scsi_register_device_handler - register a device handler personality
194 *      module.
195 * @scsi_dh - device handler to be registered.
196 *
197 * Returns 0 on success, -EBUSY if handler already registered.
198 */
199int scsi_register_device_handler(struct scsi_device_handler *scsi_dh)
200{
201	if (__scsi_dh_lookup(scsi_dh->name))
202		return -EBUSY;
203
204	if (!scsi_dh->attach || !scsi_dh->detach)
205		return -EINVAL;
206
207	spin_lock(&list_lock);
208	list_add(&scsi_dh->list, &scsi_dh_list);
209	spin_unlock(&list_lock);
210
211	printk(KERN_INFO "%s: device handler registered\n", scsi_dh->name);
212
213	return SCSI_DH_OK;
214}
215EXPORT_SYMBOL_GPL(scsi_register_device_handler);
216
217/*
218 * scsi_unregister_device_handler - register a device handler personality
219 *      module.
220 * @scsi_dh - device handler to be unregistered.
221 *
222 * Returns 0 on success, -ENODEV if handler not registered.
223 */
224int scsi_unregister_device_handler(struct scsi_device_handler *scsi_dh)
225{
226	if (!__scsi_dh_lookup(scsi_dh->name))
227		return -ENODEV;
228
229	spin_lock(&list_lock);
230	list_del(&scsi_dh->list);
231	spin_unlock(&list_lock);
232	printk(KERN_INFO "%s: device handler unregistered\n", scsi_dh->name);
233
234	return SCSI_DH_OK;
235}
236EXPORT_SYMBOL_GPL(scsi_unregister_device_handler);
237
238/*
239 * scsi_dh_activate - activate the path associated with the scsi_device
240 *      corresponding to the given request queue.
241 *     Returns immediately without waiting for activation to be completed.
242 * @q    - Request queue that is associated with the scsi_device to be
243 *         activated.
244 * @fn   - Function to be called upon completion of the activation.
245 *         Function fn is called with data (below) and the error code.
246 *         Function fn may be called from the same calling context. So,
247 *         do not hold the lock in the caller which may be needed in fn.
248 * @data - data passed to the function fn upon completion.
249 *
250 */
251int scsi_dh_activate(struct request_queue *q, activate_complete fn, void *data)
252{
253	struct scsi_device *sdev;
254	int err = SCSI_DH_NOSYS;
255
256	sdev = scsi_device_from_queue(q);
257	if (!sdev) {
258		if (fn)
259			fn(data, err);
260		return err;
261	}
262
263	if (!sdev->handler)
264		goto out_fn;
265	err = SCSI_DH_NOTCONN;
266	if (sdev->sdev_state == SDEV_CANCEL ||
267	    sdev->sdev_state == SDEV_DEL)
268		goto out_fn;
269
270	err = SCSI_DH_DEV_OFFLINED;
271	if (sdev->sdev_state == SDEV_OFFLINE)
272		goto out_fn;
273
274	if (sdev->handler->activate)
275		err = sdev->handler->activate(sdev, fn, data);
276
277out_put_device:
278	put_device(&sdev->sdev_gendev);
279	return err;
280
281out_fn:
282	if (fn)
283		fn(data, err);
284	goto out_put_device;
285}
286EXPORT_SYMBOL_GPL(scsi_dh_activate);
287
288/*
289 * scsi_dh_set_params - set the parameters for the device as per the
290 *      string specified in params.
291 * @q - Request queue that is associated with the scsi_device for
292 *      which the parameters to be set.
293 * @params - parameters in the following format
294 *      "no_of_params\0param1\0param2\0param3\0...\0"
295 *      for example, string for 2 parameters with value 10 and 21
296 *      is specified as "2\010\021\0".
297 */
298int scsi_dh_set_params(struct request_queue *q, const char *params)
299{
300	struct scsi_device *sdev;
301	int err = -SCSI_DH_NOSYS;
302
303	sdev = scsi_device_from_queue(q);
304	if (!sdev)
305		return err;
306
307	if (sdev->handler && sdev->handler->set_params)
308		err = sdev->handler->set_params(sdev, params);
309	put_device(&sdev->sdev_gendev);
310	return err;
311}
312EXPORT_SYMBOL_GPL(scsi_dh_set_params);
313
314/*
315 * scsi_dh_attach - Attach device handler
316 * @q - Request queue that is associated with the scsi_device
317 *      the handler should be attached to
318 * @name - name of the handler to attach
319 */
320int scsi_dh_attach(struct request_queue *q, const char *name)
321{
322	struct scsi_device *sdev;
323	struct scsi_device_handler *scsi_dh;
324	int err = 0;
325
326	sdev = scsi_device_from_queue(q);
327	if (!sdev)
328		return -ENODEV;
329
330	scsi_dh = scsi_dh_lookup(name);
331	if (!scsi_dh) {
332		err = -EINVAL;
333		goto out_put_device;
334	}
335
336	if (sdev->handler) {
337		if (sdev->handler != scsi_dh)
338			err = -EBUSY;
339		goto out_put_device;
340	}
341
342	err = scsi_dh_handler_attach(sdev, scsi_dh);
343
344out_put_device:
345	put_device(&sdev->sdev_gendev);
346	return err;
347}
348EXPORT_SYMBOL_GPL(scsi_dh_attach);
349
350/*
351 * scsi_dh_attached_handler_name - Get attached device handler's name
352 * @q - Request queue that is associated with the scsi_device
353 *      that may have a device handler attached
354 * @gfp - the GFP mask used in the kmalloc() call when allocating memory
355 *
356 * Returns name of attached handler, NULL if no handler is attached.
357 * Caller must take care to free the returned string.
358 */
359const char *scsi_dh_attached_handler_name(struct request_queue *q, gfp_t gfp)
360{
361	struct scsi_device *sdev;
362	const char *handler_name = NULL;
363
364	sdev = scsi_device_from_queue(q);
365	if (!sdev)
366		return NULL;
367
368	if (sdev->handler)
369		handler_name = kstrdup(sdev->handler->name, gfp);
370	put_device(&sdev->sdev_gendev);
371	return handler_name;
372}
373EXPORT_SYMBOL_GPL(scsi_dh_attached_handler_name);