aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/target/target_core_cdb.c95
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 */
118static int
119target_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 */
143static int 118static int
144target_emulate_evpd_80(struct se_cmd *cmd, unsigned char *buf) 119target_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
620static int 590static int
591target_emulate_evpd_00(struct se_cmd *cmd, unsigned char *buf);
592
593static 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 */
606static int
607target_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
629static int
621target_emulate_inquiry(struct se_cmd *cmd) 630target_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
665static int 664static int