]> git.proxmox.com Git - mirror_smartmontools-debian.git/blob - debian/patches/60_cciss.dpatch
f2d18a7dfd533b00ae78adff768b235a4232e15b
[mirror_smartmontools-debian.git] / debian / patches / 60_cciss.dpatch
1 #! /bin/sh /usr/share/dpatch/dpatch-run
2 ## 60_cciss.dpatch.dpatch by Guido Guenther <agx@sigxcpu.org>
3 ##
4 ## All lines beginning with `## DP:' are a description of the patch.
5 ## DP: add support for Compaq/HP CCISS controllers
6
7 @DPATCH@
8
9 diff -rN -u old-smartmontools-cciss/os_linux.c new-smartmontools-cciss/os_linux.c
10 --- old-smartmontools-cciss/os_linux.c 2006-02-28 17:38:26.000000000 +0100
11 +++ new-smartmontools-cciss/os_linux.c 2006-04-10 16:15:40.000000000 +0200
12 @@ -64,12 +64,15 @@
13 #include "os_linux.h"
14 #include "scsicmds.h"
15 #include "utility.h"
16 +#include "cciss_ioctl.h"
17 +
18
19 #ifndef ENOTSUP
20 #define ENOTSUP ENOSYS
21 #endif
22 typedef unsigned long long u8;
23
24 +
25 #define ARGUSED(x) ((void)(x))
26
27 static const char *filenameandversion="$Id: os_linux.c,v 1.79 2005/04/27 01:24:51 dpgilbert Exp $";
28 @@ -83,6 +86,17 @@
29 // global variable holding byte count of allocated memory
30 extern long long bytes;
31
32 +typedef struct _ReportLUNdata_struct
33 +{
34 + BYTE LUNListLength[4];
35 + DWORD reserved;
36 + BYTE LUN[CISS_MAX_LUN][8];
37 +} ReportLunData_struct;
38 +
39 +/* Structure/defines of Report Physical LUNS of drive */
40 +#define CISS_MAX_LUN 16
41 +#define CISS_MAX_PHYS_LUN 1024
42 +#define CISS_REPORT_PHYS 0xc3
43
44
45 /* This function will setup and fix device nodes for a 3ware controller. */
46 @@ -191,8 +205,15 @@
47 }
48 return open(pathname, O_RDONLY | O_NONBLOCK);
49 }
50 + // cciss+
51 + else if(!strcmp(type, "CCISS"))
52 + {
53 + // the device is a cciss smart array device.
54 + return open(pathname, O_RDWR | O_NONBLOCK);
55 + }
56 else
57 return -1;
58 +
59 }
60
61 // equivalent to close(file descriptor)
62 @@ -609,6 +630,93 @@
63
64 return 0;
65 }
66 +// cciss+
67 +static int cciss_sendpassthru(unsigned int cmdtype, unsigned char *CDB,
68 + unsigned int CDBlen, char *buff,
69 + unsigned int size, unsigned int LunID,
70 + unsigned char *scsi3addr, int fd)
71 +{
72 + int err ;
73 + IOCTL_Command_struct iocommand;
74 +
75 + memset(&iocommand, 0, sizeof(iocommand));
76 +
77 + if (cmdtype == 0)
78 + {
79 + // To controller; nothing to do
80 + }
81 + else if (cmdtype == 1)
82 + {
83 + iocommand.LUN_info.LogDev.VolId = LunID;
84 + iocommand.LUN_info.LogDev.Mode = 1;
85 + }
86 + else if (cmdtype == 2)
87 + {
88 + memcpy(&iocommand.LUN_info.LunAddrBytes,scsi3addr,8);
89 + iocommand.LUN_info.LogDev.Mode = 0;
90 + }
91 + else
92 + {
93 + fprintf(stderr, "cciss_sendpassthru: bad cmdtype\n");
94 + return 1;
95 + }
96 +
97 + memcpy(&iocommand.Request.CDB[0], CDB, CDBlen);
98 + iocommand.Request.CDBLen = CDBlen;
99 + iocommand.Request.Type.Type = TYPE_CMD;
100 + iocommand.Request.Type.Attribute = ATTR_SIMPLE;
101 + iocommand.Request.Type.Direction = XFER_READ;
102 + iocommand.Request.Timeout = 0;
103 +
104 + iocommand.buf_size = size;
105 + iocommand.buf = (unsigned char *)buff;
106 +
107 + if ((err = ioctl(fd, CCISS_PASSTHRU, &iocommand)))
108 + {
109 + fprintf(stderr, "CCISS ioctl error %d\n", err);
110 + }
111 + return err;
112 +}
113 +
114 +// cciss+
115 +static int cciss_getlun(int device, int target, unsigned char *physlun)
116 +{
117 + unsigned char CDB[16]= {0};
118 + ReportLunData_struct *luns;
119 + int reportlunsize = sizeof(*luns) + CISS_MAX_PHYS_LUN * 8;
120 + int i;
121 + int ret;
122 +
123 + luns = (ReportLunData_struct *)malloc(reportlunsize);
124 +
125 + memset(luns, 0, reportlunsize);
126 +
127 + /* Get Physical LUN Info (for physical device) */
128 + CDB[0] = CISS_REPORT_PHYS;
129 + CDB[6] = (reportlunsize >> 24) & 0xFF; /* MSB */
130 + CDB[7] = (reportlunsize >> 16) & 0xFF;
131 + CDB[8] = (reportlunsize >> 8) & 0xFF;
132 + CDB[9] = reportlunsize & 0xFF;
133 +
134 + if ((ret = cciss_sendpassthru(0, CDB, 12, (char *)luns, reportlunsize, 0, NULL, device)))
135 + {
136 + free(luns);
137 + return ret;
138 + }
139 +
140 + for (i=0; i<CISS_MAX_LUN+1; i++)
141 + {
142 + if (luns->LUN[i][6] == target)
143 + {
144 + memcpy(physlun, luns->LUN[i], 8);
145 + free(luns);
146 + return 0;
147 + }
148 + }
149 +
150 + free(luns);
151 + return ret;
152 +}
153
154 // >>>>>> Start of general SCSI specific linux code
155
156 @@ -946,6 +1054,75 @@
157 // >>>>>> End of general SCSI specific linux code
158
159
160 +// cciss+ >> CCSISS I/O passthrough
161 +// This is an interface that uses the cciss passthrough to talk to the SMART controller on
162 +// the HP system. The cciss driver provides a way to send SCSI cmds through the CCISS passthrough
163 +// essentially the methods above and below pertain to SCSI, except for the SG driver which is not
164 +// involved. The CCISS driver does not engage the scsi subsystem.
165 +int cciss_io_interface(int device, int target, struct scsi_cmnd_io * iop, int report)
166 +{
167 + unsigned char pBuf[512] = {0};
168 + unsigned char phylun[1024] = {0};
169 + int iBufLen = 512;
170 + int status = -1;
171 + int len = 0; // used later in the code.
172 + report = 0;
173 +
174 + cciss_getlun(device, target, phylun);
175 + status = cciss_sendpassthru( 2, iop->cmnd, iop->cmnd_len, (char*) pBuf, iBufLen, 1, phylun, device);
176 +
177 + if (0 == status)
178 + {
179 + if (report > 0)
180 + printf(" status=0\n");
181 + if (DXFER_FROM_DEVICE == iop->dxfer_dir)
182 + {
183 + memcpy(iop->dxferp, pBuf, iop->dxfer_len);
184 + if (report > 1)
185 + {
186 + int trunc = (iop->dxfer_len > 256) ? 1 : 0;
187 + printf(" Incoming data, len=%d%s:\n", (int)iop->dxfer_len,
188 + (trunc ? " [only first 256 bytes shown]" : ""));
189 + dStrHex((const char*)iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);
190 + }
191 + }
192 + return 0;
193 + }
194 + iop->scsi_status = status & 0x7e; /* bits 0 and 7 used to be for vendors */
195 + if (LSCSI_DRIVER_SENSE == ((status >> 24) & 0xf))
196 + iop->scsi_status = SCSI_STATUS_CHECK_CONDITION;
197 + len = (SEND_IOCTL_RESP_SENSE_LEN < iop->max_sense_len) ?
198 + SEND_IOCTL_RESP_SENSE_LEN : iop->max_sense_len;
199 + if ((SCSI_STATUS_CHECK_CONDITION == iop->scsi_status) &&
200 + iop->sensep && (len > 0))
201 + {
202 + memcpy(iop->sensep, pBuf, len);
203 + iop->resp_sense_len = iBufLen;
204 + if (report > 1)
205 + {
206 + printf(" >>> Sense buffer, len=%d:\n", (int)len);
207 + dStrHex((const char *)pBuf, len , 1);
208 + }
209 + }
210 + if (report)
211 + {
212 + if (SCSI_STATUS_CHECK_CONDITION == iop->scsi_status) {
213 + printf(" status=%x: sense_key=%x asc=%x ascq=%x\n", status & 0xff,
214 + pBuf[2] & 0xf, pBuf[12], pBuf[13]);
215 + }
216 + else
217 + printf(" status=0x%x\n", status);
218 + }
219 + if (iop->scsi_status > 0)
220 + return 0;
221 + else
222 + {
223 + if (report > 0)
224 + printf(" ioctl status=0x%x but scsi status=0, fail with EIO\n", status);
225 + return -EIO; /* give up, assume no device there */
226 + }
227 +}
228 +
229 // prototype
230 void printwarning(smart_command_set command);
231
232 diff -rN -u old-smartmontools-cciss/scsicmds.c new-smartmontools-cciss/scsicmds.c
233 --- old-smartmontools-cciss/scsicmds.c 2006-02-28 17:38:26.000000000 +0100
234 +++ new-smartmontools-cciss/scsicmds.c 2006-04-13 09:29:10.000000000 +0200
235 @@ -53,6 +53,26 @@
236 /* for passing global control variables */
237 extern smartmonctrl *con;
238
239 +// Check and call the right interface. May be when the do_generic_scsi_cmd_io interface is better
240 +// we can take off this crude way of calling the right interface
241 +
242 +static int do_generic_scsi_cmd_io(int dev_fd, struct scsi_cmnd_io * iop, int report)
243 +{
244 + switch(con->controller_type)
245 + {
246 + case CONTROLLER_CCISS:
247 + return cciss_io_interface(dev_fd, con->controller_port-1, iop, report);
248 + // not reached
249 + break;
250 + default:
251 + return do_scsi_cmnd_io(dev_fd, iop, report);
252 + // not reached
253 + break;
254 + }
255 +}
256 +
257 +
258 +
259 /* output binary in hex and optionally ascii */
260 void dStrHex(const char* str, int len, int no_ascii)
261 {
262 @@ -267,7 +287,7 @@
263 io_hdr.max_sense_len = sizeof(sense);
264 io_hdr.timeout = SCSI_TIMEOUT_DEFAULT;
265
266 - status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
267 + status = do_generic_scsi_cmd_io(device, &io_hdr, con->reportscsiioctl);
268 if (0 != status)
269 return status;
270 scsi_do_sense_disect(&io_hdr, &sinfo);
271 @@ -301,7 +321,7 @@
272 io_hdr.max_sense_len = sizeof(sense);
273 io_hdr.timeout = SCSI_TIMEOUT_DEFAULT;
274
275 - status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
276 + status = do_generic_scsi_cmd_io(device, &io_hdr, con->reportscsiioctl);
277 if (0 != status)
278 return status;
279 scsi_do_sense_disect(&io_hdr, &sinfo);
280 @@ -344,13 +364,13 @@
281 io_hdr.max_sense_len = sizeof(sense);
282 io_hdr.timeout = SCSI_TIMEOUT_DEFAULT;
283
284 - status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
285 + status = do_generic_scsi_cmd_io(device, &io_hdr, con->reportscsiioctl);
286 if (0 != status)
287 return status;
288 scsi_do_sense_disect(&io_hdr, &sinfo);
289 status = scsiSimpleSenseFilter(&sinfo);
290 if (SIMPLE_ERR_TRY_AGAIN == status) {
291 - status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
292 + status = do_generic_scsi_cmd_io(device, &io_hdr, con->reportscsiioctl);
293 if (0 != status)
294 return status;
295 scsi_do_sense_disect(&io_hdr, &sinfo);
296 @@ -406,7 +426,7 @@
297 io_hdr.max_sense_len = sizeof(sense);
298 io_hdr.timeout = SCSI_TIMEOUT_DEFAULT;
299
300 - status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
301 + status = do_generic_scsi_cmd_io(device, &io_hdr, con->reportscsiioctl);
302 if (0 != status)
303 return status;
304 scsi_do_sense_disect(&io_hdr, &sinfo);
305 @@ -440,13 +460,13 @@
306 io_hdr.max_sense_len = sizeof(sense);
307 io_hdr.timeout = SCSI_TIMEOUT_DEFAULT;
308
309 - status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
310 + status = do_generic_scsi_cmd_io(device, &io_hdr, con->reportscsiioctl);
311 if (0 != status)
312 return status;
313 scsi_do_sense_disect(&io_hdr, &sinfo);
314 status = scsiSimpleSenseFilter(&sinfo);
315 if (SIMPLE_ERR_TRY_AGAIN == status) {
316 - status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
317 + status = do_generic_scsi_cmd_io(device, &io_hdr, con->reportscsiioctl);
318 if (0 != status)
319 return status;
320 scsi_do_sense_disect(&io_hdr, &sinfo);
321 @@ -503,7 +523,7 @@
322 io_hdr.max_sense_len = sizeof(sense);
323 io_hdr.timeout = SCSI_TIMEOUT_DEFAULT;
324
325 - status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
326 + status = do_generic_scsi_cmd_io(device, &io_hdr, con->reportscsiioctl);
327 if (0 != status)
328 return status;
329 scsi_do_sense_disect(&io_hdr, &sinfo);
330 @@ -536,7 +556,7 @@
331 io_hdr.max_sense_len = sizeof(sense);
332 io_hdr.timeout = SCSI_TIMEOUT_DEFAULT;
333
334 - status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
335 + status = do_generic_scsi_cmd_io(device, &io_hdr, con->reportscsiioctl);
336 if (0 != status)
337 return status;
338 scsi_do_sense_disect(&io_hdr, &sinfo);
339 @@ -574,7 +594,7 @@
340 io_hdr.max_sense_len = sizeof(sense);
341 io_hdr.timeout = SCSI_TIMEOUT_DEFAULT;
342
343 - status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
344 + status = do_generic_scsi_cmd_io(device, &io_hdr, con->reportscsiioctl);
345 if (0 != status)
346 return status;
347 scsi_do_sense_disect(&io_hdr, &sinfo);
348 @@ -615,7 +635,7 @@
349 io_hdr.max_sense_len = sizeof(sense);
350 io_hdr.timeout = SCSI_TIMEOUT_DEFAULT;
351
352 - status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
353 + status = do_generic_scsi_cmd_io(device, &io_hdr, con->reportscsiioctl);
354 if ((0 == status) && (sense_info)) {
355 ecode = buff[0] & 0x7f;
356 sense_info->error_code = ecode;
357 @@ -665,7 +685,7 @@
358 /* worst case is an extended foreground self test on a big disk */
359 io_hdr.timeout = SCSI_TIMEOUT_SELF_TEST;
360
361 - status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
362 + status = do_generic_scsi_cmd_io(device, &io_hdr, con->reportscsiioctl);
363 if (0 != status)
364 return status;
365 scsi_do_sense_disect(&io_hdr, &sinfo);
366 @@ -700,7 +720,7 @@
367 io_hdr.max_sense_len = sizeof(sense);
368 io_hdr.timeout = SCSI_TIMEOUT_DEFAULT;
369
370 - status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
371 + status = do_generic_scsi_cmd_io(device, &io_hdr, con->reportscsiioctl);
372 if (0 != status)
373 return status;
374 scsi_do_sense_disect(&io_hdr, &sinfo);
375 @@ -727,7 +747,7 @@
376 io_hdr.max_sense_len = sizeof(sense);
377 io_hdr.timeout = SCSI_TIMEOUT_DEFAULT;
378
379 - status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
380 + status = do_generic_scsi_cmd_io(device, &io_hdr, con->reportscsiioctl);
381 if (0 != status)
382 return status;
383 scsi_do_sense_disect(&io_hdr, sinfo);
384 @@ -783,7 +803,7 @@
385 io_hdr.max_sense_len = sizeof(sense);
386 io_hdr.timeout = SCSI_TIMEOUT_DEFAULT;
387
388 - status = do_scsi_cmnd_io(device, &io_hdr, con->reportscsiioctl);
389 + status = do_generic_scsi_cmd_io(device, &io_hdr, con->reportscsiioctl);
390 if (0 != status)
391 return status;
392 scsi_do_sense_disect(&io_hdr, &sinfo);
393 diff -rN -u old-smartmontools-cciss/scsicmds.h new-smartmontools-cciss/scsicmds.h
394 --- old-smartmontools-cciss/scsicmds.h 2006-02-28 17:38:26.000000000 +0100
395 +++ new-smartmontools-cciss/scsicmds.h 2006-04-10 11:34:37.000000000 +0200
396 @@ -346,6 +346,8 @@
397 * (e.g. device not present or not a SCSI device) or some other problem
398 * arises (e.g. timeout) then returns a negative errno value. */
399 int do_scsi_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop, int report);
400 +// The cciss interface for the cciss over SCSI - Linux specific so far
401 +int cciss_io_interface(int device, int target, struct scsi_cmnd_io * iop, int report);
402
403
404 /* This is Linux specific and will be generalized later. */
405 diff -rN -u old-smartmontools-cciss/smartctl.8.in new-smartmontools-cciss/smartctl.8.in
406 --- old-smartmontools-cciss/smartctl.8.in 2006-02-28 17:38:26.000000000 +0100
407 +++ new-smartmontools-cciss/smartctl.8.in 2006-04-12 11:40:36.000000000 +0200
408 @@ -173,7 +173,7 @@
409 .TP
410 .B \-d TYPE, \-\-device=TYPE
411 Specifies the type of the device. The valid arguments to this option
412 -are \fIata\fP, \fIscsi\fP, \fImarvell\fP, and \fI3ware,N\fP. If this option is not
413 +are \fIata\fP, \fIscsi\fP, \fImarvell\fP, \fIcciss,N\fP and \fI3ware,N\fP. If this option is not
414 used then \fBsmartctl\fP will attempt to guess the device type from
415 the device name.
416
417 @@ -253,6 +253,8 @@
418
419 .B 3ware controllers are currently ONLY supported under Linux and FreeBSD.
420
421 +.B cciss controllers are currently ONLY supported under Linux.
422 +
423 .TP
424 .B \-T TYPE, \-\-tolerance=TYPE
425 Specifies how tolerant \fBsmartctl\fP should be of ATA and SMART command
426 @@ -1138,6 +1140,12 @@
427 power\-cycled during the read\-scan, resume the scan 45 minutes after power to the
428 device is restored.
429 .PP
430 +.nf
431 +.B smartctl \-a \-d cciss,0 /dev/cciss/c0d0
432 +.fi
433 +Examine all SMART data for the first SCSI disk connected to a cciss
434 +RAID controller card.
435 +.PP
436 .SH RETURN VALUES
437 The return values of \fBsmartctl\fP are defined by a bitmask. If all
438 is well with the disk, the return value (exit status) of
439 diff -rN -u old-smartmontools-cciss/smartctl.c new-smartmontools-cciss/smartctl.c
440 --- old-smartmontools-cciss/smartctl.c 2006-02-28 17:38:26.000000000 +0100
441 +++ new-smartmontools-cciss/smartctl.c 2006-04-12 11:31:32.000000000 +0200
442 @@ -234,7 +234,7 @@
443 case 'q':
444 return "errorsonly, silent";
445 case 'd':
446 - return "ata, scsi, marvell, 3ware,N";
447 + return "ata, scsi, marvell, 3ware,N, cciss,N";
448 case 'T':
449 return "normal, conservative, permissive, verypermissive";
450 case 'b':
451 @@ -384,21 +384,35 @@
452 con->dont_print = FALSE;
453 pout("No memory for argument of -d. Exiting...\n");
454 exit(FAILCMD);
455 - } else if (strncmp(s,"3ware,",6)) {
456 - badarg = TRUE;
457 - } else if (split_report_arg2(s, &i)) {
458 - sprintf(extraerror, "Option -d 3ware,N requires N to be a non-negative integer\n");
459 - badarg = TRUE;
460 - } else if (i<0 || i>15) {
461 - sprintf(extraerror, "Option -d 3ware,N (N=%d) must have 0 <= N <= 15\n", i);
462 - badarg = TRUE;
463 - } else {
464 - // NOTE: controller_port == disk number + 1
465 - con->controller_type = CONTROLLER_3WARE;
466 - con->controller_port = i+1;
467 - }
468 - free(s);
469 - }
470 + } else if (!strncmp(s,"3ware,",6)) {
471 + if (split_report_arg2(s, &i)) {
472 + sprintf(extraerror, "Option -d 3ware,N requires N to be a non-negative integer\n");
473 + badarg = TRUE;
474 + } else if (i<0 || i>15) {
475 + sprintf(extraerror, "Option -d 3ware,N (N=%d) must have 0 <= N <= 15\n", i);
476 + badarg = TRUE;
477 + } else {
478 + // NOTE: controller_port == disk number + 1
479 + con->controller_type = CONTROLLER_3WARE;
480 + con->controller_port = i+1;
481 + }
482 + free(s);
483 + } else if (!strncmp(s,"cciss,",6)) {
484 + if (split_report_arg2(s, &i)) {
485 + sprintf(extraerror, "Option -d cciss,N requires N to be a non-negative integer\n");
486 + badarg = TRUE;
487 + } else if (i<0 || i>15) {
488 + sprintf(extraerror, "Option -d cciss,N (N=%d) must have 0 <= N <= 15\n", i);
489 + badarg = TRUE;
490 + } else {
491 + // NOTE: controller_port == drive number
492 + con->controller_type = CONTROLLER_CCISS;
493 + con->controller_port = i+1;
494 + }
495 + free(s);
496 + } else
497 + badarg=TRUE;
498 + }
499 break;
500 case 'T':
501 if (!strcmp(optarg,"normal")) {
502 @@ -851,6 +865,9 @@
503 case CONTROLLER_3WARE_678K_CHAR:
504 mode="ATA_3WARE_678K";
505 break;
506 + case CONTROLLER_CCISS:
507 + mode="CCISS";
508 + break;
509 default:
510 mode="ATA";
511 break;
512 @@ -882,6 +899,11 @@
513 case CONTROLLER_SCSI:
514 retval = scsiPrintMain(fd);
515 break;
516 + case CONTROLLER_CCISS:
517 + // route the cciss command through scsiPrintMain.
518 + // cciss pass-throughs will separeate from the SCSI data-path.
519 + retval = scsiPrintMain(fd);
520 + break;
521 default:
522 retval = ataPrintMain(fd);
523 break;
524 diff -rN -u old-smartmontools-cciss/smartd.8.in new-smartmontools-cciss/smartd.8.in
525 --- old-smartmontools-cciss/smartd.8.in 2006-02-28 17:38:26.000000000 +0100
526 +++ new-smartmontools-cciss/smartd.8.in 2006-04-12 11:41:03.000000000 +0200
527 @@ -561,8 +561,8 @@
528 .B \-d TYPE
529 Specifies the type of the device. This Directive may be used multiple
530 times for one device, but the arguments \fIata\fP, \fIscsi\fP,
531 -\fImarvell\fP, and \fI3ware,N\fP are mutually-exclusive. If more than
532 -one is given then \fBsmartd\fP will use the last one which appears.
533 +\fImarvell\fP, \fIcciss,N\fP and \fI3ware,N\fP are mutually-exclusive. If more
534 +than one is given then \fBsmartd\fP will use the last one which appears.
535
536 If none of these three arguments is given, then \fBsmartd\fP will
537 first attempt to guess the device type by looking at whether the sixth
538 @@ -629,8 +629,14 @@
539 6/7/8000 series controllers) or /dev/twa0-15 (3ware 9000 series
540 controllers).
541
542 +.I cciss,N
543 +\- the device consists of one or more SCSI disks connected to a cciss
544 +RAID controller. The non-negative integer N (in the range from 0 to 15
545 +inclusive) denotes which disk on the controller is monitored. In log
546 +files and email messages this disk will be identified as cciss_disk_XX
547 +with XX in the range from 00 to 15 inclusive.
548
549 -.B 3ware controllers are currently ONLY supported under Linux.
550 +.B 3ware and cciss controllers are currently ONLY supported under Linux.
551
552 .I removable
553 \- the device or its media is removable. This indicates to
554 diff -rN -u old-smartmontools-cciss/smartd.c new-smartmontools-cciss/smartd.c
555 --- old-smartmontools-cciss/smartd.c 2006-02-28 17:38:26.000000000 +0100
556 +++ new-smartmontools-cciss/smartd.c 2006-04-12 11:32:50.000000000 +0200
557 @@ -705,6 +705,18 @@
558 *s=' ';
559 }
560 break;
561 + case CONTROLLER_CCISS:
562 + {
563 + char *s,devicetype[16];
564 + sprintf(devicetype, "cciss,%d", cfg->controller_port-1);
565 + exportenv(environ_strings[8], "SMARTD_DEVICETYPE", devicetype);
566 + if ((s=strchr(cfg->name, ' ')))
567 + *s='\0';
568 + exportenv(environ_strings[9], "SMARTD_DEVICE", cfg->name);
569 + if (s)
570 + *s=' ';
571 + }
572 + break;
573 case CONTROLLER_ATA:
574 exportenv(environ_strings[8], "SMARTD_DEVICETYPE", "ata");
575 exportenv(environ_strings[9], "SMARTD_DEVICE", cfg->name);
576 @@ -716,6 +728,7 @@
577 case CONTROLLER_SCSI:
578 exportenv(environ_strings[8], "SMARTD_DEVICETYPE", "scsi");
579 exportenv(environ_strings[9], "SMARTD_DEVICE", cfg->name);
580 + break;
581 }
582
583 snprintf(fullmessage, 1024,
584 @@ -1063,7 +1076,7 @@
585 void Directives() {
586 PrintOut(LOG_INFO,
587 "Configuration file (%s) Directives (after device name):\n"
588 - " -d TYPE Set the device type: ata, scsi, marvell, removable, 3ware,N\n"
589 + " -d TYPE Set the device type: ata, scsi, marvell, removable, 3ware,N, cciss,N\n"
590 " -T TYPE Set the tolerance to one of: normal, permissive\n"
591 " -o VAL Enable/disable automatic offline tests (on/off)\n"
592 " -S VAL Enable/disable attribute autosave (on/off)\n"
593 @@ -1593,11 +1606,15 @@
594 // should we try to register this as a SCSI device?
595 switch (cfg->controller_type) {
596 case CONTROLLER_SCSI:
597 + case CONTROLLER_CCISS:
598 case CONTROLLER_UNKNOWN:
599 break;
600 default:
601 return 1;
602 }
603 + // pass user settings on to low-level SCSI commands
604 + con->controller_port=cfg->controller_port;
605 + con->controller_type=cfg->controller_type;
606
607 // open the device
608 if ((fd = OpenDevice(device, "SCSI", scanning)) < 0)
609 @@ -2728,26 +2745,42 @@
610 PrintOut(LOG_CRIT,
611 "No memory to copy argument to -d option - exiting\n");
612 EXIT(EXIT_NOMEM);
613 - } else if (strncmp(s,"3ware,",6)) {
614 - badarg=1;
615 - } else if (split_report_arg2(s, &i)){
616 - PrintOut(LOG_CRIT, "File %s line %d (drive %s): Directive -d 3ware,N requires N integer\n",
617 - configfile, lineno, name);
618 - badarg=1;
619 - } else if ( i<0 || i>15) {
620 - PrintOut(LOG_CRIT, "File %s line %d (drive %s): Directive -d 3ware,N (N=%d) must have 0 <= N <= 15\n",
621 - configfile, lineno, name, i);
622 - badarg=1;
623 - } else {
624 - // determine type of escalade device from name of device
625 - cfg->controller_type = guess_device_type(name);
626 - if (cfg->controller_type!=CONTROLLER_3WARE_9000_CHAR && cfg->controller_type!=CONTROLLER_3WARE_678K_CHAR)
627 - cfg->controller_type=CONTROLLER_3WARE_678K;
628 + } else if (!strncmp(s,"3ware,",6)) {
629 + if (split_report_arg2(s, &i)){
630 + PrintOut(LOG_CRIT, "File %s line %d (drive %s): Directive -d 3ware,N requires N integer\n",
631 + configfile, lineno, name);
632 + badarg=1;
633 + } else if ( i<0 || i>15) {
634 + PrintOut(LOG_CRIT, "File %s line %d (drive %s): Directive -d 3ware,N (N=%d) must have 0 <= N <= 15\n",
635 + configfile, lineno, name, i);
636 + badarg=1;
637 + } else {
638 + // determine type of escalade device from name of device
639 + cfg->controller_type = guess_device_type(name);
640 + if (cfg->controller_type!=CONTROLLER_3WARE_9000_CHAR && cfg->controller_type!=CONTROLLER_3WARE_678K_CHAR)
641 + cfg->controller_type=CONTROLLER_3WARE_678K;
642
643 - // NOTE: controller_port == disk number + 1
644 - cfg->controller_port = i+1;
645 + // NOTE: controller_port == disk number + 1
646 + cfg->controller_port = i+1;
647 + }
648 + } else if (!strncmp(s,"cciss,",6)) {
649 + if (split_report_arg2(s, &i)){
650 + PrintOut(LOG_CRIT, "File %s line %d (drive %s): Directive -d cciss,N requires N integer\n",
651 + configfile, lineno, name);
652 + badarg=1;
653 + } else if ( i<0 || i>15) {
654 + PrintOut(LOG_CRIT, "File %s line %d (drive %s): Directive -d cciss,N (N=%d) must have 0 <= N <= 15\n",
655 + configfile, lineno, name, i);
656 + badarg=1;
657 + } else {
658 + // NOTE: controller_port == disk number + 1
659 + cfg->controller_type = CONTROLLER_CCISS;
660 + cfg->controller_port = i+1;
661 + }
662 + } else {
663 + badarg=1;
664 }
665 - s=CheckFree(s, __LINE__,filenameandversion);
666 + s=CheckFree(s, __LINE__,filenameandversion);
667 }
668 break;
669 case 'F':
670 @@ -3155,13 +3188,13 @@
671 }
672 }
673
674 - // If we found 3ware controller, then modify device name by adding a SPACE
675 - if (cfg->controller_port){
676 + // If we found 3ware/cciss controller, then modify device name by adding a SPACE
677 + if (cfg->controller_port) {
678 int len=17+strlen(cfg->name);
679 char *newname;
680
681 if (devscan){
682 - PrintOut(LOG_CRIT, "smartd: can not scan for 3ware devices (line %d of file %s)\n",
683 + PrintOut(LOG_CRIT, "smartd: can not scan for 3ware/cciss devices (line %d of file %s)\n",
684 lineno, configfile);
685 return -2;
686 }
687 @@ -3172,7 +3205,8 @@
688 }
689
690 // Make new device name by adding a space then RAID disk number
691 - snprintf(newname, len, "%s [3ware_disk_%02d]", cfg->name, cfg->controller_port-1);
692 + snprintf(newname, len, "%s [%s_disk_%02d]", cfg->name, (cfg->controller_type == CONTROLLER_CCISS) ? "cciss" : "3ware",
693 + cfg->controller_port-1);
694 cfg->name=CheckFree(cfg->name, __LINE__,filenameandversion);
695 cfg->name=newname;
696 bytes+=16;
697 @@ -3808,7 +3842,7 @@
698 continue;
699
700 // register ATA devices
701 - if (ent->controller_type!=CONTROLLER_SCSI){
702 + if (ent->controller_type!=CONTROLLER_SCSI && ent->controller_type!=CONTROLLER_CCISS){
703 if (ATADeviceScan(ent, scanning))
704 CanNotRegister(ent->name, "ATA", ent->lineno, scanning);
705 else {
706 @@ -3821,7 +3855,8 @@
707 }
708
709 // then register SCSI devices
710 - if (ent->controller_type==CONTROLLER_SCSI || ent->controller_type==CONTROLLER_UNKNOWN){
711 + if (ent->controller_type==CONTROLLER_SCSI || ent->controller_type==CONTROLLER_CCISS ||
712 + ent->controller_type==CONTROLLER_UNKNOWN){
713 int retscsi=0;
714
715 #if SCSITIMEOUT
716 diff -rN -u old-smartmontools-cciss/smartd.conf.5.in new-smartmontools-cciss/smartd.conf.5.in
717 --- old-smartmontools-cciss/smartd.conf.5.in 2006-02-28 17:38:26.000000000 +0100
718 +++ new-smartmontools-cciss/smartd.conf.5.in 2006-04-12 11:58:07.000000000 +0200
719 @@ -226,8 +226,8 @@
720 .B \-d TYPE
721 Specifies the type of the device. This Directive may be used multiple
722 times for one device, but the arguments \fIata\fP, \fIscsi\fP,
723 -\fImarvell\fP, and \fI3ware,N\fP are mutually-exclusive. If more than
724 -one is given then \fBsmartd\fP will use the last one which appears.
725 +\fImarvell\fP, \fIcciss,N\fP and \fI3ware,N\fP are mutually-exclusive. If more
726 +than one is given then \fBsmartd\fP will use the last one which appears.
727
728 If none of these three arguments is given, then \fBsmartd\fP will
729 first attempt to guess the device type by looking at whether the sixth
730 @@ -294,8 +294,14 @@
731 6/7/8000 series controllers) or /dev/twa0-15 (3ware 9000 series
732 controllers).
733
734 +.I cciss,N
735 +\- the device consists of one or more SCSI disks connected to a cciss
736 +RAID controller. The non-negative integer N (in the range from 0 to 15
737 +inclusive) denotes which disk on the controller is monitored. In log
738 +files and email messages this disk will be identified as cciss_disk_XX
739 +with XX in the range from 00 to 15 inclusive.
740
741 -.B 3ware controllers are currently ONLY supported under Linux.
742 +.B 3ware and cciss controllers are currently ONLY supported under Linux.
743
744 .I removable
745 \- the device or its media is removable. This indicates to
746 diff -rN -u old-smartmontools-cciss/utility.h new-smartmontools-cciss/utility.h
747 --- old-smartmontools-cciss/utility.h 2006-02-28 17:38:26.000000000 +0100
748 +++ new-smartmontools-cciss/utility.h 2006-04-13 09:28:32.000000000 +0200
749 @@ -174,6 +174,6 @@
750 #define CONTROLLER_3WARE_9000_CHAR 0x05 // set by guess_device_type()
751 #define CONTROLLER_3WARE_678K_CHAR 0x06 // set by guess_device_type()
752 #define CONTROLLER_MARVELL_SATA 0x07 // SATA drives behind Marvell controllers
753 -
754 +#define CONTROLLER_CCISS 0x08 // CCISS controller
755
756 #endif
757