scsi.c (1e3f720a67c29e145321ed9b4ef7a83e6416d201) | scsi.c (ccf1e0045eea8f98d60fc9327bcb14c958d2e4c7) |
---|---|
1/* 2 * scsi.c Copyright (C) 1992 Drew Eckhardt 3 * Copyright (C) 1993, 1994, 1995, 1999 Eric Youngdale 4 * Copyright (C) 2002, 2003 Christoph Hellwig 5 * 6 * generic mid-level SCSI driver 7 * Initial versions: Drew Eckhardt 8 * Subsequent revisions: Eric Youngdale --- 401 unchanged lines hidden (view full) --- 410 return -EINVAL; 411} 412EXPORT_SYMBOL_GPL(scsi_get_vpd_page); 413 414/** 415 * scsi_get_vpd_buf - Get Vital Product Data from a SCSI device 416 * @sdev: The device to ask 417 * @page: Which Vital Product Data to return | 1/* 2 * scsi.c Copyright (C) 1992 Drew Eckhardt 3 * Copyright (C) 1993, 1994, 1995, 1999 Eric Youngdale 4 * Copyright (C) 2002, 2003 Christoph Hellwig 5 * 6 * generic mid-level SCSI driver 7 * Initial versions: Drew Eckhardt 8 * Subsequent revisions: Eric Youngdale --- 401 unchanged lines hidden (view full) --- 410 return -EINVAL; 411} 412EXPORT_SYMBOL_GPL(scsi_get_vpd_page); 413 414/** 415 * scsi_get_vpd_buf - Get Vital Product Data from a SCSI device 416 * @sdev: The device to ask 417 * @page: Which Vital Product Data to return |
418 * @len: Upon success, the VPD length will be stored in *@len. | |
419 * 420 * Returns %NULL upon failure. 421 */ | 418 * 419 * Returns %NULL upon failure. 420 */ |
422static unsigned char *scsi_get_vpd_buf(struct scsi_device *sdev, u8 page, 423 int *len) | 421static struct scsi_vpd *scsi_get_vpd_buf(struct scsi_device *sdev, u8 page) |
424{ | 422{ |
425 unsigned char *vpd_buf; | 423 struct scsi_vpd *vpd_buf; |
426 int vpd_len = SCSI_VPD_PG_LEN, result; 427 428retry_pg: | 424 int vpd_len = SCSI_VPD_PG_LEN, result; 425 426retry_pg: |
429 vpd_buf = kmalloc(vpd_len, GFP_KERNEL); | 427 vpd_buf = kmalloc(sizeof(*vpd_buf) + vpd_len, GFP_KERNEL); |
430 if (!vpd_buf) 431 return NULL; 432 | 428 if (!vpd_buf) 429 return NULL; 430 |
433 result = scsi_vpd_inquiry(sdev, vpd_buf, page, vpd_len); | 431 result = scsi_vpd_inquiry(sdev, vpd_buf->data, page, vpd_len); |
434 if (result < 0) { 435 kfree(vpd_buf); 436 return NULL; 437 } 438 if (result > vpd_len) { 439 vpd_len = result; 440 kfree(vpd_buf); 441 goto retry_pg; 442 } 443 | 432 if (result < 0) { 433 kfree(vpd_buf); 434 return NULL; 435 } 436 if (result > vpd_len) { 437 vpd_len = result; 438 kfree(vpd_buf); 439 goto retry_pg; 440 } 441 |
444 *len = result; | 442 vpd_buf->len = result; |
445 446 return vpd_buf; 447} 448 449static void scsi_update_vpd_page(struct scsi_device *sdev, u8 page, | 443 444 return vpd_buf; 445} 446 447static void scsi_update_vpd_page(struct scsi_device *sdev, u8 page, |
450 unsigned char __rcu **sdev_vpd_buf, 451 int *sdev_vpd_len) | 448 struct scsi_vpd __rcu **sdev_vpd_buf) |
452{ | 449{ |
453 unsigned char *vpd_buf; 454 int len; | 450 struct scsi_vpd *vpd_buf; |
455 | 451 |
456 vpd_buf = scsi_get_vpd_buf(sdev, page, &len); | 452 vpd_buf = scsi_get_vpd_buf(sdev, page); |
457 if (!vpd_buf) 458 return; 459 460 mutex_lock(&sdev->inquiry_mutex); 461 rcu_swap_protected(*sdev_vpd_buf, vpd_buf, 462 lockdep_is_held(&sdev->inquiry_mutex)); | 453 if (!vpd_buf) 454 return; 455 456 mutex_lock(&sdev->inquiry_mutex); 457 rcu_swap_protected(*sdev_vpd_buf, vpd_buf, 458 lockdep_is_held(&sdev->inquiry_mutex)); |
463 *sdev_vpd_len = len; | |
464 mutex_unlock(&sdev->inquiry_mutex); 465 | 459 mutex_unlock(&sdev->inquiry_mutex); 460 |
466 synchronize_rcu(); 467 468 kfree(vpd_buf); | 461 if (vpd_buf) 462 kfree_rcu(vpd_buf, rcu); |
469} 470 471/** 472 * scsi_attach_vpd - Attach Vital Product Data to a SCSI device structure 473 * @sdev: The device to ask 474 * 475 * Attach the 'Device Identification' VPD page (0x83) and the 476 * 'Unit Serial Number' VPD page (0x80) to a SCSI device 477 * structure. This information can be used to identify the device 478 * uniquely. 479 */ 480void scsi_attach_vpd(struct scsi_device *sdev) 481{ | 463} 464 465/** 466 * scsi_attach_vpd - Attach Vital Product Data to a SCSI device structure 467 * @sdev: The device to ask 468 * 469 * Attach the 'Device Identification' VPD page (0x83) and the 470 * 'Unit Serial Number' VPD page (0x80) to a SCSI device 471 * structure. This information can be used to identify the device 472 * uniquely. 473 */ 474void scsi_attach_vpd(struct scsi_device *sdev) 475{ |
482 int i, vpd_len; 483 unsigned char *vpd_buf; | 476 int i; 477 struct scsi_vpd *vpd_buf; |
484 485 if (!scsi_device_supports_vpd(sdev)) 486 return; 487 488 /* Ask for all the pages supported by this device */ | 478 479 if (!scsi_device_supports_vpd(sdev)) 480 return; 481 482 /* Ask for all the pages supported by this device */ |
489 vpd_buf = scsi_get_vpd_buf(sdev, 0, &vpd_len); | 483 vpd_buf = scsi_get_vpd_buf(sdev, 0); |
490 if (!vpd_buf) 491 return; 492 | 484 if (!vpd_buf) 485 return; 486 |
493 for (i = 4; i < vpd_len; i++) { 494 if (vpd_buf[i] == 0x80) 495 scsi_update_vpd_page(sdev, 0x80, &sdev->vpd_pg80, 496 &sdev->vpd_pg80_len); 497 if (vpd_buf[i] == 0x83) 498 scsi_update_vpd_page(sdev, 0x83, &sdev->vpd_pg83, 499 &sdev->vpd_pg83_len); | 487 for (i = 4; i < vpd_buf->len; i++) { 488 if (vpd_buf->data[i] == 0x80) 489 scsi_update_vpd_page(sdev, 0x80, &sdev->vpd_pg80); 490 if (vpd_buf->data[i] == 0x83) 491 scsi_update_vpd_page(sdev, 0x83, &sdev->vpd_pg83); |
500 } 501 kfree(vpd_buf); 502} 503 504/** 505 * scsi_report_opcode - Find out if a given command opcode is supported 506 * @sdev: scsi device to query 507 * @buffer: scratch buffer (must be at least 20 bytes long) --- 343 unchanged lines hidden --- | 492 } 493 kfree(vpd_buf); 494} 495 496/** 497 * scsi_report_opcode - Find out if a given command opcode is supported 498 * @sdev: scsi device to query 499 * @buffer: scratch buffer (must be at least 20 bytes long) --- 343 unchanged lines hidden --- |