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