23 #include <linux/slab.h>
24 #include <linux/module.h>
25 #include <scsi/scsi.h>
30 #define CLARIION_NAME "emc"
32 #define CLARIION_TRESPASS_PAGE 0x22
33 #define CLARIION_BUFFER_SIZE 0xFC
34 #define CLARIION_TIMEOUT (60 * HZ)
35 #define CLARIION_RETRIES 3
36 #define CLARIION_UNBOUND_LU -1
37 #define CLARIION_SP_A 0
38 #define CLARIION_SP_B 1
41 #define CLARIION_SHORT_TRESPASS 1
42 #define CLARIION_HONOR_RESERVATIONS 2
45 #define CLARIION_LUN_UNINITIALIZED -1
46 #define CLARIION_LUN_UNBOUND 0
47 #define CLARIION_LUN_BOUND 1
48 #define CLARIION_LUN_OWNED 2
50 static unsigned char long_trespass[] = {
51 0, 0, 0, 0, 0, 0, 0, 0,
59 static unsigned char short_trespass[] = {
67 static const char * lun_state[] =
134 "0x%2x, 0x%2x while sending CLARiiON trespass "
136 sshdr.asc, sshdr.ascq);
138 if ((sshdr.sense_key == 0x05) && (sshdr.asc == 0x04) &&
139 (sshdr.ascq == 0x00)) {
145 "progress while sending CLARiiON trespass "
148 }
else if ((sshdr.sense_key == 0x02) && (sshdr.asc == 0x04) &&
149 (sshdr.ascq == 0x03)) {
155 "ucode upgrade NDU operation while sending "
162 "%s: failed to send MODE SELECT, no sense available\n",
168 static int parse_sp_info_reply(
struct scsi_device *sdev,
174 if (csdev->
buffer[48] != 0) {
176 "ucode upgrade NDU operation while finding "
181 if (csdev->
buffer[4] > 2) {
184 "%s: invalid VPD page 0xC0 format\n",
189 switch (csdev->
buffer[28] & 0x0f) {
192 "%s: ALUA failover mode detected\n",
200 "%s: Invalid failover mode %d\n",
215 #define emc_default_str "FC (Legacy)"
219 unsigned char len = buffer[4] + 5;
220 char *sp_model =
NULL;
221 unsigned char sp_len, serial_len;
225 "%s: Invalid information section length %d\n",
228 if (!
strncmp(buffer + 8,
"DGC", 3)) {
238 serial_len = buffer[160];
239 if (serial_len == 0 || serial_len + 161 > len) {
241 "%s: Invalid array serial number length %d\n",
246 if (sp_len == 0 || serial_len + sp_len + 161 > len) {
248 "%s: Invalid model number length %d\n",
252 sp_model = &buffer[serial_len + 161];
254 while (sp_len > 1 && sp_model[sp_len - 1] ==
' ')
257 sp_model[sp_len] =
'\0';
288 len =
sizeof(short_trespass);
293 len =
sizeof(long_trespass);
307 rq->cmd_type = REQ_TYPE_BLOCK_PC;
330 rq->sense = csdev->
sense;
332 rq->sense_len = csdev->
senselen = 0;
342 "%s: failed to send %s INQUIRY: %x\n",
354 static int send_trespass_cmd(
struct scsi_device *sdev,
358 unsigned char *page22;
362 page22 = short_trespass;
366 len =
sizeof(short_trespass);
369 page22 = long_trespass;
373 len =
sizeof(long_trespass);
379 rq = get_req(sdev, cmd, csdev->
buffer);
383 rq->sense = csdev->
sense;
385 rq->sense_len = csdev->
senselen = 0;
390 err = trespass_endio(sdev, csdev->
sense);
393 "%s: failed to send MODE SELECT: %x\n",
403 static int clariion_check_sense(
struct scsi_device *sdev,
408 if (sense_hdr->
asc == 0x04 && sense_hdr->
ascq == 0x03)
425 if (sense_hdr->
asc == 0x25 && sense_hdr->
ascq == 0x01)
439 if (sense_hdr->
asc == 0x29 && sense_hdr->
ascq == 0x00)
454 int ret = BLKPREP_OK;
464 static int clariion_std_inquiry(
struct scsi_device *sdev,
470 err = send_inquiry_cmd(sdev, 0, csdev);
478 sshdr.sense_key, sshdr.asc, sshdr.ascq);
484 sp_model = parse_sp_model(sdev, csdev->
buffer);
497 "%s: detected Clariion %s, flags %x\n",
503 static int clariion_send_inquiry(
struct scsi_device *sdev,
509 err = send_inquiry_cmd(sdev, 0xC0, csdev);
518 err = clariion_check_sense(sdev, &sshdr);
525 sshdr.sense_key, sshdr.asc, sshdr.ascq);
528 err = parse_sp_info_reply(sdev, csdev);
533 static int clariion_activate(
struct scsi_device *sdev,
539 result = clariion_send_inquiry(sdev, csdev);
546 result = send_trespass_cmd(sdev, csdev);
554 result = clariion_send_inquiry(sdev, csdev);
560 "%s: at SP %c Port %d (%s, default SP %c)\n",
578 unsigned int hr = 0,
st = 0,
argc;
592 if ((
sscanf(p,
"%u", &hr) != 1) || (hr > 1))
614 result = send_trespass_cmd(sdev, csdev);
619 result = clariion_send_inquiry(sdev, csdev);
632 static bool clariion_match(
struct scsi_device *sdev)
636 if (scsi_device_tpgs(sdev))
639 for (i = 0; clariion_dev_list[
i].
vendor; i++) {
650 static int clariion_bus_attach(
struct scsi_device *sdev);
651 static void clariion_bus_detach(
struct scsi_device *sdev);
656 .devlist = clariion_dev_list,
657 .attach = clariion_bus_attach,
658 .detach = clariion_bus_detach,
659 .check_sense = clariion_check_sense,
660 .activate = clariion_activate,
661 .prep_fn = clariion_prep_fn,
662 .set_params = clariion_set_params,
663 .match = clariion_match,
666 static int clariion_bus_attach(
struct scsi_device *sdev)
673 scsi_dh_data = kzalloc(
sizeof(*scsi_dh_data)
681 scsi_dh_data->
scsi_dh = &clariion_dh;
687 err = clariion_std_inquiry(sdev, h);
691 err = clariion_send_inquiry(sdev, h);
700 spin_unlock_irqrestore(sdev->
request_queue->queue_lock, flags);
703 "%s: connected to SP %c Port %d (%s, default SP %c)\n",
717 static void clariion_bus_detach(
struct scsi_device *sdev)
725 spin_unlock_irqrestore(sdev->
request_queue->queue_lock, flags);
734 static int __init clariion_init(
void)
745 static void __exit clariion_exit(
void)