#include "int64.h"
#include "atacmds.h"
#include "scsicmds.h"
+#include "cciss.h"
#include "utility.h"
+#include "extern.h"
#include "os_freebsd.h"
-static const char *filenameandversion="$Id: os_freebsd.cpp,v 1.51 2006/09/17 03:17:53 dpgilbert Exp $";
+static const char *filenameandversion="$Id: os_freebsd.cpp,v 1.54 2007/09/06 08:48:55 ballen4705 Exp $";
-const char *os_XXXX_c_cvsid="$Id: os_freebsd.cpp,v 1.51 2006/09/17 03:17:53 dpgilbert Exp $" \
+const char *os_XXXX_c_cvsid="$Id: os_freebsd.cpp,v 1.54 2007/09/06 08:48:55 ballen4705 Exp $" \
ATACMDS_H_CVSID CONFIG_H_CVSID INT64_H_CVSID OS_FREEBSD_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
// to hold onto exit code for atexit routine
extern int exitstatus;
+extern smartmonctrl * con;
+
// Private table of open devices: guaranteed zero on startup since
// part of static data.
struct freebsd_dev_channel *devicetable[FREEBSD_MAXDEV];
}
// Like open(). Return positive integer handle, used by functions below only. mode=="ATA" or "SCSI".
-int deviceopen (const char* dev, char* mode __unused) {
+int deviceopen (const char* dev, __unused char* mode) {
struct freebsd_dev_channel *fdchan;
int parse_ok, i;
}
}
+ if (parse_ok == CONTROLLER_CCISS) {
+ if ((fdchan->device = open(dev,O_RDWR))<0) {
+ int myerror = errno; // preserver across free call
+ free(fdchan);
+ errno=myerror;
+ return -1;
+ }
+ }
+
if (parse_ok == CONTROLLER_SCSI) {
// this is really a NO-OP, as the parse takes care
// of filling in correct details
return;
}
-
// Interface to ATA devices. See os_linux.c
-int marvell_command_interface(int fd __unused, smart_command_set command __unused, int select __unused, char *data __unused) {
- return -1;
+
+int marvell_command_interface(__unused int fd, __unused smart_command_set command, __unused int select, __unused char *data) {
+ return -1;
}
-int highpoint_command_interface(int fd __unused, smart_command_set command __unused, int select __unused, char *data __unused)
+int highpoint_command_interface(__unused int fd, __unused smart_command_set command, __unused int select, __unused char *data) {
{
return -1;
}
// Interface to SCSI devices. See os_linux.c
-int do_scsi_cmnd_io(int fd, struct scsi_cmnd_io * iop, int report)
+int do_normal_scsi_cmnd_io(int fd, struct scsi_cmnd_io * iop, int report)
{
struct freebsd_dev_channel* con = NULL;
struct cam_device* cam_dev = NULL;
return 0;
}
+/* Check and call the right interface. Maybe when the do_generic_scsi_cmd_io interface is better
+ we can take off this crude way of calling the right interface */
+int do_scsi_cmnd_io(int dev_fd, struct scsi_cmnd_io * iop, int report)
+{
+struct freebsd_dev_channel *fdchan;
+ switch(con->controller_type)
+ {
+ case CONTROLLER_CCISS:
+ // check that "file descriptor" is valid
+ if (isnotopen(&dev_fd,&fdchan))
+ return -ENOTTY;
+#ifdef HAVE_DEV_CISS_CISSIO_H
+ return cciss_io_interface(fdchan->device, con->controller_port-1, iop, report);
+#else
+ {
+ static int warned = 0;
+ if (!warned) {
+ pout("CCISS support is not available in this build of smartmontools,\n"
+ "/usr/src/sys/dev/ciss/cissio.h was not available at build time.\n\n");
+ warned = 1;
+ }
+ }
+ errno = ENOSYS;
+ return -1;
+#endif
+ // not reached
+ break;
+ default:
+ return do_normal_scsi_cmnd_io(dev_fd, iop, report);
+ // not reached
+ break;
+ }
+}
+
// Interface to ATA devices behind 3ware escalade RAID controller cards. See os_linux.c
#define BUFFER_LEN_678K_CHAR ( sizeof(struct twe_usercommand) ) // 520
// Same for (almost) all commands - but some reset below
ata->request_id = 0xFF;
- ata->unit = disknum;
- ata->host_id = 0;
+ ata->unit = disknum;
ata->status = 0;
ata->flags = 0x1;
ata->drive_head = 0x0;
static const char * fbsd_dev_scsi_tape3 = "esa";
static const char * fbsd_dev_twe_ctrl = "twe";
static const char * fbsd_dev_twa_ctrl = "twa";
+static const char * fbsd_dev_cciss = "ciss";
static int parse_ata_chan_dev(const char * dev_name, struct freebsd_dev_channel *chan) {
int len;
}
return CONTROLLER_3WARE_678K_CHAR;
}
+ // form /dev/ciss*
+ if (!strncmp(fbsd_dev_cciss, dev_name,
+ strlen(fbsd_dev_cciss)))
+ return CONTROLLER_CCISS;
// we failed to recognize any of the forms
return CONTROLLER_UNKNOWN;
// Use glob to look for any directory entries matching the patterns
// first call inits with first pattern match, second call appends
- // to first list. Turn on NOCHECK for second call. This results in no
- // error if no more matches found, however it does append the actual
- // pattern to the list of paths....
- if ((retglob=glob(pattern1, GLOB_ERR, NULL, &globbuf)) ||
+ // to first list. GLOB_NOCHECK results in no error if no more matches
+ // found, however it does append the actual pattern to the list of
+ // paths....
+ if ((retglob=glob(pattern1, GLOB_ERR|GLOB_NOCHECK, NULL, &globbuf)) ||
(retglob=glob(pattern2, GLOB_ERR|GLOB_APPEND|GLOB_NOCHECK,NULL,&globbuf))) {
int retval = -1;
// glob failed
return retval;
}
- // did we find too many paths?
// did we find too many paths?
lim = globbuf.gl_pathc < MAX_NUM_DEV ? globbuf.gl_pathc : MAX_NUM_DEV;
if (lim < globbuf.gl_pathc)
// now step through the list returned by glob. No link checking needed
// in FreeBSD
for (i=0; i<globbuf.gl_pathc; i++){
- // becuase of the NO_CHECK on second call to glob,
+ // because of the NO_CHECK in calls to glob,
// the pattern itself will be added to path list..
// so ignore any paths that have the ']' from pattern
if (strchr(globbuf.gl_pathv[i],']') == NULL)