aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Jones <pjones@redhat.com>2011-01-06 15:31:29 -0500
committerJames Bottomley <James.Bottomley@suse.de>2011-01-24 13:01:07 -0500
commit38a039be2e7bda32517642ecfce54c9317292a9c (patch)
tree2eb828510c3ee4a40295d73f4414fd8f9625128c
parent716163ff908be72f6b74752ad0796cc7c00b047a (diff)
[SCSI] Add scsi_dev_info_list_del_keyed()
For scsi_dh.c to use devinfo lists, we have to be able to remove entries before rmmod. Signed-off-by: James Bottomley <James.Bottomley@suse.de>
-rw-r--r--drivers/scsi/scsi_devinfo.c85
-rw-r--r--drivers/scsi/scsi_priv.h1
2 files changed, 86 insertions, 0 deletions
diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c
index 43fad4c09beb..82e9e5c0476e 100644
--- a/drivers/scsi/scsi_devinfo.c
+++ b/drivers/scsi/scsi_devinfo.c
@@ -382,6 +382,91 @@ int scsi_dev_info_list_add_keyed(int compatible, char *vendor, char *model,
382EXPORT_SYMBOL(scsi_dev_info_list_add_keyed); 382EXPORT_SYMBOL(scsi_dev_info_list_add_keyed);
383 383
384/** 384/**
385 * scsi_dev_info_list_del_keyed - remove one dev_info list entry.
386 * @vendor: vendor string
387 * @model: model (product) string
388 * @key: specify list to use
389 *
390 * Description:
391 * Remove and destroy one dev_info entry for @vendor, @model
392 * in list specified by @key.
393 *
394 * Returns: 0 OK, -error on failure.
395 **/
396int scsi_dev_info_list_del_keyed(char *vendor, char *model, int key)
397{
398 struct scsi_dev_info_list *devinfo, *found = NULL;
399 struct scsi_dev_info_list_table *devinfo_table =
400 scsi_devinfo_lookup_by_key(key);
401
402 if (IS_ERR(devinfo_table))
403 return PTR_ERR(devinfo_table);
404
405 list_for_each_entry(devinfo, &devinfo_table->scsi_dev_info_list,
406 dev_info_list) {
407 if (devinfo->compatible) {
408 /*
409 * Behave like the older version of get_device_flags.
410 */
411 size_t max;
412 /*
413 * XXX why skip leading spaces? If an odd INQUIRY
414 * value, that should have been part of the
415 * scsi_static_device_list[] entry, such as " FOO"
416 * rather than "FOO". Since this code is already
417 * here, and we don't know what device it is
418 * trying to work with, leave it as-is.
419 */
420 max = 8; /* max length of vendor */
421 while ((max > 0) && *vendor == ' ') {
422 max--;
423 vendor++;
424 }
425 /*
426 * XXX removing the following strlen() would be
427 * good, using it means that for a an entry not in
428 * the list, we scan every byte of every vendor
429 * listed in scsi_static_device_list[], and never match
430 * a single one (and still have to compare at
431 * least the first byte of each vendor).
432 */
433 if (memcmp(devinfo->vendor, vendor,
434 min(max, strlen(devinfo->vendor))))
435 continue;
436 /*
437 * Skip spaces again.
438 */
439 max = 16; /* max length of model */
440 while ((max > 0) && *model == ' ') {
441 max--;
442 model++;
443 }
444 if (memcmp(devinfo->model, model,
445 min(max, strlen(devinfo->model))))
446 continue;
447 found = devinfo;
448 } else {
449 if (!memcmp(devinfo->vendor, vendor,
450 sizeof(devinfo->vendor)) &&
451 !memcmp(devinfo->model, model,
452 sizeof(devinfo->model)))
453 found = devinfo;
454 }
455 if (found)
456 break;
457 }
458
459 if (found) {
460 list_del(&found->dev_info_list);
461 kfree(found);
462 return 0;
463 }
464
465 return -ENOENT;
466}
467EXPORT_SYMBOL(scsi_dev_info_list_del_keyed);
468
469/**
385 * scsi_dev_info_list_add_str - parse dev_list and add to the scsi_dev_info_list. 470 * scsi_dev_info_list_add_str - parse dev_list and add to the scsi_dev_info_list.
386 * @dev_list: string of device flags to add 471 * @dev_list: string of device flags to add
387 * 472 *
diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h
index b4056d14f812..ce9e0adc8df8 100644
--- a/drivers/scsi/scsi_priv.h
+++ b/drivers/scsi/scsi_priv.h
@@ -56,6 +56,7 @@ extern int scsi_get_device_flags_keyed(struct scsi_device *sdev,
56extern int scsi_dev_info_list_add_keyed(int compatible, char *vendor, 56extern int scsi_dev_info_list_add_keyed(int compatible, char *vendor,
57 char *model, char *strflags, 57 char *model, char *strflags,
58 int flags, int key); 58 int flags, int key);
59extern int scsi_dev_info_list_del_keyed(char *vendor, char *model, int key);
59extern int scsi_dev_info_add_list(int key, const char *name); 60extern int scsi_dev_info_add_list(int key, const char *name);
60extern int scsi_dev_info_remove_list(int key); 61extern int scsi_dev_info_remove_list(int key);
61 62