/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include "mhd_local.h"
#include <ftw.h>
#include <libgen.h>
/*
* manipulate drives
*/
/*
* null list constant
*/
/*
* add drive to list
*/
void
)
{
/* add drive to list */
}
}
/*
* delete drive from list
*/
void
)
{
uint_t i;
/* delete drive from list */
break;
}
}
/*
* free drive list
*/
void
)
{
}
/*
* manipulate drive state
*/
int
)
{
/* check lock */
/* set state and kick thread */
MHDPRINTF2(("%s: state 0x%x now 0x%x\n",
/* if this is the last PROBING drive, disable any failfast */
++cnt;
}
if (cnt == 0) {
}
return (-1);
}
}
}
/* return success */
return (0);
}
int
)
{
}
static int
)
{
}
/*
* idle a drive
*/
int
)
{
/* check lock */
/* wait for thread to idle */
for (;;) {
if (DRIVE_IS_IDLE(dp))
return (0);
return (-1);
}
}
/*
* reserve the drive
*/
static int
)
{
int err;
/* check locks */
/* setup timeouts */
/* reserve drive */
if (! serial)
if (! serial)
if (err != 0) {
return (-1);
}
/* return success */
return (0);
}
/*
* failfast the drive
*/
static int
)
{
int err;
/* check locks */
/* failfast drive */
if (! serial)
if (! serial)
if (err != 0) {
return (-1);
}
/* return success */
MHDPRINTF(("%s: MHIOCENFAILFAST%s: succeeded\n",
return (0);
}
/*
* release the drive
*/
static int
)
{
int err;
/* check locks */
/* disable failfast */
if (! serial)
if (! serial)
if (err != 0) {
return (-1);
}
MHDPRINTF(("%s: MHIOCENFAILFAST (release): succeeded\n",
/* release drive */
if (! serial)
if (! serial)
if (err != 0) {
return (-1);
}
/* return success */
return (0);
}
/*
* probe the drive
*/
static int
)
{
int err;
/* check locks */
/* get status (we may get dumped from PROBING here) */
if (! serial)
if (! serial)
return (0);
/* update status */
if (err == 1) {
MHDPRINTF(("%s: MHIOCSTATUS: reserved\n",
} else if (err != 0) {
} else {
MHDPRINTF(("%s: MHIOCSTATUS: available\n",
}
}
/* update time or die */
/* check our drive */
if (err == 0) {
} else if (err == 1) {
mhd_eprintf("%s: %s: reservation conflict\n",
mhd_ff_die(sp);
}
/* check other drives */
}
/* return success */
return (0);
}
/*
* cached controller map
*/
typedef struct {
char *regexpr1;
char *regexpr2;
char *scan;
/*
* free up controller map
*/
static void
free_map()
{
size_t i;
for (i = 0; (i < ctlr_num); ++i) {
}
ctlr_num = 0;
}
/*
* unlock controller map
*/
static void
{
}
/*
* update controller map and lock it
*/
static int
{
/* see if map file has changed */
goto out;
}
rval = 0;
goto out;
}
/* trade up to writer lock, check again */
rval = 0;
goto out;
}
if (ctlr_mtime != 0)
mhd_eprintf("updating controller map\n");
/* toss existing cache */
free_map();
/* parse md.ctlrmap */
goto out;
}
/* skip blank lines and comments */
continue;
/* parse line */
mhd_eprintf("%s: bad regex(es) '%s'\n",
METACTLRMAP, line);
continue;
}
/* add to cache */
}
goto out;
}
goto out;
}
/* success */
rval = 0;
/* return success */
out:
if (rval != 0) {
return (-1);
}
return (0);
}
static char *
char *path
)
{
char *devicesname, *p;
return (NULL);
}
/* strip off the "ssd@..." portion of the devices name */
*p = '\0';
/* strip off the "../../" in front of "devices" */
return (NULL);
}
}
struct pln_cache {
char *pln_name;
};
/* singled threaded by caller */
static void
char *pln_name,
enum mhd_ctlrtype_t ctype
)
{
struct pln_cache *p;
p = Malloc(sizeof (*p));
p->next = pln_cache_anchor;
pln_cache_anchor = p;
}
/* singled threaded by caller */
static int
char *pln_name,
enum mhd_ctlrtype_t *ctype_ret
)
{
struct pln_cache *p;
return (1);
}
}
return (0);
}
static void
free_pln_cache(void)
{
(void) mutex_lock(&mhd_pln_mx);
for (p = pln_cache_anchor; p != NULL; p = n) {
n = p->next;
Free(p);
}
(void) mutex_unlock(&mhd_pln_mx);
}
/*
* match on SSA Model 200.
*/
static void
char *path
)
{
int fd;
char *pln_ctlr_name;
char *p;
return;
(void) mutex_lock(&mhd_pln_mx);
(void) mutex_unlock(&mhd_pln_mx);
if (ctype != MHD_CTLR_SSA200)
return;
/* over-ride for SSA200 */
return;
}
(void) mutex_unlock(&mhd_pln_mx);
return;
}
(void) mutex_unlock(&mhd_pln_mx);
MHDPRINTF(("%s: USCSICMD(SCMD_INQUIRY): failed errno %d\n",
pln_ctlr_name, errno));
return;
}
/* Make all trailing spaces be null char */
p--) {
if (*p == '\0')
continue;
if (!isspace(*p))
break;
*p = '\0';
}
goto out;
/* over-ride the ctype, and tray */
out:
(void) mutex_unlock(&mhd_pln_mx);
}
/*
* get controller info
*/
static void
char *path
)
{
uint_t i;
char *p;
const char *fmt;
/* update and lock controller map */
if (update_map() != 0)
return; /* give up */
/* look for match in cache */
for (i = 0; (i < ctlr_num); ++i) {
break;
}
}
/* unlock controller map */
unlock_map();
}
/*
* get unique drive ID
*/
static int
)
{
int len;
int err;
/* check locks */
/* reset ID */
/* get serial number */
if (! serial)
if (! serial)
if (err != 0) {
"%s: USCSICMD(SCMD_INQUIRY): failed errno %d\n",
} else {
char *p, *e;
uint_t i;
MHDPRINTF(("%s: USCSICMD(SCMD_INQUIRY): success\n",
for (i = 0;
for (i = 0;
for (i = 0;
((i < sizeof (inq.inq_revision)) && (p < e)); ++i)
*p++ = inq.inq_revision[i];
for (i = 0;
((i < sizeof (inq.inq_serial)) && (p < e)); ++i)
*p++ = inq.inq_serial[i];
assert(p == e);
if (*p == '\0')
*p = ' ';
}
}
} else {
}
/* get VTOC */
if (! serial)
if (! serial)
if (err < 0) {
MHDPRINTF(("%s: read_extvtoc: failed errno %d\n",
} else {
MHDPRINTF(("%s: read_extvtoc: success\n",
}
} else {
}
/* get controller info */
if (! serial)
if (! serial)
len = -1;
}
if (len < 0) {
MHDPRINTF(("%s: readlink: failed errno %d\n",
} else {
MHDPRINTF(("%s: readlink: success\n",
}
} else {
}
/* return success */
return (0);
}
/*
* disk thread
*/
static void
)
{
/* wait for dp->dr_thread to be filled in */
/* forever */
for (;;) {
/* check locks */
/* check for changed set */
MHDPRINTF2(("%s: changed from set '%s' to '%s'\n",
}
/* open drive, if necessary */
if (! serial)
if (! serial)
}
continue;
}
/* dispatch */
case DRIVE_IDLE:
break;
case DRIVE_ERRORED:
MHDPRINTF1(("%s: ERRORED %d\n",
break;
case DRIVE_IDLING:
continue;
case DRIVE_RESERVING:
(void) mhd_reserve(dp);
continue;
case DRIVE_FAILFASTING:
(void) mhd_failfast(dp);
continue;
case DRIVE_RELEASING:
(void) mhd_release(dp);
continue;
/* non-exclusive states */
default:
(DRIVE_EXCLUSIVE_STATES & ~DRIVE_ERRORED)));
}
continue; /* in case we're probing */
}
break;
}
/* close drive, if possible */
if (! serial)
if (! serial)
}
/* wake up anybody waiting */
/* see if anything happened */
if (! DRIVE_IS_IDLE(dp))
continue;
/* wait for something to happen */
} else {
}
}
}
/*
* kick off drive thread
*/
static int
)
{
int rval = 0;
/* check lock and thread */
/* create thread */
} else {
}
/* return success */
return (rval);
}
/*
* peel off s%u from name
*/
static char *
const char *sname
)
{
char *dname;
char *p, *e;
/* duplicate name */
return (NULL);
/* gobble number and 's' */
for (; (p > dname); --p) {
if (!isdigit(*p))
break;
}
if ((p == e) || (p <= dname)) {
return (NULL);
}
if (*p-- != 's') {
return (NULL);
}
return (NULL);
}
*(++p) = '\0';
return (dname);
}
/*
* create new drive
*/
char *rname, /* raw drive name */
int *fdp, /* open device or -1 */
)
{
/* check locks */
/* if drive already exists */
/* if set has changed, move drive */
return (NULL);
}
}
/* return drive */
return (dp);
}
/* build slice0 */
/* allocate and initialize drive */
/* steal open drive */
*fdp = -1;
}
/* add to set */
/* kick off drive thread */
return (NULL);
}
/* return drive */
return (dp);
}
/*
* find or create drive in any set
*/
static mhd_drive_t *
char *rname,
int *fdp,
)
{
/* check locks */
/* drive already exists */
return (dp);
/* add to null set */
/* return drive */
return (dp);
}
/*
* process a file in the tree walk
*/
static int
const char *path,
int type
)
{
/* skip all but character devices */
return (0);
}
/* see if drive already exists */
return (0);
/* see if device is a disk */
goto out;
switch (errno) {
case EINVAL:
case ENOTTY:
break;
default:
break;
}
goto out;
}
/* skip CDROMs */
return (0);
}
/* put disk on list */
goto out;
}
/* cleanup, return success (no matter what) */
out:
if (fd >= 0)
return (0);
}
/*
* find or create all the drives under a given directory
*/
int
char *path,
)
{
/* default */
/* walk the directory, adding disks */
/* return success */
return (0);
}