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