]> git.proxmox.com Git - mirror_smartmontools-debian.git/blob - os_freebsd.cpp
Imported upstream version 5.38~rc0
[mirror_smartmontools-debian.git] / os_freebsd.cpp
1 /*
2 * os_freebsd.c
3 *
4 * Home page of code is: http://smartmontools.sourceforge.net
5 *
6 * Copyright (C) 2003-6 Eduard Martinescu <smartmontools-support@lists.sourceforge.net>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2, or (at your option)
11 * any later version.
12 *
13 * You should have received a copy of the GNU General Public License
14 * (for example COPYING); if not, write to the Free
15 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
16 */
17
18 #include <stdio.h>
19 #include <sys/types.h>
20 #include <dirent.h>
21 #include <fcntl.h>
22 #include <err.h>
23 #include <camlib.h>
24 #include <cam/scsi/scsi_message.h>
25 #if defined(__DragonFly__)
26 #include <sys/nata.h>
27 #else
28 #include <sys/ata.h>
29 #endif
30 #include <sys/stat.h>
31 #include <unistd.h>
32 #include <fcntl.h>
33 #include <glob.h>
34 #include <fcntl.h>
35 #include <stddef.h>
36
37
38 #include "config.h"
39 #include "int64.h"
40 #include "atacmds.h"
41 #include "scsicmds.h"
42 #include "cciss.h"
43 #include "utility.h"
44 #include "extern.h"
45 #include "os_freebsd.h"
46
47 static const char *filenameandversion="$Id: os_freebsd.cpp,v 1.56 2008/02/23 06:41:59 ballen4705 Exp $";
48
49 const char *os_XXXX_c_cvsid="$Id: os_freebsd.cpp,v 1.56 2008/02/23 06:41:59 ballen4705 Exp $" \
50 ATACMDS_H_CVSID CONFIG_H_CVSID INT64_H_CVSID OS_FREEBSD_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
51
52 // to hold onto exit code for atexit routine
53 extern int exitstatus;
54
55 extern smartmonctrl * con;
56
57 // Private table of open devices: guaranteed zero on startup since
58 // part of static data.
59 struct freebsd_dev_channel *devicetable[FREEBSD_MAXDEV];
60
61 // forward declaration
62 static int parse_ata_chan_dev(const char * dev_name, struct freebsd_dev_channel *ch);
63
64 // print examples for smartctl
65 void print_smartctl_examples(){
66 printf("=================================================== SMARTCTL EXAMPLES =====\n\n");
67 #ifdef HAVE_GETOPT_LONG
68 printf(
69 " smartctl -a /dev/ad0 (Prints all SMART information)\n\n"
70 " smartctl --smart=on --offlineauto=on --saveauto=on /dev/ad0\n"
71 " (Enables SMART on first disk)\n\n"
72 " smartctl -t long /dev/ad0 (Executes extended disk self-test)\n\n"
73 " smartctl --attributes --log=selftest --quietmode=errorsonly /dev/ad0\n"
74 " (Prints Self-Test & Attribute errors)\n"
75 " (Prints Self-Test & Attribute errors)\n\n"
76 " smartctl -a --device=3ware,2 /dev/twa0\n"
77 " smartctl -a --device=3ware,2 /dev/twe0\n"
78 " (Prints all SMART information for ATA disk on\n"
79 " third port of first 3ware RAID controller)\n"
80 );
81 #else
82 printf(
83 " smartctl -a /dev/ad0 (Prints all SMART information)\n"
84 " smartctl -s on -o on -S on /dev/ad0 (Enables SMART on first disk)\n"
85 " smartctl -t long /dev/ad0 (Executes extended disk self-test)\n"
86 " smartctl -A -l selftest -q errorsonly /dev/ad0\n"
87 " (Prints Self-Test & Attribute errors)\n"
88 " smartctl -a -d 3ware,2 /dev/twa0\n"
89 " smartctl -a -d 3ware,2 /dev/twe0\n"
90 );
91 #endif
92 return;
93 }
94
95 // Like open(). Return positive integer handle, used by functions below only. mode=="ATA" or "SCSI".
96 int deviceopen (const char* dev, __unused char* mode) {
97 struct freebsd_dev_channel *fdchan;
98 int parse_ok, i;
99
100 // Search table for a free entry
101 for (i=0; i<FREEBSD_MAXDEV; i++)
102 if (!devicetable[i])
103 break;
104
105 // If no free entry found, return error. We have max allowed number
106 // of "file descriptors" already allocated.
107 if (i==FREEBSD_MAXDEV) {
108 errno=EMFILE;
109 return -1;
110 }
111
112 fdchan = (struct freebsd_dev_channel *)calloc(1,sizeof(struct freebsd_dev_channel));
113 if (fdchan == NULL) {
114 // errno already set by call to malloc()
115 return -1;
116 }
117
118 parse_ok = parse_ata_chan_dev (dev,fdchan);
119 if (parse_ok == CONTROLLER_UNKNOWN) {
120 free(fdchan);
121 errno = ENOTTY;
122 return -1; // can't handle what we don't know
123 }
124
125 if (parse_ok == CONTROLLER_ATA) {
126 #ifdef IOCATAREQUEST
127 if ((fdchan->device = open(dev,O_RDONLY))<0) {
128 #else
129 if ((fdchan->atacommand = open("/dev/ata",O_RDWR))<0) {
130 #endif
131 int myerror = errno; //preserve across free call
132 free (fdchan);
133 errno = myerror;
134 return -1;
135 }
136 }
137
138 if (parse_ok == CONTROLLER_3WARE_678K_CHAR) {
139 char buf[512];
140 sprintf(buf,"/dev/twe%d",fdchan->device);
141 #ifdef IOCATAREQUEST
142 if ((fdchan->device = open(buf,O_RDWR))<0) {
143 #else
144 if ((fdchan->atacommand = open(buf,O_RDWR))<0) {
145 #endif
146 int myerror = errno; // preserver across free call
147 free(fdchan);
148 errno=myerror;
149 return -1;
150 }
151 }
152
153 if (parse_ok == CONTROLLER_3WARE_9000_CHAR) {
154 char buf[512];
155 sprintf(buf,"/dev/twa%d",fdchan->device);
156 #ifdef IOCATAREQUEST
157 if ((fdchan->device = open(buf,O_RDWR))<0) {
158 #else
159 if ((fdchan->atacommand = open(buf,O_RDWR))<0) {
160 #endif
161 int myerror = errno; // preserver across free call
162 free(fdchan);
163 errno=myerror;
164 return -1;
165 }
166 }
167
168 if (parse_ok == CONTROLLER_CCISS) {
169 if ((fdchan->device = open(dev,O_RDWR))<0) {
170 int myerror = errno; // preserver across free call
171 free(fdchan);
172 errno=myerror;
173 return -1;
174 }
175 }
176
177 if (parse_ok == CONTROLLER_SCSI) {
178 // this is really a NO-OP, as the parse takes care
179 // of filling in correct details
180 }
181
182 // return pointer to "file descriptor" table entry, properly offset.
183 devicetable[i]=fdchan;
184 return i+FREEBSD_FDOFFSET;
185 }
186
187 // Returns 1 if device not available/open/found else 0. Also shifts fd into valid range.
188 static int isnotopen(int *fd, struct freebsd_dev_channel** fdchan) {
189 // put valid "file descriptor" into range 0...FREEBSD_MAXDEV-1
190 *fd -= FREEBSD_FDOFFSET;
191
192 // check for validity of "file descriptor".
193 if (*fd<0 || *fd>=FREEBSD_MAXDEV || !((*fdchan)=devicetable[*fd])) {
194 errno = ENODEV;
195 return 1;
196 }
197
198 return 0;
199 }
200
201 // Like close(). Acts on handles returned by above function.
202 int deviceclose (int fd) {
203 struct freebsd_dev_channel *fdchan;
204 int failed = 0;
205
206 // check for valid file descriptor
207 if (isnotopen(&fd, &fdchan))
208 return -1;
209
210
211 // did we allocate a SCSI device name?
212 if (fdchan->devname)
213 free(fdchan->devname);
214
215 // close device, if open
216 #ifdef IOCATAREQUEST
217 if (fdchan->device)
218 failed=close(fdchan->device);
219 #else
220 if (fdchan->atacommand)
221 failed=close(fdchan->atacommand);
222 #endif
223
224 if (fdchan->scsicontrol)
225 failed=close(fdchan->scsicontrol);
226
227 // if close succeeded, then remove from device list
228 // Eduard, should we also remove it from list if close() fails? I'm
229 // not sure. Here I only remove it from list if close() worked.
230 if (!failed) {
231 free(fdchan);
232 devicetable[fd]=NULL;
233 }
234
235 return failed;
236 }
237
238 #define NO_RETURN 0
239 #define BAD_SMART 1
240 #define NO_DISK_3WARE 2
241 #define BAD_KERNEL 3
242 #define MAX_MSG 3
243
244 // Utility function for printing warnings
245 void printwarning(int msgNo, const char* extra) {
246 static int printed[] = {0,0,0,0};
247 static const char* message[]={
248 "The SMART RETURN STATUS return value (smartmontools -H option/Directive)\n can not be retrieved with this version of ATAng, please do not rely on this value\nYou should update to at least 5.2\n",
249
250 "Error SMART Status command failed\nPlease get assistance from \n" PACKAGE_HOMEPAGE "\nRegister values returned from SMART Status command are:\n",
251
252 "You must specify a DISK # for 3ware drives with -d 3ware,<n> where <n> begins with 1 for first disk drive\n",
253
254 "ATA support is not provided for this kernel version. Please ugrade to a recent 5-CURRENT kernel (post 09/01/2003 or so)\n"
255 };
256
257 if (msgNo >= 0 && msgNo <= MAX_MSG) {
258 if (!printed[msgNo]) {
259 printed[msgNo] = 1;
260 pout("%s", message[msgNo]);
261 if (extra)
262 pout("%s",extra);
263 }
264 }
265 return;
266 }
267
268 // Interface to ATA devices. See os_linux.c
269
270 int marvell_command_interface(__unused int fd, __unused smart_command_set command, __unused int select, __unused char *data) {
271 return -1;
272 }
273
274 int highpoint_command_interface(__unused int fd, __unused smart_command_set command, __unused int select, __unused char *data) {
275 {
276 return -1;
277 }
278
279 int ata_command_interface(int fd, smart_command_set command, int select, char *data) {
280 #if !defined(ATAREQUEST) && !defined(IOCATAREQUEST)
281 // sorry, but without ATAng, we can't do anything here
282 printwarning(BAD_KERNEL,NULL);
283 errno = ENOSYS;
284 return -1;
285 #else
286 struct freebsd_dev_channel* con;
287 int retval, copydata=0;
288 #ifdef IOCATAREQUEST
289 struct ata_ioc_request request;
290 #else
291 struct ata_cmd iocmd;
292 #endif
293 unsigned char buff[512];
294
295 // check that "file descriptor" is valid
296 if (isnotopen(&fd,&con))
297 return -1;
298
299 bzero(buff,512);
300
301 #ifdef IOCATAREQUEST
302 bzero(&request,sizeof(struct ata_ioc_request));
303 #else
304 bzero(&iocmd,sizeof(struct ata_cmd));
305 #endif
306 bzero(buff,512);
307
308 #ifndef IOCATAREQUEST
309 iocmd.cmd=ATAREQUEST;
310 iocmd.channel=con->channel;
311 iocmd.device=con->device;
312 #define request iocmd.u.request
313 #endif
314
315 request.u.ata.command=ATA_SMART_CMD;
316 request.timeout=600;
317 switch (command){
318 case READ_VALUES:
319 request.u.ata.feature=ATA_SMART_READ_VALUES;
320 request.u.ata.lba=0xc24f<<8;
321 request.flags=ATA_CMD_READ;
322 request.data=(char *)buff;
323 request.count=512;
324 copydata=1;
325 break;
326 case READ_THRESHOLDS:
327 request.u.ata.feature=ATA_SMART_READ_THRESHOLDS;
328 request.u.ata.count=1;
329 request.u.ata.lba=1|(0xc24f<<8);
330 request.flags=ATA_CMD_READ;
331 request.data=(char *)buff;
332 request.count=512;
333 copydata=1;
334 break;
335 case READ_LOG:
336 request.u.ata.feature=ATA_SMART_READ_LOG_SECTOR;
337 request.u.ata.lba=select|(0xc24f<<8);
338 request.u.ata.count=1;
339 request.flags=ATA_CMD_READ;
340 request.data=(char *)buff;
341 request.count=512;
342 copydata=1;
343 break;
344 case IDENTIFY:
345 request.u.ata.command=ATA_IDENTIFY_DEVICE;
346 request.flags=ATA_CMD_READ;
347 request.data=(char *)buff;
348 request.count=512;
349 copydata=1;
350 break;
351 case PIDENTIFY:
352 request.u.ata.command=ATA_IDENTIFY_PACKET_DEVICE;
353 request.flags=ATA_CMD_READ;
354 request.data=(char *)buff;
355 request.count=512;
356 copydata=1;
357 break;
358 case ENABLE:
359 request.u.ata.feature=ATA_SMART_ENABLE;
360 request.u.ata.lba=0xc24f<<8;
361 request.flags=ATA_CMD_CONTROL;
362 break;
363 case DISABLE:
364 request.u.ata.feature=ATA_SMART_DISABLE;
365 request.u.ata.lba=0xc24f<<8;
366 request.flags=ATA_CMD_CONTROL;
367 break;
368 case AUTO_OFFLINE:
369 // NOTE: According to ATAPI 4 and UP, this command is obsolete
370 request.u.ata.feature=ATA_SMART_AUTO_OFFLINE;
371 request.u.ata.lba=0xc24f<<8;
372 request.u.ata.count=select;
373 request.flags=ATA_CMD_CONTROL;
374 break;
375 case AUTOSAVE:
376 request.u.ata.feature=ATA_SMART_AUTOSAVE;
377 request.u.ata.count=0xf1; // to enable autosave
378 request.u.ata.lba=0xc24f<<8;
379 request.flags=ATA_CMD_CONTROL;
380 break;
381 case IMMEDIATE_OFFLINE:
382 request.u.ata.feature=ATA_SMART_IMMEDIATE_OFFLINE;
383 request.u.ata.lba = select|(0xc24f<<8); // put test in sector
384 request.flags=ATA_CMD_CONTROL;
385 break;
386 case STATUS_CHECK: // same command, no HDIO in FreeBSD
387 case STATUS:
388 // this command only says if SMART is working. It could be
389 // replaced with STATUS_CHECK below.
390 request.u.ata.feature=ATA_SMART_STATUS;
391 request.u.ata.lba=0xc24f<<8;
392 request.flags=ATA_CMD_CONTROL;
393 break;
394 default:
395 pout("Unrecognized command %d in ata_command_interface()\n"
396 "Please contact " PACKAGE_BUGREPORT "\n", command);
397 errno=ENOSYS;
398 return -1;
399 }
400
401 if (command==STATUS_CHECK){
402 unsigned const char normal_lo=0x4f, normal_hi=0xc2;
403 unsigned const char failed_lo=0xf4, failed_hi=0x2c;
404 unsigned char low,high;
405
406 #ifdef IOCATAREQUEST
407 if ((retval=ioctl(con->device, IOCATAREQUEST, &request)) || request.error)
408 #else
409 if ((retval=ioctl(con->atacommand, IOCATA, &iocmd)) || request.error)
410 #endif
411 return -1;
412
413 #if __FreeBSD_version < 502000
414 printwarning(NO_RETURN,NULL);
415 #endif
416
417 high = (request.u.ata.lba >> 16) & 0xff;
418 low = (request.u.ata.lba >> 8) & 0xff;
419
420 // Cyl low and Cyl high unchanged means "Good SMART status"
421 if (low==normal_lo && high==normal_hi)
422 return 0;
423
424 // These values mean "Bad SMART status"
425 if (low==failed_lo && high==failed_hi)
426 return 1;
427
428 // We haven't gotten output that makes sense; print out some debugging info
429 char buf[512];
430 sprintf(buf,"CMD=0x%02x\nFR =0x%02x\nNS =0x%02x\nSC =0x%02x\nCL =0x%02x\nCH =0x%02x\nRETURN =0x%04x\n",
431 (int)request.u.ata.command,
432 (int)request.u.ata.feature,
433 (int)request.u.ata.count,
434 (int)((request.u.ata.lba) & 0xff),
435 (int)((request.u.ata.lba>>8) & 0xff),
436 (int)((request.u.ata.lba>>16) & 0xff),
437 (int)request.error);
438 printwarning(BAD_SMART,buf);
439 return 0;
440 }
441
442 #ifdef IOCATAREQUEST
443 if ((retval=ioctl(con->device, IOCATAREQUEST, &request)) || request.error)
444 #else
445 if ((retval=ioctl(con->atacommand, IOCATA, &iocmd)) || request.error)
446 #endif
447 {
448 return -1;
449 }
450 //
451 if (copydata)
452 memcpy(data, buff, 512);
453
454 return 0;
455 #endif
456 }
457
458
459 // Interface to SCSI devices. See os_linux.c
460 int do_normal_scsi_cmnd_io(int fd, struct scsi_cmnd_io * iop, int report)
461 {
462 struct freebsd_dev_channel* con = NULL;
463 struct cam_device* cam_dev = NULL;
464 union ccb *ccb;
465
466
467 if (report > 0) {
468 unsigned int k;
469 const unsigned char * ucp = iop->cmnd;
470 const char * np;
471
472 np = scsi_get_opcode_name(ucp[0]);
473 pout(" [%s: ", np ? np : "<unknown opcode>");
474 for (k = 0; k < iop->cmnd_len; ++k)
475 pout("%02x ", ucp[k]);
476 if ((report > 1) &&
477 (DXFER_TO_DEVICE == iop->dxfer_dir) && (iop->dxferp)) {
478 int trunc = (iop->dxfer_len > 256) ? 1 : 0;
479
480 pout("]\n Outgoing data, len=%d%s:\n", (int)iop->dxfer_len,
481 (trunc ? " [only first 256 bytes shown]" : ""));
482 dStrHex(iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);
483 }
484 else
485 pout("]");
486 }
487
488 // check that "file descriptor" is valid
489 if (isnotopen(&fd,&con))
490 return -ENOTTY;
491
492
493 if (!(cam_dev = cam_open_spec_device(con->devname,con->unitnum,O_RDWR,NULL))) {
494 warnx("%s",cam_errbuf);
495 return -1;
496 }
497
498 if (!(ccb = cam_getccb(cam_dev))) {
499 warnx("error allocating ccb");
500 return -ENOMEM;
501 }
502
503 // clear out structure, except for header that was filled in for us
504 bzero(&(&ccb->ccb_h)[1],
505 sizeof(struct ccb_scsiio) - sizeof(struct ccb_hdr));
506
507 cam_fill_csio(&ccb->csio,
508 /*retrires*/ 1,
509 /*cbfcnp*/ NULL,
510 /* flags */ (iop->dxfer_dir == DXFER_NONE ? CAM_DIR_NONE :(iop->dxfer_dir == DXFER_FROM_DEVICE ? CAM_DIR_IN : CAM_DIR_OUT)),
511 /* tagaction */ MSG_SIMPLE_Q_TAG,
512 /* dataptr */ iop->dxferp,
513 /* datalen */ iop->dxfer_len,
514 /* senselen */ iop->max_sense_len,
515 /* cdblen */ iop->cmnd_len,
516 /* timout (converted to seconds) */ iop->timeout*1000);
517 memcpy(ccb->csio.cdb_io.cdb_bytes,iop->cmnd,iop->cmnd_len);
518
519 if (cam_send_ccb(cam_dev,ccb) < 0) {
520 warn("error sending SCSI ccb");
521 #if __FreeBSD_version > 500000
522 cam_error_print(cam_dev,ccb,CAM_ESF_ALL,CAM_EPF_ALL,stderr);
523 #endif
524 cam_freeccb(ccb);
525 return -1;
526 }
527
528 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
529 #if __FreeBSD_version > 500000
530 cam_error_print(cam_dev,ccb,CAM_ESF_ALL,CAM_EPF_ALL,stderr);
531 #endif
532 cam_freeccb(ccb);
533 return -1;
534 }
535
536 if (iop->sensep) {
537 memcpy(iop->sensep,&(ccb->csio.sense_data),sizeof(struct scsi_sense_data));
538 iop->resp_sense_len = sizeof(struct scsi_sense_data);
539 }
540
541 iop->scsi_status = ccb->csio.scsi_status;
542
543 cam_freeccb(ccb);
544
545 if (cam_dev)
546 cam_close_device(cam_dev);
547
548 if (report > 0) {
549 int trunc;
550
551 pout(" status=0\n");
552 trunc = (iop->dxfer_len > 256) ? 1 : 0;
553
554 pout(" Incoming data, len=%d%s:\n", (int)iop->dxfer_len,
555 (trunc ? " [only first 256 bytes shown]" : ""));
556 dStrHex(iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);
557 }
558 return 0;
559 }
560
561 /* Check and call the right interface. Maybe when the do_generic_scsi_cmd_io interface is better
562 we can take off this crude way of calling the right interface */
563 int do_scsi_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop, int report)
564 {
565 struct freebsd_dev_channel *fdchan;
566 switch(con->controller_type)
567 {
568 case CONTROLLER_CCISS:
569 // check that "file descriptor" is valid
570 if (isnotopen(&dev_fd,&fdchan))
571 return -ENOTTY;
572 #ifdef HAVE_DEV_CISS_CISSIO_H
573 return cciss_io_interface(fdchan->device, con->controller_port-1, iop, report);
574 #else
575 {
576 static int warned = 0;
577 if (!warned) {
578 pout("CCISS support is not available in this build of smartmontools,\n"
579 "/usr/src/sys/dev/ciss/cissio.h was not available at build time.\n\n");
580 warned = 1;
581 }
582 }
583 errno = ENOSYS;
584 return -1;
585 #endif
586 // not reached
587 break;
588 default:
589 return do_normal_scsi_cmnd_io(dev_fd, iop, report);
590 // not reached
591 break;
592 }
593 }
594
595 // Interface to ATA devices behind 3ware escalade RAID controller cards. See os_linux.c
596
597 #define BUFFER_LEN_678K_CHAR ( sizeof(struct twe_usercommand) ) // 520
598 #define BUFFER_LEN_9000_CHAR ( sizeof(TW_OSLI_IOCTL_NO_DATA_BUF) + sizeof(TWE_Command) ) // 2048
599 #define TW_IOCTL_BUFFER_SIZE ( MAX(BUFFER_LEN_678K_CHAR, BUFFER_LEN_9000_CHAR) )
600
601 int escalade_command_interface(int fd, int disknum, int escalade_type, smart_command_set command, int select, char *data) {
602 // to hold true file descriptor
603 struct freebsd_dev_channel* con;
604
605 // return value and buffer for ioctl()
606 int ioctlreturn, readdata=0;
607 struct twe_usercommand* cmd_twe = NULL;
608 TW_OSLI_IOCTL_NO_DATA_BUF* cmd_twa = NULL;
609 TWE_Command_ATA* ata = NULL;
610
611 // Used by both the SCSI and char interfaces
612 char ioctl_buffer[TW_IOCTL_BUFFER_SIZE];
613
614 if (disknum < 0) {
615 printwarning(NO_DISK_3WARE,NULL);
616 return -1;
617 }
618
619 // check that "file descriptor" is valid
620 if (isnotopen(&fd,&con))
621 return -1;
622
623 memset(ioctl_buffer, 0, TW_IOCTL_BUFFER_SIZE);
624
625 if (escalade_type==CONTROLLER_3WARE_9000_CHAR) {
626 cmd_twa = (TW_OSLI_IOCTL_NO_DATA_BUF*)ioctl_buffer;
627 cmd_twa->pdata = ((TW_OSLI_IOCTL_WITH_PAYLOAD*)cmd_twa)->payload.data_buf;
628 cmd_twa->driver_pkt.buffer_length = 512;
629 ata = (TWE_Command_ATA*)&cmd_twa->cmd_pkt.command.cmd_pkt_7k;
630 } else if (escalade_type==CONTROLLER_3WARE_678K_CHAR) {
631 cmd_twe = (struct twe_usercommand*)ioctl_buffer;
632 ata = &cmd_twe->tu_command.ata;
633 } else {
634 pout("Unrecognized escalade_type %d in freebsd_3ware_command_interface(disk %d)\n"
635 "Please contact " PACKAGE_BUGREPORT "\n", escalade_type, disknum);
636 errno=ENOSYS;
637 return -1;
638 }
639
640 ata->opcode = TWE_OP_ATA_PASSTHROUGH;
641
642 // Same for (almost) all commands - but some reset below
643 ata->request_id = 0xFF;
644 ata->unit = disknum;
645 ata->status = 0;
646 ata->flags = 0x1;
647 ata->drive_head = 0x0;
648 ata->sector_num = 0;
649
650 // All SMART commands use this CL/CH signature. These are magic
651 // values from the ATA specifications.
652 ata->cylinder_lo = 0x4F;
653 ata->cylinder_hi = 0xC2;
654
655 // SMART ATA COMMAND REGISTER value
656 ata->command = ATA_SMART_CMD;
657
658 // Is this a command that reads or returns 512 bytes?
659 // passthru->param values are:
660 // 0x0 - non data command without TFR write check,
661 // 0x8 - non data command with TFR write check,
662 // 0xD - data command that returns data to host from device
663 // 0xF - data command that writes data from host to device
664 // passthru->size values are 0x5 for non-data and 0x07 for data
665 if (command == READ_VALUES ||
666 command == READ_THRESHOLDS ||
667 command == READ_LOG ||
668 command == IDENTIFY ||
669 command == WRITE_LOG ) {
670 readdata=1;
671 if (escalade_type==CONTROLLER_3WARE_678K_CHAR) {
672 cmd_twe->tu_data = data;
673 cmd_twe->tu_size = 512;
674 }
675 ata->sgl_offset = 0x5;
676 ata->size = 0x5;
677 ata->param = 0xD;
678 ata->sector_count = 0x1;
679 // For 64-bit to work correctly, up the size of the command packet
680 // in dwords by 1 to account for the 64-bit single sgl 'address'
681 // field. Note that this doesn't agree with the typedefs but it's
682 // right (agree with kernel driver behavior/typedefs).
683 //if (sizeof(long)==8)
684 // ata->size++;
685 }
686 else {
687 // Non data command -- but doesn't use large sector
688 // count register values.
689 ata->sgl_offset = 0x0;
690 ata->size = 0x5;
691 ata->param = 0x8;
692 ata->sector_count = 0x0;
693 }
694
695 // Now set ATA registers depending upon command
696 switch (command){
697 case CHECK_POWER_MODE:
698 ata->command = ATA_CHECK_POWER_MODE;
699 ata->features = 0;
700 ata->cylinder_lo = 0;
701 ata->cylinder_hi = 0;
702 break;
703 case READ_VALUES:
704 ata->features = ATA_SMART_READ_VALUES;
705 break;
706 case READ_THRESHOLDS:
707 ata->features = ATA_SMART_READ_THRESHOLDS;
708 break;
709 case READ_LOG:
710 ata->features = ATA_SMART_READ_LOG_SECTOR;
711 // log number to return
712 ata->sector_num = select;
713 break;
714 case WRITE_LOG:
715 readdata=0;
716 ata->features = ATA_SMART_WRITE_LOG_SECTOR;
717 ata->sector_count = 1;
718 ata->sector_num = select;
719 ata->param = 0xF; // PIO data write
720 break;
721 case IDENTIFY:
722 // ATA IDENTIFY DEVICE
723 ata->command = ATA_IDENTIFY_DEVICE;
724 ata->features = 0;
725 ata->cylinder_lo = 0;
726 ata->cylinder_hi = 0;
727 break;
728 case PIDENTIFY:
729 // 3WARE controller can NOT have packet device internally
730 pout("WARNING - NO DEVICE FOUND ON 3WARE CONTROLLER (disk %d)\n", disknum);
731 errno=ENODEV;
732 return -1;
733 case ENABLE:
734 ata->features = ATA_SMART_ENABLE;
735 break;
736 case DISABLE:
737 ata->features = ATA_SMART_DISABLE;
738 break;
739 case AUTO_OFFLINE:
740 ata->features = ATA_SMART_AUTO_OFFLINE;
741 // Enable or disable?
742 ata->sector_count = select;
743 break;
744 case AUTOSAVE:
745 ata->features = ATA_SMART_AUTOSAVE;
746 // Enable or disable?
747 ata->sector_count = select;
748 break;
749 case IMMEDIATE_OFFLINE:
750 ata->features = ATA_SMART_IMMEDIATE_OFFLINE;
751 // What test type to run?
752 ata->sector_num = select;
753 break;
754 case STATUS_CHECK:
755 ata->features = ATA_SMART_STATUS;
756 break;
757 case STATUS:
758 // This is JUST to see if SMART is enabled, by giving SMART status
759 // command. But it doesn't say if status was good, or failing.
760 // See below for the difference.
761 ata->features = ATA_SMART_STATUS;
762 break;
763 default:
764 pout("Unrecognized command %d in freebsd_3ware_command_interface(disk %d)\n"
765 "Please contact " PACKAGE_BUGREPORT "\n", command, disknum);
766 errno=ENOSYS;
767 return -1;
768 }
769
770 // Now send the command down through an ioctl()
771 if (escalade_type==CONTROLLER_3WARE_9000_CHAR) {
772 #ifdef IOCATAREQUEST
773 ioctlreturn=ioctl(con->device,TW_OSL_IOCTL_FIRMWARE_PASS_THROUGH,cmd_twa);
774 #else
775 ioctlreturn=ioctl(con->atacommand,TW_OSL_IOCTL_FIRMWARE_PASS_THROUGH,cmd_twa);
776 #endif
777 } else {
778 #ifdef IOCATAREQUEST
779 ioctlreturn=ioctl(con->device,TWEIO_COMMAND,cmd_twe);
780 #else
781 ioctlreturn=ioctl(con->atacommand,TWEIO_COMMAND,cmd_twe);
782 #endif
783 }
784
785 // Deal with the different error cases
786 if (ioctlreturn) {
787 if (!errno)
788 errno=EIO;
789 return -1;
790 }
791
792 // See if the ATA command failed. Now that we have returned from
793 // the ioctl() call, if passthru is valid, then:
794 // - ata->status contains the 3ware controller STATUS
795 // - ata->command contains the ATA STATUS register
796 // - ata->features contains the ATA ERROR register
797 //
798 // Check bits 0 (error bit) and 5 (device fault) of the ATA STATUS
799 // If bit 0 (error bit) is set, then ATA ERROR register is valid.
800 // While we *might* decode the ATA ERROR register, at the moment it
801 // doesn't make much sense: we don't care in detail why the error
802 // happened.
803
804 if (ata->status || (ata->command & 0x21)) {
805 pout("Command failed, ata.status=(0x%2.2x), ata.command=(0x%2.2x), ata.flags=(0x%2.2x)\n",ata->status,ata->command,ata->flags);
806 errno=EIO;
807 return -1;
808 }
809
810 // If this is a read data command, copy data to output buffer
811 if (readdata) {
812 if (escalade_type==CONTROLLER_3WARE_9000_CHAR)
813 memcpy(data, cmd_twa->pdata, 512);
814 }
815
816 // For STATUS_CHECK, we need to check register values
817 if (command==STATUS_CHECK) {
818
819 // To find out if the SMART RETURN STATUS is good or failing, we
820 // need to examine the values of the Cylinder Low and Cylinder
821 // High Registers.
822
823 unsigned short cyl_lo=ata->cylinder_lo;
824 unsigned short cyl_hi=ata->cylinder_hi;
825
826 // If values in Cyl-LO and Cyl-HI are unchanged, SMART status is good.
827 if (cyl_lo==0x4F && cyl_hi==0xC2)
828 return 0;
829
830 // If values in Cyl-LO and Cyl-HI are as follows, SMART status is FAIL
831 if (cyl_lo==0xF4 && cyl_hi==0x2C)
832 return 1;
833
834 errno=EIO;
835 return -1;
836 }
837
838 // copy sector count register (one byte!) to return data
839 if (command==CHECK_POWER_MODE)
840 *data=*(char *)&(ata->sector_count);
841
842 // look for nonexistent devices/ports
843 if (command==IDENTIFY && !nonempty((unsigned char *)data, 512)) {
844 errno=ENODEV;
845 return -1;
846 }
847
848 return 0;
849 }
850
851 static int get_tw_channel_unit (const char* name, int* unit, int* dev) {
852 const char *p;
853
854 /* device node sanity check */
855 for (p = name + 3; *p; p++)
856 if (*p < '0' || *p > '9')
857 return -1;
858 if (strlen(name) > 4 && *(name + 3) == '0')
859 return -1;
860
861 if (dev != NULL)
862 *dev=atoi(name + 3);
863
864 /* no need for unit number */
865 if (unit != NULL)
866 *unit=0;
867 return 0;
868 }
869
870
871 #ifndef IOCATAREQUEST
872 static int get_ata_channel_unit ( const char* name, int* unit, int* dev) {
873 #ifndef ATAREQUEST
874 *dev=0;
875 *unit=0;
876 return 0;
877 #else
878 // there is no direct correlation between name 'ad0, ad1, ...' and
879 // channel/unit number. So we need to iterate through the possible
880 // channels and check each unit to see if we match names
881 struct ata_cmd iocmd;
882 int fd,maxunit;
883
884 bzero(&iocmd, sizeof(struct ata_cmd));
885
886 if ((fd = open("/dev/ata", O_RDWR)) < 0)
887 return -errno;
888
889 iocmd.cmd = ATAGMAXCHANNEL;
890 if (ioctl(fd, IOCATA, &iocmd) < 0) {
891 return -errno;
892 close(fd);
893 }
894 maxunit = iocmd.u.maxchan;
895 for (*unit = 0; *unit < maxunit; (*unit)++) {
896 iocmd.channel = *unit;
897 iocmd.device = -1;
898 iocmd.cmd = ATAGPARM;
899 if (ioctl(fd, IOCATA, &iocmd) < 0) {
900 close(fd);
901 return -errno;
902 }
903 if (iocmd.u.param.type[0] && !strcmp(name,iocmd.u.param.name[0])) {
904 *dev = 0;
905 break;
906 }
907 if (iocmd.u.param.type[1] && !strcmp(name,iocmd.u.param.name[1])) {
908 *dev = 1;
909 break;
910 }
911 }
912 close(fd);
913 if (*unit == maxunit)
914 return -1;
915 else
916 return 0;
917 #endif
918 }
919 #endif
920
921 // Guess device type (ata or scsi) based on device name (FreeBSD
922 // specific) SCSI device name in FreeBSD can be sd, sr, scd, st, nst,
923 // osst, nosst and sg.
924 static const char * fbsd_dev_prefix = "/dev/";
925 static const char * fbsd_dev_ata_disk_prefix = "ad";
926 static const char * fbsd_dev_scsi_disk_plus = "da";
927 static const char * fbsd_dev_scsi_tape1 = "sa";
928 static const char * fbsd_dev_scsi_tape2 = "nsa";
929 static const char * fbsd_dev_scsi_tape3 = "esa";
930 static const char * fbsd_dev_twe_ctrl = "twe";
931 static const char * fbsd_dev_twa_ctrl = "twa";
932 static const char * fbsd_dev_cciss = "ciss";
933
934 static int parse_ata_chan_dev(const char * dev_name, struct freebsd_dev_channel *chan) {
935 int len;
936 int dev_prefix_len = strlen(fbsd_dev_prefix);
937
938 // if dev_name null, or string length zero
939 if (!dev_name || !(len = strlen(dev_name)))
940 return CONTROLLER_UNKNOWN;
941
942 // Remove the leading /dev/... if it's there
943 if (!strncmp(fbsd_dev_prefix, dev_name, dev_prefix_len)) {
944 if (len <= dev_prefix_len)
945 // if nothing else in the string, unrecognized
946 return CONTROLLER_UNKNOWN;
947 // else advance pointer to following characters
948 dev_name += dev_prefix_len;
949 }
950 // form /dev/ad* or ad*
951 if (!strncmp(fbsd_dev_ata_disk_prefix, dev_name,
952 strlen(fbsd_dev_ata_disk_prefix))) {
953 #ifndef IOCATAREQUEST
954 if (chan != NULL) {
955 if (get_ata_channel_unit(dev_name,&(chan->channel),&(chan->device))<0) {
956 return CONTROLLER_UNKNOWN;
957 }
958 }
959 #endif
960 return CONTROLLER_ATA;
961 }
962
963 // form /dev/da* or da*
964 if (!strncmp(fbsd_dev_scsi_disk_plus, dev_name,
965 strlen(fbsd_dev_scsi_disk_plus)))
966 goto handlescsi;
967
968 // form /dev/sa* or sa*
969 if (!strncmp(fbsd_dev_scsi_tape1, dev_name,
970 strlen(fbsd_dev_scsi_tape1)))
971 goto handlescsi;
972
973 // form /dev/nsa* or nsa*
974 if (!strncmp(fbsd_dev_scsi_tape2, dev_name,
975 strlen(fbsd_dev_scsi_tape2)))
976 goto handlescsi;
977
978 // form /dev/esa* or esa*
979 if (!strncmp(fbsd_dev_scsi_tape3, dev_name,
980 strlen(fbsd_dev_scsi_tape3)))
981 goto handlescsi;
982
983 if (!strncmp(fbsd_dev_twa_ctrl,dev_name,
984 strlen(fbsd_dev_twa_ctrl))) {
985 if (chan != NULL) {
986 if (get_tw_channel_unit(dev_name,&(chan->channel),&(chan->device))<0) {
987 return CONTROLLER_UNKNOWN;
988 }
989 }
990 else if (get_tw_channel_unit(dev_name,NULL,NULL)<0) {
991 return CONTROLLER_UNKNOWN;
992 }
993 return CONTROLLER_3WARE_9000_CHAR;
994 }
995
996 if (!strncmp(fbsd_dev_twe_ctrl,dev_name,
997 strlen(fbsd_dev_twe_ctrl))) {
998 if (chan != NULL) {
999 if (get_tw_channel_unit(dev_name,&(chan->channel),&(chan->device))<0) {
1000 return CONTROLLER_UNKNOWN;
1001 }
1002 }
1003 else if (get_tw_channel_unit(dev_name,NULL,NULL)<0) {
1004 return CONTROLLER_UNKNOWN;
1005 }
1006 return CONTROLLER_3WARE_678K_CHAR;
1007 }
1008 // form /dev/ciss*
1009 if (!strncmp(fbsd_dev_cciss, dev_name,
1010 strlen(fbsd_dev_cciss)))
1011 return CONTROLLER_CCISS;
1012
1013 // we failed to recognize any of the forms
1014 return CONTROLLER_UNKNOWN;
1015
1016 handlescsi:
1017 if (chan != NULL) {
1018 if (!(chan->devname = (char *)calloc(1,DEV_IDLEN+1)))
1019 return CONTROLLER_UNKNOWN;
1020
1021 if (cam_get_device(dev_name,chan->devname,DEV_IDLEN,&(chan->unitnum)) == -1)
1022 return CONTROLLER_UNKNOWN;
1023 }
1024 return CONTROLLER_SCSI;
1025
1026 }
1027
1028 int guess_device_type (const char* dev_name) {
1029 return parse_ata_chan_dev(dev_name,NULL);
1030 }
1031
1032 // global variable holding byte count of allocated memory
1033 extern long long bytes;
1034
1035 // we are going to take advantage of the fact that FreeBSD's devfs will only
1036 // have device entries for devices that exist. So if we get the equivilent of
1037 // ls /dev/ad?, we have all the ATA devices on the system
1038 //
1039 // If any errors occur, leave errno set as it was returned by the
1040 // system call, and return <0.
1041
1042 // Return values:
1043 // -1 out of memory
1044 // -2 to -5 errors in glob
1045
1046 int get_dev_names(char*** names, const char* prefix) {
1047 int n = 0;
1048 char** mp;
1049 int retglob,lim;
1050 glob_t globbuf;
1051 int i;
1052 char pattern1[128],pattern2[128];
1053
1054 bzero(&globbuf,sizeof(globbuf));
1055 // in case of non-clean exit
1056 *names=NULL;
1057
1058 // handle 0-99 possible devices, will still be limited by MAX_NUM_DEV
1059 sprintf(pattern1,"/dev/%s[0-9]",prefix);
1060 sprintf(pattern2,"/dev/%s[0-9][0-9]",prefix);
1061
1062 // Use glob to look for any directory entries matching the patterns
1063 // first call inits with first pattern match, second call appends
1064 // to first list. GLOB_NOCHECK results in no error if no more matches
1065 // found, however it does append the actual pattern to the list of
1066 // paths....
1067 if ((retglob=glob(pattern1, GLOB_ERR|GLOB_NOCHECK, NULL, &globbuf)) ||
1068 (retglob=glob(pattern2, GLOB_ERR|GLOB_APPEND|GLOB_NOCHECK,NULL,&globbuf))) {
1069 int retval = -1;
1070 // glob failed
1071 if (retglob==GLOB_NOSPACE)
1072 pout("glob(3) ran out of memory matching patterns (%s),(%s)\n",
1073 pattern1, pattern2);
1074 else if (retglob==GLOB_ABORTED)
1075 pout("glob(3) aborted matching patterns (%s),(%s)\n",
1076 pattern1, pattern2);
1077 else if (retglob==GLOB_NOMATCH) {
1078 pout("glob(3) found no matches for patterns (%s),(%s)\n",
1079 pattern1, pattern2);
1080 retval = 0;
1081 }
1082 else if (retglob)
1083 pout("Unexplained error in glob(3) of patterns (%s),(%s)\n",
1084 pattern1, pattern2);
1085
1086 // Free memory and return
1087 globfree(&globbuf);
1088
1089 return retval;
1090 }
1091
1092 // did we find too many paths?
1093 lim = globbuf.gl_pathc < MAX_NUM_DEV ? globbuf.gl_pathc : MAX_NUM_DEV;
1094 if (lim < globbuf.gl_pathc)
1095 pout("glob(3) found %d > MAX=%d devices matching patterns (%s),(%s): ignoring %d paths\n",
1096 globbuf.gl_pathc, MAX_NUM_DEV, pattern1,pattern2,
1097 globbuf.gl_pathc-MAX_NUM_DEV);
1098
1099 // allocate space for up to lim number of ATA devices
1100 if (!(mp = (char **)calloc(lim, sizeof(char*)))){
1101 pout("Out of memory constructing scan device list\n");
1102 return -1;
1103 }
1104
1105 // now step through the list returned by glob. No link checking needed
1106 // in FreeBSD
1107 for (i=0; i<globbuf.gl_pathc; i++){
1108 // because of the NO_CHECK in calls to glob,
1109 // the pattern itself will be added to path list..
1110 // so ignore any paths that have the ']' from pattern
1111 if (strchr(globbuf.gl_pathv[i],']') == NULL)
1112 mp[n++] = CustomStrDup(globbuf.gl_pathv[i], 1, __LINE__, filenameandversion);
1113 }
1114
1115 globfree(&globbuf);
1116 mp = (char **)realloc(mp,n*(sizeof(char*))); // shrink to correct size
1117 bytes += (n)*(sizeof(char*)); // and set allocated byte count
1118 *names=mp;
1119 return n;
1120 }
1121
1122 int make_device_names (char*** devlist, const char* name) {
1123 if (!strcmp(name,"SCSI"))
1124 return get_dev_names(devlist,"da");
1125 else if (!strcmp(name,"ATA"))
1126 return get_dev_names(devlist,"ad");
1127 else
1128 return 0;
1129 }