diff options
| -rw-r--r-- | drivers/target/target_core_cdb.c | 95 |
1 files changed, 47 insertions, 48 deletions
diff --git a/drivers/target/target_core_cdb.c b/drivers/target/target_core_cdb.c index 09ef3f811567..1157e0c6dba6 100644 --- a/drivers/target/target_core_cdb.c +++ b/drivers/target/target_core_cdb.c | |||
| @@ -114,31 +114,6 @@ target_emulate_inquiry_std(struct se_cmd *cmd) | |||
| 114 | return 0; | 114 | return 0; |
| 115 | } | 115 | } |
| 116 | 116 | ||
| 117 | /* supported vital product data pages */ | ||
| 118 | static int | ||
| 119 | target_emulate_evpd_00(struct se_cmd *cmd, unsigned char *buf) | ||
| 120 | { | ||
| 121 | buf[1] = 0x00; | ||
| 122 | if (cmd->data_length < 8) | ||
| 123 | return 0; | ||
| 124 | |||
| 125 | buf[4] = 0x0; | ||
| 126 | /* | ||
| 127 | * Only report the INQUIRY EVPD=1 pages after a valid NAA | ||
| 128 | * Registered Extended LUN WWN has been set via ConfigFS | ||
| 129 | * during device creation/restart. | ||
| 130 | */ | ||
| 131 | if (cmd->se_dev->se_sub_dev->su_dev_flags & | ||
| 132 | SDF_EMULATED_VPD_UNIT_SERIAL) { | ||
| 133 | buf[3] = 3; | ||
| 134 | buf[5] = 0x80; | ||
| 135 | buf[6] = 0x83; | ||
| 136 | buf[7] = 0x86; | ||
| 137 | } | ||
| 138 | |||
| 139 | return 0; | ||
| 140 | } | ||
| 141 | |||
| 142 | /* unit serial number */ | 117 | /* unit serial number */ |
| 143 | static int | 118 | static int |
| 144 | target_emulate_evpd_80(struct se_cmd *cmd, unsigned char *buf) | 119 | target_emulate_evpd_80(struct se_cmd *cmd, unsigned char *buf) |
| @@ -146,7 +121,6 @@ target_emulate_evpd_80(struct se_cmd *cmd, unsigned char *buf) | |||
| 146 | struct se_device *dev = cmd->se_dev; | 121 | struct se_device *dev = cmd->se_dev; |
| 147 | u16 len = 0; | 122 | u16 len = 0; |
| 148 | 123 | ||
| 149 | buf[1] = 0x80; | ||
| 150 | if (dev->se_sub_dev->su_dev_flags & | 124 | if (dev->se_sub_dev->su_dev_flags & |
| 151 | SDF_EMULATED_VPD_UNIT_SERIAL) { | 125 | SDF_EMULATED_VPD_UNIT_SERIAL) { |
| 152 | u32 unit_serial_len; | 126 | u32 unit_serial_len; |
| @@ -190,7 +164,6 @@ target_emulate_evpd_83(struct se_cmd *cmd, unsigned char *buf) | |||
| 190 | int i; | 164 | int i; |
| 191 | u16 len = 0, id_len; | 165 | u16 len = 0, id_len; |
| 192 | 166 | ||
| 193 | buf[1] = 0x83; | ||
| 194 | off = 4; | 167 | off = 4; |
| 195 | 168 | ||
| 196 | /* | 169 | /* |
| @@ -471,7 +444,6 @@ target_emulate_evpd_86(struct se_cmd *cmd, unsigned char *buf) | |||
| 471 | if (cmd->data_length < 60) | 444 | if (cmd->data_length < 60) |
| 472 | return 0; | 445 | return 0; |
| 473 | 446 | ||
| 474 | buf[1] = 0x86; | ||
| 475 | buf[2] = 0x3c; | 447 | buf[2] = 0x3c; |
| 476 | /* Set HEADSUP, ORDSUP, SIMPSUP */ | 448 | /* Set HEADSUP, ORDSUP, SIMPSUP */ |
| 477 | buf[5] = 0x07; | 449 | buf[5] = 0x07; |
| @@ -512,7 +484,6 @@ target_emulate_evpd_b0(struct se_cmd *cmd, unsigned char *buf) | |||
| 512 | } | 484 | } |
| 513 | 485 | ||
| 514 | buf[0] = dev->transport->get_device_type(dev); | 486 | buf[0] = dev->transport->get_device_type(dev); |
| 515 | buf[1] = 0xb0; | ||
| 516 | buf[3] = have_tp ? 0x3c : 0x10; | 487 | buf[3] = have_tp ? 0x3c : 0x10; |
| 517 | 488 | ||
| 518 | /* | 489 | /* |
| @@ -579,7 +550,6 @@ target_emulate_evpd_b2(struct se_cmd *cmd, unsigned char *buf) | |||
| 579 | * defined in table 162. | 550 | * defined in table 162. |
| 580 | */ | 551 | */ |
| 581 | buf[0] = dev->transport->get_device_type(dev); | 552 | buf[0] = dev->transport->get_device_type(dev); |
| 582 | buf[1] = 0xb2; | ||
| 583 | 553 | ||
| 584 | /* | 554 | /* |
| 585 | * Set Hardcoded length mentioned above for DP=0 | 555 | * Set Hardcoded length mentioned above for DP=0 |
| @@ -618,11 +588,51 @@ target_emulate_evpd_b2(struct se_cmd *cmd, unsigned char *buf) | |||
| 618 | } | 588 | } |
| 619 | 589 | ||
| 620 | static int | 590 | static int |
| 591 | target_emulate_evpd_00(struct se_cmd *cmd, unsigned char *buf); | ||
| 592 | |||
| 593 | static struct { | ||
| 594 | uint8_t page; | ||
| 595 | int (*emulate)(struct se_cmd *, unsigned char *); | ||
| 596 | } evpd_handlers[] = { | ||
| 597 | { .page = 0x00, .emulate = target_emulate_evpd_00 }, | ||
| 598 | { .page = 0x80, .emulate = target_emulate_evpd_80 }, | ||
| 599 | { .page = 0x83, .emulate = target_emulate_evpd_83 }, | ||
| 600 | { .page = 0x86, .emulate = target_emulate_evpd_86 }, | ||
| 601 | { .page = 0xb0, .emulate = target_emulate_evpd_b0 }, | ||
| 602 | { .page = 0xb2, .emulate = target_emulate_evpd_b2 }, | ||
| 603 | }; | ||
| 604 | |||
| 605 | /* supported vital product data pages */ | ||
| 606 | static int | ||
| 607 | target_emulate_evpd_00(struct se_cmd *cmd, unsigned char *buf) | ||
| 608 | { | ||
| 609 | int p; | ||
| 610 | |||
| 611 | if (cmd->data_length < 8) | ||
| 612 | return 0; | ||
| 613 | /* | ||
| 614 | * Only report the INQUIRY EVPD=1 pages after a valid NAA | ||
| 615 | * Registered Extended LUN WWN has been set via ConfigFS | ||
| 616 | * during device creation/restart. | ||
| 617 | */ | ||
| 618 | if (cmd->se_dev->se_sub_dev->su_dev_flags & | ||
| 619 | SDF_EMULATED_VPD_UNIT_SERIAL) { | ||
| 620 | buf[3] = ARRAY_SIZE(evpd_handlers); | ||
| 621 | for (p = 0; p < min_t(int, ARRAY_SIZE(evpd_handlers), | ||
| 622 | cmd->data_length - 4); ++p) | ||
| 623 | buf[p + 4] = evpd_handlers[p].page; | ||
| 624 | } | ||
| 625 | |||
| 626 | return 0; | ||
| 627 | } | ||
| 628 | |||
| 629 | static int | ||
| 621 | target_emulate_inquiry(struct se_cmd *cmd) | 630 | target_emulate_inquiry(struct se_cmd *cmd) |
| 622 | { | 631 | { |
| 623 | struct se_device *dev = cmd->se_dev; | 632 | struct se_device *dev = cmd->se_dev; |
| 624 | unsigned char *buf = cmd->t_task_buf; | 633 | unsigned char *buf = cmd->t_task_buf; |
| 625 | unsigned char *cdb = cmd->t_task_cdb; | 634 | unsigned char *cdb = cmd->t_task_cdb; |
| 635 | int p; | ||
| 626 | 636 | ||
| 627 | if (!(cdb[1] & 0x1)) | 637 | if (!(cdb[1] & 0x1)) |
| 628 | return target_emulate_inquiry_std(cmd); | 638 | return target_emulate_inquiry_std(cmd); |
| @@ -641,25 +651,14 @@ target_emulate_inquiry(struct se_cmd *cmd) | |||
| 641 | } | 651 | } |
| 642 | buf[0] = dev->transport->get_device_type(dev); | 652 | buf[0] = dev->transport->get_device_type(dev); |
| 643 | 653 | ||
| 644 | switch (cdb[2]) { | 654 | for (p = 0; p < ARRAY_SIZE(evpd_handlers); ++p) |
| 645 | case 0x00: | 655 | if (cdb[2] == evpd_handlers[p].page) { |
| 646 | return target_emulate_evpd_00(cmd, buf); | 656 | buf[1] = cdb[2]; |
| 647 | case 0x80: | 657 | return evpd_handlers[p].emulate(cmd, buf); |
| 648 | return target_emulate_evpd_80(cmd, buf); | 658 | } |
| 649 | case 0x83: | ||
| 650 | return target_emulate_evpd_83(cmd, buf); | ||
| 651 | case 0x86: | ||
| 652 | return target_emulate_evpd_86(cmd, buf); | ||
| 653 | case 0xb0: | ||
| 654 | return target_emulate_evpd_b0(cmd, buf); | ||
| 655 | case 0xb2: | ||
| 656 | return target_emulate_evpd_b2(cmd, buf); | ||
| 657 | default: | ||
| 658 | printk(KERN_ERR "Unknown VPD Code: 0x%02x\n", cdb[2]); | ||
| 659 | return -EINVAL; | ||
| 660 | } | ||
| 661 | 659 | ||
| 662 | return 0; | 660 | printk(KERN_ERR "Unknown VPD Code: 0x%02x\n", cdb[2]); |
| 661 | return -EINVAL; | ||
| 663 | } | 662 | } |
| 664 | 663 | ||
| 665 | static int | 664 | static int |
