svn commit: r225144 - in projects/zfsd/head/sys/cam: ata scsi
Alexander Motin
mav at FreeBSD.org
Wed Aug 24 14:09:33 UTC 2011
Author: mav
Date: Wed Aug 24 14:09:32 2011
New Revision: 225144
URL: http://svn.freebsd.org/changeset/base/225144
Log:
First part of SAF-TE driver refactoring to the new fsm-based model:
- make configuration and status reading asynchronous.
Modified:
projects/zfsd/head/sys/cam/ata/ata_all.c
projects/zfsd/head/sys/cam/ata/ata_all.h
projects/zfsd/head/sys/cam/scsi/scsi_all.c
projects/zfsd/head/sys/cam/scsi/scsi_all.h
projects/zfsd/head/sys/cam/scsi/scsi_enc.c
projects/zfsd/head/sys/cam/scsi/scsi_enc_internal.h
projects/zfsd/head/sys/cam/scsi/scsi_enc_safte.c
projects/zfsd/head/sys/cam/scsi/scsi_enc_ses.c
Modified: projects/zfsd/head/sys/cam/ata/ata_all.c
==============================================================================
--- projects/zfsd/head/sys/cam/ata/ata_all.c Wed Aug 24 13:35:56 2011 (r225143)
+++ projects/zfsd/head/sys/cam/ata/ata_all.c Wed Aug 24 14:09:32 2011 (r225144)
@@ -762,3 +762,44 @@ semb_send_diagnostic(struct ccb_ataio *a
length > 0 ? data_ptr[0] : 0, 0x82, length / 4);
}
+void
+semb_read_buffer(struct ccb_ataio *ataio,
+ u_int32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb*),
+ uint8_t tag_action, uint8_t page_code,
+ uint8_t *data_ptr, uint16_t length, uint32_t timeout)
+{
+
+ length = min(length, 1020);
+ length = (length + 3) & ~3;
+ cam_fill_ataio(ataio,
+ retries,
+ cbfcnp,
+ /*flags*/CAM_DIR_IN,
+ tag_action,
+ data_ptr,
+ length,
+ timeout);
+ ata_28bit_cmd(ataio, ATA_SEP_ATTN,
+ page_code, 0x00, length / 4);
+}
+
+void
+semb_write_buffer(struct ccb_ataio *ataio,
+ u_int32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb *),
+ uint8_t tag_action, uint8_t *data_ptr, uint16_t length, uint32_t timeout)
+{
+
+ length = min(length, 1020);
+ length = (length + 3) & ~3;
+ cam_fill_ataio(ataio,
+ retries,
+ cbfcnp,
+ /*flags*/length ? CAM_DIR_OUT : CAM_DIR_NONE,
+ tag_action,
+ data_ptr,
+ length,
+ timeout);
+ ata_28bit_cmd(ataio, ATA_SEP_ATTN,
+ length > 0 ? data_ptr[0] : 0, 0x80, length / 4);
+}
+
Modified: projects/zfsd/head/sys/cam/ata/ata_all.h
==============================================================================
--- projects/zfsd/head/sys/cam/ata/ata_all.h Wed Aug 24 13:35:56 2011 (r225143)
+++ projects/zfsd/head/sys/cam/ata/ata_all.h Wed Aug 24 14:09:32 2011 (r225144)
@@ -152,4 +152,14 @@ void semb_send_diagnostic(struct ccb_ata
uint8_t tag_action, uint8_t *data_ptr, uint16_t param_list_length,
uint32_t timeout);
+void semb_read_buffer(struct ccb_ataio *ataio,
+ u_int32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb*),
+ uint8_t tag_action, uint8_t page_code,
+ uint8_t *data_ptr, uint16_t allocation_length, uint32_t timeout);
+
+void semb_write_buffer(struct ccb_ataio *ataio,
+ u_int32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb *),
+ uint8_t tag_action, uint8_t *data_ptr, uint16_t param_list_length,
+ uint32_t timeout);
+
#endif
Modified: projects/zfsd/head/sys/cam/scsi/scsi_all.c
==============================================================================
--- projects/zfsd/head/sys/cam/scsi/scsi_all.c Wed Aug 24 13:35:56 2011 (r225143)
+++ projects/zfsd/head/sys/cam/scsi/scsi_all.c Wed Aug 24 14:09:32 2011 (r225144)
@@ -3564,7 +3564,7 @@ scsi_devid_is_naa_ieee_reg(uint8_t *bufp
return 0;
if (descr->length < sizeof(struct scsi_vpd_id_naa_ieee_reg))
return 0;
- if ((naa->naa >> SVPD_ID_NAA_NAA_SHIFT) != SVPD_ID_NAA_IEEE_REG)
+ if (0 && (naa->naa >> SVPD_ID_NAA_NAA_SHIFT) != SVPD_ID_NAA_IEEE_REG)
return 0;
return 1;
}
@@ -4276,6 +4276,66 @@ scsi_send_diagnostic(struct ccb_scsiio *
timeout);
}
+void
+scsi_read_buffer(struct ccb_scsiio *csio, u_int32_t retries,
+ void (*cbfcnp)(struct cam_periph *, union ccb*),
+ uint8_t tag_action, int mode,
+ uint8_t buffer_id, u_int32_t offset,
+ uint8_t *data_ptr, uint32_t allocation_length,
+ uint8_t sense_len, uint32_t timeout)
+{
+ struct scsi_read_buffer *scsi_cmd;
+
+ scsi_cmd = (struct scsi_read_buffer *)&csio->cdb_io.cdb_bytes;
+ memset(scsi_cmd, 0, sizeof(*scsi_cmd));
+ scsi_cmd->opcode = READ_BUFFER;
+ scsi_cmd->byte2 = mode;
+ scsi_cmd->buffer_id = buffer_id;
+ scsi_ulto3b(offset, scsi_cmd->offset);
+ scsi_ulto3b(allocation_length, scsi_cmd->length);
+
+ cam_fill_csio(csio,
+ retries,
+ cbfcnp,
+ /*flags*/CAM_DIR_IN,
+ tag_action,
+ data_ptr,
+ allocation_length,
+ sense_len,
+ sizeof(*scsi_cmd),
+ timeout);
+}
+
+void
+scsi_write_buffer(struct ccb_scsiio *csio, u_int32_t retries,
+ void (*cbfcnp)(struct cam_periph *, union ccb *),
+ uint8_t tag_action, int mode,
+ uint8_t buffer_id, u_int32_t offset,
+ uint8_t *data_ptr, uint32_t param_list_length,
+ uint8_t sense_len, uint32_t timeout)
+{
+ struct scsi_write_buffer *scsi_cmd;
+
+ scsi_cmd = (struct scsi_write_buffer *)&csio->cdb_io.cdb_bytes;
+ memset(scsi_cmd, 0, sizeof(*scsi_cmd));
+ scsi_cmd->opcode = WRITE_BUFFER;
+ scsi_cmd->byte2 = mode;
+ scsi_cmd->buffer_id = buffer_id;
+ scsi_ulto3b(offset, scsi_cmd->offset);
+ scsi_ulto3b(param_list_length, scsi_cmd->length);
+
+ cam_fill_csio(csio,
+ retries,
+ cbfcnp,
+ /*flags*/param_list_length ? CAM_DIR_OUT : CAM_DIR_NONE,
+ tag_action,
+ data_ptr,
+ param_list_length,
+ sense_len,
+ sizeof(*scsi_cmd),
+ timeout);
+}
+
void
scsi_start_stop(struct ccb_scsiio *csio, u_int32_t retries,
void (*cbfcnp)(struct cam_periph *, union ccb *),
Modified: projects/zfsd/head/sys/cam/scsi/scsi_all.h
==============================================================================
--- projects/zfsd/head/sys/cam/scsi/scsi_all.h Wed Aug 24 13:35:56 2011 (r225143)
+++ projects/zfsd/head/sys/cam/scsi/scsi_all.h Wed Aug 24 14:09:32 2011 (r225144)
@@ -1487,6 +1487,20 @@ void scsi_send_diagnostic(struct ccb_scs
uint16_t param_list_length, uint8_t sense_len,
uint32_t timeout);
+void scsi_read_buffer(struct ccb_scsiio *csio, u_int32_t retries,
+ void (*cbfcnp)(struct cam_periph *, union ccb*),
+ uint8_t tag_action, int mode,
+ uint8_t buffer_id, u_int32_t offset,
+ uint8_t *data_ptr, uint32_t allocation_length,
+ uint8_t sense_len, uint32_t timeout);
+
+void scsi_write_buffer(struct ccb_scsiio *csio, u_int32_t retries,
+ void (*cbfcnp)(struct cam_periph *, union ccb *),
+ uint8_t tag_action, int mode,
+ uint8_t buffer_id, u_int32_t offset,
+ uint8_t *data_ptr, uint32_t param_list_length,
+ uint8_t sense_len, uint32_t timeout);
+
void scsi_read_write(struct ccb_scsiio *csio, u_int32_t retries,
void (*cbfcnp)(struct cam_periph *, union ccb *),
u_int8_t tag_action, int readop, u_int8_t byte2,
Modified: projects/zfsd/head/sys/cam/scsi/scsi_enc.c
==============================================================================
--- projects/zfsd/head/sys/cam/scsi/scsi_enc.c Wed Aug 24 13:35:56 2011 (r225143)
+++ projects/zfsd/head/sys/cam/scsi/scsi_enc.c Wed Aug 24 14:09:32 2011 (r225144)
@@ -429,7 +429,7 @@ enc_ioctl(struct cdev *dev, u_long cmd,
cam_periph_unlock(periph);
break;
}
- tmp = cache->enc_status & ~ENCI_SVALID;
+ tmp = cache->enc_status;
cam_periph_unlock(periph);
error = copyout(&tmp, addr, sizeof(tmp));
cache->enc_status = tmp;
Modified: projects/zfsd/head/sys/cam/scsi/scsi_enc_internal.h
==============================================================================
--- projects/zfsd/head/sys/cam/scsi/scsi_enc_internal.h Wed Aug 24 13:35:56 2011 (r225143)
+++ projects/zfsd/head/sys/cam/scsi/scsi_enc_internal.h Wed Aug 24 14:09:32 2011 (r225144)
@@ -139,7 +139,6 @@ struct enc_softc {
enc_cache_t enc_daemon_cache;
struct sx enc_cache_lock;
-#define ENCI_SVALID 0x80
uint8_t enc_flags;
#define ENC_FLAG_INVALID 0x01
#define ENC_FLAG_INITIALIZED 0x02
Modified: projects/zfsd/head/sys/cam/scsi/scsi_enc_safte.c
==============================================================================
--- projects/zfsd/head/sys/cam/scsi/scsi_enc_safte.c Wed Aug 24 13:35:56 2011 (r225143)
+++ projects/zfsd/head/sys/cam/scsi/scsi_enc_safte.c Wed Aug 24 14:09:32 2011 (r225144)
@@ -45,6 +45,7 @@ __FBSDID("$FreeBSD: head/sys/cam/scsi/sc
#include <cam/scsi/scsi_enc.h>
#include <cam/scsi/scsi_enc_internal.h>
+#include <cam/scsi/scsi_message.h>
#include <opt_enc.h>
@@ -52,8 +53,6 @@ __FBSDID("$FreeBSD: head/sys/cam/scsi/sc
* SAF-TE Type Device Emulation
*/
-static int safte_getconfig(enc_softc_t *);
-static int safte_rdstat(enc_softc_t *, int);
static int set_elm_status_sel(enc_softc_t *, encioc_elm_status_t *, int);
static int wrbuf16(enc_softc_t *, uint8_t, uint8_t, uint8_t, uint8_t, int);
static void wrslot_stat(enc_softc_t *, int);
@@ -81,8 +80,54 @@ static int perf_slotop(enc_softc_t *, ui
#define SAFTE_WT_ACTPWS 0x14 /* turn on/off power supply */
#define SAFTE_WT_GLOBAL 0x15 /* send global command */
-
#define SAFT_SCRATCH 64
+#define SCSZ 0x8000
+
+typedef enum {
+ SAFTE_UPDATE_NONE,
+ SAFTE_UPDATE_READCONFIG,
+ SAFTE_UPDATE_READENCSTATUS,
+ SAFTE_UPDATE_READSLOTSTATUS,
+ SAFTE_NUM_UPDATE_STATES
+} safte_update_action;
+
+static fsm_fill_handler_t safte_fill_read_buf_io;
+static fsm_done_handler_t safte_process_config;
+static fsm_done_handler_t safte_process_status;
+static fsm_done_handler_t safte_process_slotstatus;
+
+static struct enc_fsm_state enc_fsm_states[SAFTE_NUM_UPDATE_STATES] =
+{
+ { "SAFTE_UPDATE_NONE", 0, 0, 0, NULL, NULL, NULL },
+ {
+ "SAFTE_UPDATE_READCONFIG",
+ SAFTE_RD_RDCFG,
+ SAFT_SCRATCH,
+ 60 * 1000,
+ safte_fill_read_buf_io,
+ safte_process_config,
+ enc_error
+ },
+ {
+ "SAFTE_UPDATE_READENCSTATUS",
+ SAFTE_RD_RDESTS,
+ SCSZ,
+ 60 * 1000,
+ safte_fill_read_buf_io,
+ safte_process_status,
+ enc_error
+ },
+ {
+ "SAFTE_UPDATE_READSLOTSTATUS",
+ SAFTE_RD_RDDSTS,
+ SCSZ,
+ 60 * 1000,
+ safte_fill_read_buf_io,
+ safte_process_slotstatus,
+ enc_error
+ }
+};
+
#define NPSEUDO_ALARM 1
struct scfg {
/*
@@ -124,121 +169,127 @@ struct scfg {
static char *safte_2little = "Too Little Data Returned (%d) at line %d\n";
#define SAFT_BAIL(r, x, k) \
if ((r) >= (x)) { \
- ENC_LOG(ssc, safte_2little, x, __LINE__);\
+ ENC_LOG(enc, safte_2little, x, __LINE__);\
ENC_FREE((k)); \
return (EIO); \
}
static int
-safte_getconfig(enc_softc_t *ssc)
+safte_fill_read_buf_io(enc_softc_t *enc, struct enc_fsm_state *state,
+ union ccb *ccb, uint8_t *buf)
+{
+
+ if (state->page_code != SAFTE_RD_RDCFG &&
+ enc->enc_cache.nelms == 0) {
+ enc_update_request(enc, SAFTE_UPDATE_READCONFIG);
+ return (-1);
+ }
+
+ if (enc->enc_type == ENC_SEMB_SAFT) {
+ semb_read_buffer(&ccb->ataio, /*retries*/5,
+ enc_done, MSG_SIMPLE_Q_TAG,
+ state->page_code, buf, state->buf_size,
+ state->timeout);
+ } else {
+ scsi_read_buffer(&ccb->csio, /*retries*/5,
+ enc_done, MSG_SIMPLE_Q_TAG, 1,
+ state->page_code, 0, buf, state->buf_size,
+ SSD_FULL_SIZE, state->timeout);
+ }
+ return (0);
+}
+
+static int
+safte_process_config(enc_softc_t *enc, struct enc_fsm_state *state,
+ union ccb *ccb, uint8_t **bufp, int xfer_len)
{
struct scfg *cfg;
- int err, amt;
- char *sdata;
- static char cdb[10] =
- { READ_BUFFER, 1, SAFTE_RD_RDCFG, 0, 0, 0, 0, 0, SAFT_SCRATCH, 0 };
+ uint8_t *buf = *bufp;
+ int i, r;
- cfg = ssc->enc_private;
+ cfg = enc->enc_private;
if (cfg == NULL)
return (ENXIO);
- sdata = ENC_MALLOC(SAFT_SCRATCH);
- if (sdata == NULL)
- return (ENOMEM);
-
- amt = SAFT_SCRATCH;
- err = enc_runcmd(ssc, cdb, 10, sdata, &amt);
- if (err) {
- ENC_FREE(sdata);
- return (err);
- }
- amt = SAFT_SCRATCH - amt;
- if (amt < 6) {
- ENC_LOG(ssc, "too little data (%d) for configuration\n", amt);
- ENC_FREE(sdata);
+ if (xfer_len < 6) {
+ ENC_LOG(enc, "too little data (%d) for configuration\n",
+ xfer_len);
return (EIO);
}
- cfg->Nfans = sdata[0];
- cfg->Npwr = sdata[1];
- cfg->Nslots = sdata[2];
- cfg->DoorLock = sdata[3];
- cfg->Ntherm = sdata[4];
- cfg->Nspkrs = sdata[5];
+ cfg->Nfans = buf[0];
+ cfg->Npwr = buf[1];
+ cfg->Nslots = buf[2];
+ cfg->DoorLock = buf[3];
+ cfg->Ntherm = buf[4];
+ cfg->Nspkrs = buf[5];
cfg->Nalarm = NPSEUDO_ALARM;
- if (amt >= 7)
- cfg->Ntstats = sdata[6] & 0x0f;
+ if (xfer_len >= 7)
+ cfg->Ntstats = buf[6] & 0x0f;
else
cfg->Ntstats = 0;
- ENC_VLOG(ssc, "Nfans %d Npwr %d Nslots %d Lck %d Ntherm %d Nspkrs %d "
+ ENC_VLOG(enc, "Nfans %d Npwr %d Nslots %d Lck %d Ntherm %d Nspkrs %d "
"Ntstats %d\n",
cfg->Nfans, cfg->Npwr, cfg->Nslots, cfg->DoorLock, cfg->Ntherm,
cfg->Nspkrs, cfg->Ntstats);
- ENC_FREE(sdata);
- return (0);
-}
-
-static int
-safte_rdstat(enc_softc_t *ssc, int slpflg)
-{
- int err, oid, r, i, hiwater, nitems, amt;
- uint16_t tempflags;
- size_t buflen;
- uint8_t status, oencstat;
- char *sdata, cdb[10];
- struct scfg *cc = ssc->enc_private;
- enc_cache_t *cache = &ssc->enc_cache;
-
- /*
- * The number of objects overstates things a bit,
- * both for the bogus 'thermometer' entries and
- * the drive status (which isn't read at the same
- * time as the enclosure status), but that's okay.
- */
- buflen = 4 * cc->Nslots;
- if (cache->nelms > buflen)
- buflen = cache->nelms;
- sdata = ENC_MALLOC(buflen);
- if (sdata == NULL)
+ enc->enc_cache.nelms = cfg->Nfans + cfg->Npwr + cfg->Nslots +
+ cfg->DoorLock + cfg->Ntherm + cfg->Nspkrs + cfg->Ntstats + 1 +
+ NPSEUDO_ALARM;
+ ENC_FREE_AND_NULL(enc->enc_cache.elm_map);
+ enc->enc_cache.elm_map =
+ ENC_MALLOCZ(enc->enc_cache.nelms * sizeof(enc_element_t));
+ if (enc->enc_cache.elm_map == NULL) {
+ enc->enc_cache.nelms = 0;
return (ENOMEM);
-
- cdb[0] = READ_BUFFER;
- cdb[1] = 1;
- cdb[2] = SAFTE_RD_RDESTS;
- cdb[3] = 0;
- cdb[4] = 0;
- cdb[5] = 0;
- cdb[6] = 0;
- cdb[7] = (buflen >> 8) & 0xff;
- cdb[8] = buflen & 0xff;
- cdb[9] = 0;
- amt = buflen;
- err = enc_runcmd(ssc, cdb, 10, sdata, &amt);
- if (err) {
- ENC_FREE(sdata);
- return (err);
}
- hiwater = buflen - amt;
-
+ r = 0;
/*
- * invalidate all status bits.
+ * Note that this is all arranged for the convenience
+ * in later fetches of status.
*/
- for (i = 0; i < cache->nelms; i++)
- cache->elm_map[i].svalid = 0;
- oencstat = cache->enc_status & ALL_ENC_STAT;
- ssc->enc_cache.enc_status = 0;
+ for (i = 0; i < cfg->Nfans; i++)
+ enc->enc_cache.elm_map[r++].enctype = ELMTYP_FAN;
+ cfg->pwroff = (uint8_t) r;
+ for (i = 0; i < cfg->Npwr; i++)
+ enc->enc_cache.elm_map[r++].enctype = ELMTYP_POWER;
+ for (i = 0; i < cfg->DoorLock; i++)
+ enc->enc_cache.elm_map[r++].enctype = ELMTYP_DOORLOCK;
+ for (i = 0; i < cfg->Nspkrs; i++)
+ enc->enc_cache.elm_map[r++].enctype = ELMTYP_ALARM;
+ for (i = 0; i < cfg->Ntherm; i++)
+ enc->enc_cache.elm_map[r++].enctype = ELMTYP_THERM;
+ for (i = 0; i <= cfg->Ntstats; i++)
+ enc->enc_cache.elm_map[r++].enctype = ELMTYP_THERM;
+ enc->enc_cache.elm_map[r++].enctype = ELMTYP_ALARM;
+ cfg->slotoff = (uint8_t) r;
+ for (i = 0; i < cfg->Nslots; i++)
+ enc->enc_cache.elm_map[r++].enctype = ELMTYP_DEVICE;
+ enc_update_request(enc, SAFTE_UPDATE_READENCSTATUS);
+ enc_update_request(enc, SAFTE_UPDATE_READSLOTSTATUS);
+
+ return (0);
+}
+
+static int
+safte_process_status(enc_softc_t *enc, struct enc_fsm_state *state,
+ union ccb *ccb, uint8_t **bufp, int xfer_len)
+{
+ struct scfg *cfg;
+ uint8_t *buf = *bufp;
+ int oid, r, i, nitems;
+ uint16_t tempflags;
+ enc_cache_t *cache = &enc->enc_cache;
+
+ cfg = enc->enc_private;
+ if (cfg == NULL)
+ return (ENXIO);
- /*
- * Now parse returned buffer.
- * If we didn't get enough data back,
- * that's considered a fatal error.
- */
oid = r = 0;
- for (nitems = i = 0; i < cc->Nfans; i++) {
- SAFT_BAIL(r, hiwater, sdata);
+ for (nitems = i = 0; i < cfg->Nfans; i++) {
+ SAFT_BAIL(r, xfer_len, buf);
/*
* 0 = Fan Operational
* 1 = Fan is malfunctioning
@@ -247,7 +298,7 @@ safte_rdstat(enc_softc_t *ssc, int slpfl
*/
cache->elm_map[oid].encstat[1] = 0; /* resvd */
cache->elm_map[oid].encstat[2] = 0; /* resvd */
- switch ((int)(uint8_t)sdata[r]) {
+ switch ((int)buf[r]) {
case 0:
nitems++;
cache->elm_map[oid].encstat[0] = SES_OBJSTAT_OK;
@@ -271,7 +322,7 @@ safte_rdstat(enc_softc_t *ssc, int slpfl
* if only one fan or no thermometers,
* else the NONCRITICAL error is set.
*/
- if (cc->Nfans == 1 || (cc->Ntherm + cc->Ntstats) == 0)
+ if (cfg->Nfans == 1 || (cfg->Ntherm + cfg->Ntstats) == 0)
cache->enc_status |= SES_ENCSTAT_CRITICAL;
else
cache->enc_status |= SES_ENCSTAT_NONCRITICAL;
@@ -285,7 +336,7 @@ safte_rdstat(enc_softc_t *ssc, int slpfl
* if only one fan or no thermometers,
* else the NONCRITICAL error is set.
*/
- if (cc->Nfans == 1)
+ if (cfg->Nfans == 1)
cache->enc_status |= SES_ENCSTAT_CRITICAL;
else
cache->enc_status |= SES_ENCSTAT_NONCRITICAL;
@@ -297,8 +348,8 @@ safte_rdstat(enc_softc_t *ssc, int slpfl
break;
default:
cache->elm_map[oid].encstat[0] = SES_OBJSTAT_UNSUPPORTED;
- ENC_LOG(ssc, "Unknown fan%d status 0x%x\n", i,
- sdata[r] & 0xff);
+ ENC_LOG(enc, "Unknown fan%d status 0x%x\n", i,
+ buf[r] & 0xff);
break;
}
cache->elm_map[oid++].svalid = 1;
@@ -309,18 +360,18 @@ safte_rdstat(enc_softc_t *ssc, int slpfl
* No matter how you cut it, no cooling elements when there
* should be some there is critical.
*/
- if (cc->Nfans && nitems == 0) {
+ if (cfg->Nfans && nitems == 0) {
cache->enc_status |= SES_ENCSTAT_CRITICAL;
}
- for (i = 0; i < cc->Npwr; i++) {
- SAFT_BAIL(r, hiwater, sdata);
+ for (i = 0; i < cfg->Npwr; i++) {
+ SAFT_BAIL(r, xfer_len, buf);
cache->elm_map[oid].encstat[0] = SES_OBJSTAT_UNKNOWN;
cache->elm_map[oid].encstat[1] = 0; /* resvd */
cache->elm_map[oid].encstat[2] = 0; /* resvd */
cache->elm_map[oid].encstat[3] = 0x20; /* requested on */
- switch ((uint8_t)sdata[r]) {
+ switch (buf[r]) {
case 0x00: /* pws operational and on */
cache->elm_map[oid].encstat[0] = SES_OBJSTAT_OK;
break;
@@ -359,25 +410,25 @@ safte_rdstat(enc_softc_t *ssc, int slpfl
cache->enc_status |= SES_ENCSTAT_INFO;
break;
default:
- ENC_LOG(ssc, "unknown power supply %d status (0x%x)\n",
- i, sdata[r] & 0xff);
+ ENC_LOG(enc, "unknown power supply %d status (0x%x)\n",
+ i, buf[r] & 0xff);
break;
}
- ssc->enc_cache.elm_map[oid++].svalid = 1;
+ enc->enc_cache.elm_map[oid++].svalid = 1;
r++;
}
/*
* Skip over Slot SCSI IDs
*/
- r += cc->Nslots;
+ r += cfg->Nslots;
/*
* We always have doorlock status, no matter what,
* but we only save the status if we have one.
*/
- SAFT_BAIL(r, hiwater, sdata);
- if (cc->DoorLock) {
+ SAFT_BAIL(r, xfer_len, buf);
+ if (cfg->DoorLock) {
/*
* 0 = Door Locked
* 1 = Door Unlocked, or no Lock Installed
@@ -385,7 +436,7 @@ safte_rdstat(enc_softc_t *ssc, int slpfl
*/
cache->elm_map[oid].encstat[1] = 0;
cache->elm_map[oid].encstat[2] = 0;
- switch ((uint8_t)sdata[r]) {
+ switch (buf[r]) {
case 0:
cache->elm_map[oid].encstat[0] = SES_OBJSTAT_OK;
cache->elm_map[oid].encstat[3] = 0;
@@ -402,8 +453,8 @@ safte_rdstat(enc_softc_t *ssc, int slpfl
default:
cache->elm_map[oid].encstat[0] =
SES_OBJSTAT_UNSUPPORTED;
- ENC_LOG(ssc, "unknown lock status 0x%x\n",
- sdata[r] & 0xff);
+ ENC_LOG(enc, "unknown lock status 0x%x\n",
+ buf[r] & 0xff);
break;
}
cache->elm_map[oid++].svalid = 1;
@@ -414,11 +465,11 @@ safte_rdstat(enc_softc_t *ssc, int slpfl
* We always have speaker status, no matter what,
* but we only save the status if we have one.
*/
- SAFT_BAIL(r, hiwater, sdata);
- if (cc->Nspkrs) {
+ SAFT_BAIL(r, xfer_len, buf);
+ if (cfg->Nspkrs) {
cache->elm_map[oid].encstat[1] = 0;
cache->elm_map[oid].encstat[2] = 0;
- if (sdata[r] == 1) {
+ if (buf[r] == 1) {
/*
* We need to cache tone urgency indicators.
* Someday.
@@ -426,14 +477,14 @@ safte_rdstat(enc_softc_t *ssc, int slpfl
cache->elm_map[oid].encstat[0] = SES_OBJSTAT_NONCRIT;
cache->elm_map[oid].encstat[3] = 0x8;
cache->enc_status |= SES_ENCSTAT_NONCRITICAL;
- } else if (sdata[r] == 0) {
+ } else if (buf[r] == 0) {
cache->elm_map[oid].encstat[0] = SES_OBJSTAT_OK;
cache->elm_map[oid].encstat[3] = 0;
} else {
cache->elm_map[oid].encstat[0] = SES_OBJSTAT_UNSUPPORTED;
cache->elm_map[oid].encstat[3] = 0;
- ENC_LOG(ssc, "unknown spkr status 0x%x\n",
- sdata[r] & 0xff);
+ ENC_LOG(enc, "unknown spkr status 0x%x\n",
+ buf[r] & 0xff);
}
cache->elm_map[oid++].svalid = 1;
}
@@ -449,13 +500,13 @@ safte_rdstat(enc_softc_t *ssc, int slpfl
* binary temperature sensor.
*/
- SAFT_BAIL(r + cc->Ntherm, hiwater, sdata);
- tempflags = sdata[r + cc->Ntherm];
- SAFT_BAIL(r + cc->Ntherm + 1, hiwater, sdata);
- tempflags |= (tempflags << 8) | sdata[r + cc->Ntherm + 1];
+ SAFT_BAIL(r + cfg->Ntherm, xfer_len, buf);
+ tempflags = buf[r + cfg->Ntherm];
+ SAFT_BAIL(r + cfg->Ntherm + 1, xfer_len, buf);
+ tempflags |= (tempflags << 8) | buf[r + cfg->Ntherm + 1];
- for (i = 0; i < cc->Ntherm; i++) {
- SAFT_BAIL(r, hiwater, sdata);
+ for (i = 0; i < cfg->Ntherm; i++) {
+ SAFT_BAIL(r, xfer_len, buf);
/*
* Status is a range from -10 to 245 deg Celsius,
* which we need to normalize to -20 to -245 according
@@ -492,16 +543,16 @@ safte_rdstat(enc_softc_t *ssc, int slpfl
} else
cache->elm_map[oid].encstat[0] = SES_OBJSTAT_OK;
cache->elm_map[oid].encstat[1] = 0;
- cache->elm_map[oid].encstat[2] = sdata[r];
+ cache->elm_map[oid].encstat[2] = buf[r];
cache->elm_map[oid].encstat[3] = 0;
cache->elm_map[oid++].svalid = 1;
r++;
}
- for (i = 0; i <= cc->Ntstats; i++) {
+ for (i = 0; i <= cfg->Ntstats; i++) {
cache->elm_map[oid].encstat[1] = 0;
if (tempflags & (1 <<
- ((i == cc->Ntstats) ? 15 : (cc->Ntherm + i)))) {
+ ((i == cfg->Ntstats) ? 15 : (cfg->Ntherm + i)))) {
cache->elm_map[oid].encstat[0] = SES_OBJSTAT_CRIT;
cache->elm_map[4].encstat[2] = 0xff;
/*
@@ -516,7 +567,7 @@ safte_rdstat(enc_softc_t *ssc, int slpfl
* Just say 'OK', and use the reserved value of
* zero.
*/
- if ((cc->Ntherm + cc->Ntstats) == 0)
+ if ((cfg->Ntherm + cfg->Ntstats) == 0)
cache->elm_map[oid].encstat[0] =
SES_OBJSTAT_NOTAVAIL;
else
@@ -536,24 +587,31 @@ safte_rdstat(enc_softc_t *ssc, int slpfl
cache->elm_map[oid].encstat[3] = cache->elm_map[oid].priv;
cache->elm_map[oid++].svalid = 1;
- /*
- * Now get drive slot status
- */
- cdb[2] = SAFTE_RD_RDDSTS;
- amt = buflen;
- err = enc_runcmd(ssc, cdb, 10, sdata, &amt);
- if (err) {
- ENC_FREE(sdata);
- return (err);
- }
- hiwater = buflen - amt;
- for (r = i = 0; i < cc->Nslots; i++, r += 4) {
- SAFT_BAIL(r+3, hiwater, sdata);
+ return (0);
+}
+
+static int
+safte_process_slotstatus(enc_softc_t *enc, struct enc_fsm_state *state,
+ union ccb *ccb, uint8_t **bufp, int xfer_len)
+{
+ struct scfg *cfg;
+ uint8_t *buf = *bufp;
+ enc_cache_t *cache = &enc->enc_cache;
+ int oid, r, i;
+ uint8_t status;
+
+ cfg = enc->enc_private;
+ if (cfg == NULL)
+ return (ENXIO);
+
+ oid = cfg->slotoff;
+ for (r = i = 0; i < cfg->Nslots; i++, r += 4) {
+ SAFT_BAIL(r+3, xfer_len, buf);
cache->elm_map[oid].encstat[0] = SES_OBJSTAT_UNSUPPORTED;
cache->elm_map[oid].encstat[1] = (uint8_t) i;
cache->elm_map[oid].encstat[2] = 0;
cache->elm_map[oid].encstat[3] = 0;
- status = sdata[r+3];
+ status = buf[r+3];
if ((status & 0x1) == 0) { /* no device */
cache->elm_map[oid].encstat[0] =
SES_OBJSTAT_NOTINSTALLED;
@@ -568,29 +626,28 @@ safte_rdstat(enc_softc_t *ssc, int slpfl
}
cache->elm_map[oid++].svalid = 1;
}
- /* see comment below about sticky enclosure status */
- cache->enc_status |= ENCI_SVALID | oencstat;
- ENC_FREE(sdata);
return (0);
}
static int
-set_elm_status_sel(enc_softc_t *ssc, encioc_elm_status_t *elms, int slp)
+set_elm_status_sel(enc_softc_t *enc, encioc_elm_status_t *elms, int slp)
{
int idx;
enc_element_t *ep;
- struct scfg *cc = ssc->enc_private;
+ struct scfg *cc = enc->enc_private;
if (cc == NULL)
return (0);
idx = (int)elms->elm_idx;
- ep = &ssc->enc_cache.elm_map[idx];
+ ep = &enc->enc_cache.elm_map[idx];
switch (ep->enctype) {
case ELMTYP_DEVICE:
if (elms->cstat[0] & SESCTL_PRDFAIL) {
ep->priv |= 0x40;
+ } else {
+ ep->priv &= ~0x40;
}
/* SESCTL_RSTSWAP has no correspondence in SAF-TE */
if (elms->cstat[0] & SESCTL_DISABLE) {
@@ -599,13 +656,15 @@ set_elm_status_sel(enc_softc_t *ssc, enc
* Hmm. Try to set the 'No Drive' flag.
* Maybe that will count as a 'disable'.
*/
+ } else {
+ ep->priv &= ~0x80;
}
if (ep->priv & 0xc6) {
ep->priv &= ~0x1;
} else {
ep->priv |= 0x1; /* no errors */
}
- wrslot_stat(ssc, slp);
+ wrslot_stat(enc, slp);
break;
case ELMTYP_POWER:
/*
@@ -613,7 +672,7 @@ set_elm_status_sel(enc_softc_t *ssc, enc
* do the 'disable' for a power supply.
*/
if (elms->cstat[0] & SESCTL_DISABLE) {
- (void) wrbuf16(ssc, SAFTE_WT_ACTPWS,
+ (void) wrbuf16(enc, SAFTE_WT_ACTPWS,
idx - cc->pwroff, 0, 0, slp);
}
break;
@@ -624,7 +683,7 @@ set_elm_status_sel(enc_softc_t *ssc, enc
*/
if (elms->cstat[0] & SESCTL_DISABLE) {
/* remember- fans are the first items, so idx works */
- (void) wrbuf16(ssc, SAFTE_WT_FANSPD, idx, 0, 0, slp);
+ (void) wrbuf16(enc, SAFTE_WT_FANSPD, idx, 0, 0, slp);
}
break;
case ELMTYP_DOORLOCK:
@@ -633,7 +692,7 @@ set_elm_status_sel(enc_softc_t *ssc, enc
*/
if (elms->cstat[0] & SESCTL_DISABLE) {
cc->flag2 &= ~SAFT_FLG2_LOCKDOOR;
- (void) wrbuf16(ssc, SAFTE_WT_GLOBAL, cc->flag1,
+ (void) wrbuf16(enc, SAFTE_WT_GLOBAL, cc->flag1,
cc->flag2, 0, slp);
}
break;
@@ -644,7 +703,7 @@ set_elm_status_sel(enc_softc_t *ssc, enc
if (elms->cstat[0] & SESCTL_DISABLE) {
cc->flag2 &= ~SAFT_FLG1_ALARM;
ep->priv |= 0x40; /* Muted */
- (void) wrbuf16(ssc, SAFTE_WT_GLOBAL, cc->flag1,
+ (void) wrbuf16(enc, SAFTE_WT_GLOBAL, cc->flag1,
cc->flag2, 0, slp);
}
break;
@@ -659,12 +718,12 @@ set_elm_status_sel(enc_softc_t *ssc, enc
* This function handles all of the 16 byte WRITE BUFFER commands.
*/
static int
-wrbuf16(enc_softc_t *ssc, uint8_t op, uint8_t b1, uint8_t b2,
+wrbuf16(enc_softc_t *enc, uint8_t op, uint8_t b1, uint8_t b2,
uint8_t b3, int slp)
{
int err, amt;
char *sdata;
- struct scfg *cc = ssc->enc_private;
+ struct scfg *cc = enc->enc_private;
static char cdb[10] = { WRITE_BUFFER, 1, 0, 0, 0, 0, 0, 0, 16, 0 };
if (cc == NULL)
@@ -674,14 +733,14 @@ wrbuf16(enc_softc_t *ssc, uint8_t op, ui
if (sdata == NULL)
return (ENOMEM);
- ENC_DLOG(ssc, "saf_wrbuf16 %x %x %x %x\n", op, b1, b2, b3);
+ ENC_DLOG(enc, "saf_wrbuf16 %x %x %x %x\n", op, b1, b2, b3);
sdata[0] = op;
sdata[1] = b1;
sdata[2] = b2;
sdata[3] = b3;
amt = -16;
- err = enc_runcmd(ssc, cdb, 10, sdata, &amt);
+ err = enc_runcmd(enc, cdb, 10, sdata, &amt);
ENC_FREE(sdata);
return (err);
}
@@ -693,17 +752,17 @@ wrbuf16(enc_softc_t *ssc, uint8_t op, ui
* returning an error.
*/
static void
-wrslot_stat(enc_softc_t *ssc, int slp)
+wrslot_stat(enc_softc_t *enc, int slp)
{
int i, amt;
enc_element_t *ep;
char cdb[10], *sdata;
- struct scfg *cc = ssc->enc_private;
+ struct scfg *cc = enc->enc_private;
if (cc == NULL)
return;
- ENC_DLOG(ssc, "saf_wrslot\n");
+ ENC_DLOG(enc, "saf_wrslot\n");
cdb[0] = WRITE_BUFFER;
cdb[1] = 1;
cdb[2] = 0;
@@ -721,12 +780,12 @@ wrslot_stat(enc_softc_t *ssc, int slp)
sdata[0] = SAFTE_WT_DSTAT;
for (i = 0; i < cc->Nslots; i++) {
- ep = &ssc->enc_cache.elm_map[cc->slotoff + i];
- ENC_DLOG(ssc, "saf_wrslot %d <- %x\n", i, ep->priv & 0xff);
+ ep = &enc->enc_cache.elm_map[cc->slotoff + i];
+ ENC_DLOG(enc, "saf_wrslot %d <- %x\n", i, ep->priv & 0xff);
sdata[1 + (3 * i)] = ep->priv & 0xff;
}
amt = -(cc->Nslots * 3 + 1);
- (void) enc_runcmd(ssc, cdb, 10, sdata, &amt);
+ (void) enc_runcmd(enc, cdb, 10, sdata, &amt);
ENC_FREE(sdata);
}
@@ -734,11 +793,11 @@ wrslot_stat(enc_softc_t *ssc, int slp)
* This function issues the "PERFORM SLOT OPERATION" command.
*/
static int
-perf_slotop(enc_softc_t *ssc, uint8_t slot, uint8_t opflag, int slp)
+perf_slotop(enc_softc_t *enc, uint8_t slot, uint8_t opflag, int slp)
{
int err, amt;
char *sdata;
- struct scfg *cc = ssc->enc_private;
+ struct scfg *cc = enc->enc_private;
static char cdb[10] =
{ WRITE_BUFFER, 1, 0, 0, 0, 0, 0, 0, SAFT_SCRATCH, 0 };
@@ -752,9 +811,9 @@ perf_slotop(enc_softc_t *ssc, uint8_t sl
sdata[0] = SAFTE_WT_SLTOP;
sdata[1] = slot;
sdata[2] = opflag;
- ENC_DLOG(ssc, "saf_slotop slot %d op %x\n", slot, opflag);
+ ENC_DLOG(enc, "saf_slotop slot %d op %x\n", slot, opflag);
amt = -SAFT_SCRATCH;
- err = enc_runcmd(ssc, cdb, 10, sdata, &amt);
+ err = enc_runcmd(enc, cdb, 10, sdata, &amt);
ENC_FREE(sdata);
return (err);
}
@@ -762,39 +821,40 @@ perf_slotop(enc_softc_t *ssc, uint8_t sl
static void
safte_softc_cleanup(struct cam_periph *periph)
{
- enc_softc_t *ssc;
+ enc_softc_t *enc;
- ssc = periph->softc;
- ENC_FREE_AND_NULL(ssc->enc_cache.elm_map);
- ENC_FREE_AND_NULL(ssc->enc_private);
- ssc->enc_cache.nelms = 0;
+ enc = periph->softc;
+ ENC_FREE_AND_NULL(enc->enc_cache.elm_map);
+ ENC_FREE_AND_NULL(enc->enc_private);
+ enc->enc_cache.nelms = 0;
}
static int
-safte_init_enc(enc_softc_t *ssc)
+safte_init_enc(enc_softc_t *enc)
{
int err;
static char cdb0[6] = { SEND_DIAGNOSTIC };
- err = enc_runcmd(ssc, cdb0, 6, NULL, 0);
+ err = enc_runcmd(enc, cdb0, 6, NULL, 0);
if (err) {
return (err);
}
DELAY(5000);
- err = wrbuf16(ssc, SAFTE_WT_GLOBAL, 0, 0, 0, 1);
+ err = wrbuf16(enc, SAFTE_WT_GLOBAL, 0, 0, 0, 1);
return (err);
}
static int
-safte_get_enc_status(enc_softc_t *ssc, int slpflg)
+safte_get_enc_status(enc_softc_t *enc, int slpflg)
{
- return (safte_rdstat(ssc, slpflg));
+
+ return (0);
}
static int
-safte_set_enc_status(enc_softc_t *ssc, uint8_t encstat, int slpflg)
+safte_set_enc_status(enc_softc_t *enc, uint8_t encstat, int slpflg)
{
- struct scfg *cc = ssc->enc_private;
+ struct scfg *cc = enc->enc_private;
if (cc == NULL)
return (0);
/*
@@ -803,46 +863,39 @@ safte_set_enc_status(enc_softc_t *ssc, u
* that is, things set in enclosure status stay set (as implied
* by conditions set in reading object status) until cleared.
*/
- ssc->enc_cache.enc_status &= ~ALL_ENC_STAT;
- ssc->enc_cache.enc_status |= (encstat & ALL_ENC_STAT);
- ssc->enc_cache.enc_status |= ENCI_SVALID;
+ enc->enc_cache.enc_status &= ~ALL_ENC_STAT;
+ enc->enc_cache.enc_status |= (encstat & ALL_ENC_STAT);
cc->flag1 &= ~(SAFT_FLG1_ALARM|SAFT_FLG1_GLOBFAIL|SAFT_FLG1_GLOBWARN);
if ((encstat & (SES_ENCSTAT_CRITICAL|SES_ENCSTAT_UNRECOV)) != 0) {
cc->flag1 |= SAFT_FLG1_ALARM|SAFT_FLG1_GLOBFAIL;
} else if ((encstat & SES_ENCSTAT_NONCRITICAL) != 0) {
cc->flag1 |= SAFT_FLG1_GLOBWARN;
}
- return (wrbuf16(ssc, SAFTE_WT_GLOBAL, cc->flag1, cc->flag2, 0, slpflg));
+ return (wrbuf16(enc, SAFTE_WT_GLOBAL, cc->flag1, cc->flag2, 0, slpflg));
}
static int
-safte_get_elm_status(enc_softc_t *ssc, encioc_elm_status_t *elms, int slpflg)
+safte_get_elm_status(enc_softc_t *enc, encioc_elm_status_t *elms, int slpflg)
{
int i = (int)elms->elm_idx;
- if ((ssc->enc_cache.enc_status & ENCI_SVALID) == 0 ||
- (ssc->enc_cache.elm_map[i].svalid) == 0) {
- int err = safte_rdstat(ssc, slpflg);
- if (err)
- return (err);
- }
- elms->cstat[0] = ssc->enc_cache.elm_map[i].encstat[0];
- elms->cstat[1] = ssc->enc_cache.elm_map[i].encstat[1];
- elms->cstat[2] = ssc->enc_cache.elm_map[i].encstat[2];
- elms->cstat[3] = ssc->enc_cache.elm_map[i].encstat[3];
+ elms->cstat[0] = enc->enc_cache.elm_map[i].encstat[0];
+ elms->cstat[1] = enc->enc_cache.elm_map[i].encstat[1];
+ elms->cstat[2] = enc->enc_cache.elm_map[i].encstat[2];
+ elms->cstat[3] = enc->enc_cache.elm_map[i].encstat[3];
return (0);
}
static int
-safte_set_elm_status(enc_softc_t *ssc, encioc_elm_status_t *elms, int slp)
+safte_set_elm_status(enc_softc_t *enc, encioc_elm_status_t *elms, int slp)
{
int idx, err;
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-projects
mailing list