aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/cciss_scsi.c
diff options
context:
space:
mode:
authorMike Miller <mike.miller@hp.com>2005-09-13 04:25:25 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-09-13 11:22:30 -0400
commit47922d068e90ed34c1336cdd39912d51e190f8a5 (patch)
tree7e19d44c078339428318054ebbadd00479d461cf /drivers/block/cciss_scsi.c
parentbb2a37bf4131d64b76dcdb126e3ff5bf371b1842 (diff)
[PATCH] cciss: One Button Disaster Recovery support
This patch adds support for "One Button Disaster Recovery" devices to the cciss driver. (OBDR devices are tape drives which can pretend to be cd-rom devices temporarily. Once booted the device can be reverted to a tape drive and data recovery operations can be automatically begun.) This is an enhancement request by a vendor/partner working on One Button Disaster Recovery. Signed-off-by: Stephen M. Cameron <steve.cameron@hp.com> Signed-off-by: Mike Miller <mike.miller@hp.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/block/cciss_scsi.c')
-rw-r--r--drivers/block/cciss_scsi.c41
1 files changed, 29 insertions, 12 deletions
diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c
index df4afacc75d7..efc0bea7693f 100644
--- a/drivers/block/cciss_scsi.c
+++ b/drivers/block/cciss_scsi.c
@@ -878,7 +878,7 @@ cciss_scsi_interpret_error(CommandList_struct *cp)
878 878
879static int 879static int
880cciss_scsi_do_inquiry(ctlr_info_t *c, unsigned char *scsi3addr, 880cciss_scsi_do_inquiry(ctlr_info_t *c, unsigned char *scsi3addr,
881 InquiryData_struct *buf) 881 unsigned char *buf, unsigned char bufsize)
882{ 882{
883 int rc; 883 int rc;
884 CommandList_struct *cp; 884 CommandList_struct *cp;
@@ -901,11 +901,10 @@ cciss_scsi_do_inquiry(ctlr_info_t *c, unsigned char *scsi3addr,
901 cdb[1] = 0; 901 cdb[1] = 0;
902 cdb[2] = 0; 902 cdb[2] = 0;
903 cdb[3] = 0; 903 cdb[3] = 0;
904 cdb[4] = sizeof(*buf) & 0xff; 904 cdb[4] = bufsize;
905 cdb[5] = 0; 905 cdb[5] = 0;
906 rc = cciss_scsi_do_simple_cmd(c, cp, scsi3addr, cdb, 906 rc = cciss_scsi_do_simple_cmd(c, cp, scsi3addr, cdb,
907 6, (unsigned char *) buf, 907 6, buf, bufsize, XFER_READ);
908 sizeof(*buf), XFER_READ);
909 908
910 if (rc != 0) return rc; /* something went wrong */ 909 if (rc != 0) return rc; /* something went wrong */
911 910
@@ -1001,9 +1000,10 @@ cciss_update_non_disk_devices(int cntl_num, int hostno)
1001 that though. 1000 that though.
1002 1001
1003 */ 1002 */
1004 1003#define OBDR_TAPE_INQ_SIZE 49
1004#define OBDR_TAPE_SIG "$DR-10"
1005 ReportLunData_struct *ld_buff; 1005 ReportLunData_struct *ld_buff;
1006 InquiryData_struct *inq_buff; 1006 unsigned char *inq_buff;
1007 unsigned char scsi3addr[8]; 1007 unsigned char scsi3addr[8];
1008 ctlr_info_t *c; 1008 ctlr_info_t *c;
1009 __u32 num_luns=0; 1009 __u32 num_luns=0;
@@ -1021,7 +1021,7 @@ cciss_update_non_disk_devices(int cntl_num, int hostno)
1021 return; 1021 return;
1022 } 1022 }
1023 memset(ld_buff, 0, reportlunsize); 1023 memset(ld_buff, 0, reportlunsize);
1024 inq_buff = kmalloc(sizeof( InquiryData_struct), GFP_KERNEL); 1024 inq_buff = kmalloc(OBDR_TAPE_INQ_SIZE, GFP_KERNEL);
1025 if (inq_buff == NULL) { 1025 if (inq_buff == NULL) {
1026 printk(KERN_ERR "cciss: out of memory\n"); 1026 printk(KERN_ERR "cciss: out of memory\n");
1027 kfree(ld_buff); 1027 kfree(ld_buff);
@@ -1052,19 +1052,36 @@ cciss_update_non_disk_devices(int cntl_num, int hostno)
1052 1052
1053 /* for each physical lun, do an inquiry */ 1053 /* for each physical lun, do an inquiry */
1054 if (ld_buff->LUN[i][3] & 0xC0) continue; 1054 if (ld_buff->LUN[i][3] & 0xC0) continue;
1055 memset(inq_buff, 0, sizeof(InquiryData_struct)); 1055 memset(inq_buff, 0, OBDR_TAPE_INQ_SIZE);
1056 memcpy(&scsi3addr[0], &ld_buff->LUN[i][0], 8); 1056 memcpy(&scsi3addr[0], &ld_buff->LUN[i][0], 8);
1057 1057
1058 if (cciss_scsi_do_inquiry(hba[cntl_num], 1058 if (cciss_scsi_do_inquiry(hba[cntl_num], scsi3addr, inq_buff,
1059 scsi3addr, inq_buff) != 0) 1059 (unsigned char) OBDR_TAPE_INQ_SIZE) != 0) {
1060 {
1061 /* Inquiry failed (msg printed already) */ 1060 /* Inquiry failed (msg printed already) */
1062 devtype = 0; /* so we will skip this device. */ 1061 devtype = 0; /* so we will skip this device. */
1063 } else /* what kind of device is this? */ 1062 } else /* what kind of device is this? */
1064 devtype = (inq_buff->data_byte[0] & 0x1f); 1063 devtype = (inq_buff[0] & 0x1f);
1065 1064
1066 switch (devtype) 1065 switch (devtype)
1067 { 1066 {
1067 case 0x05: /* CD-ROM */ {
1068
1069 /* We don't *really* support actual CD-ROM devices,
1070 * just this "One Button Disaster Recovery" tape drive
1071 * which temporarily pretends to be a CD-ROM drive.
1072 * So we check that the device is really an OBDR tape
1073 * device by checking for "$DR-10" in bytes 43-48 of
1074 * the inquiry data.
1075 */
1076 char obdr_sig[7];
1077
1078 strncpy(obdr_sig, &inq_buff[43], 6);
1079 obdr_sig[6] = '\0';
1080 if (strncmp(obdr_sig, OBDR_TAPE_SIG, 6) != 0)
1081 /* Not OBDR device, ignore it. */
1082 break;
1083 }
1084 /* fall through . . . */
1068 case 0x01: /* sequential access, (tape) */ 1085 case 0x01: /* sequential access, (tape) */
1069 case 0x08: /* medium changer */ 1086 case 0x08: /* medium changer */
1070 if (ncurrent >= CCISS_MAX_SCSI_DEVS_PER_HBA) { 1087 if (ncurrent >= CCISS_MAX_SCSI_DEVS_PER_HBA) {