summaryrefslogtreecommitdiffstats
path: root/sys/dev/sym
diff options
context:
space:
mode:
authorgroudier <groudier@FreeBSD.org>2001-03-24 21:11:31 +0000
committergroudier <groudier@FreeBSD.org>2001-03-24 21:11:31 +0000
commit4887732081c545aab296a7932db991ff2ce1fa87 (patch)
tree1f0fddcbbac304c925f9ab931f00cd7b3af3dd91 /sys/dev/sym
parent250b6a9c42af07b528f4634a8bfcc4aadb3be389 (diff)
downloadFreeBSD-src-4887732081c545aab296a7932db991ff2ce1fa87.zip
FreeBSD-src-4887732081c545aab296a7932db991ff2ce1fa87.tar.gz
Add #if'ed support for the future option CAM_NEW_TRAN_CODE.
Diffstat (limited to 'sys/dev/sym')
-rw-r--r--sys/dev/sym/sym_hipd.c293
1 files changed, 236 insertions, 57 deletions
diff --git a/sys/dev/sym/sym_hipd.c b/sys/dev/sym/sym_hipd.c
index fed183b..eebd097 100644
--- a/sys/dev/sym/sym_hipd.c
+++ b/sys/dev/sym/sym_hipd.c
@@ -60,6 +60,7 @@
#define SYM_DRIVER_NAME "sym-1.6.5-20000902"
/* #define SYM_DEBUG_GENERIC_SUPPORT */
+/* #define CAM_NEW_TRAN_CODE */
#include <sys/param.h>
@@ -137,6 +138,13 @@ typedef u_int16_t u16;
typedef u_int32_t u32;
/*
+ * From 'cam.error_recovery_diffs.20010313.context' patch.
+ */
+#ifdef CAM_NEW_TRAN_CODE
+#define FreeBSD_New_Tran_Settings
+#endif /* CAM_NEW_TRAN_CODE */
+
+/*
* Driver definitions.
*/
#include <dev/sym/sym_defs.h>
@@ -1240,6 +1248,10 @@ typedef struct sym_hcb *hcb_p;
* Gather negotiable parameters value
*/
struct sym_trans {
+#ifdef FreeBSD_New_Tran_Settings
+ u8 scsi_version;
+ u8 spi_version;
+#endif
u8 period;
u8 offset;
u8 width;
@@ -2943,6 +2955,10 @@ static int sym_prepare_setting(hcb_p np, struct sym_nvram *nvram)
for (i = 0 ; i < SYM_CONF_MAX_TARGET ; i++) {
tcb_p tp = &np->target[i];
+#ifdef FreeBSD_New_Tran_Settings
+ tp->tinfo.user.scsi_version = tp->tinfo.current.scsi_version= 2;
+ tp->tinfo.user.spi_version = tp->tinfo.current.spi_version = 2;
+#endif
tp->tinfo.user.period = np->minsync;
tp->tinfo.user.offset = np->maxoffs;
tp->tinfo.user.width = np->maxwide ? BUS_16_BIT : BUS_8_BIT;
@@ -2960,6 +2976,9 @@ static int sym_prepare_setting(hcb_p np, struct sym_nvram *nvram)
tp->tinfo.user.width == BUS_16_BIT) {
tp->tinfo.user.options |= PPR_OPT_DT;
tp->tinfo.user.offset = np->maxoffs_dt;
+#ifdef FreeBSD_New_Tran_Settings
+ tp->tinfo.user.spi_version = 3;
+#endif
}
}
@@ -3629,13 +3648,91 @@ sym_getsync(hcb_p np, u_char dt, u_char sfac, u_char *divp, u_char *fakp)
}
/*
+ * Tell the SCSI layer about the new transfer parameters.
+ */
+static void
+sym_xpt_async_transfer_neg(hcb_p np, int target, u_int spi_valid)
+{
+ struct ccb_trans_settings cts;
+ struct cam_path *path;
+ int sts;
+ tcb_p tp = &np->target[target];
+
+ sts = xpt_create_path(&path, NULL, cam_sim_path(np->sim), target,
+ CAM_LUN_WILDCARD);
+ if (sts != CAM_REQ_CMP)
+ return;
+
+ bzero(&cts, sizeof(cts));
+
+#ifdef FreeBSD_New_Tran_Settings
+#define cts__scsi (cts.proto_specific.scsi)
+#define cts__spi (cts.xport_specific.spi)
+
+ cts.type = CTS_TYPE_CURRENT_SETTINGS;
+ cts.protocol = PROTO_SCSI;
+ cts.transport = XPORT_SPI;
+ cts.protocol_version = tp->tinfo.current.scsi_version;
+ cts.transport_version = tp->tinfo.current.spi_version;
+
+ cts__spi.valid = spi_valid;
+ if (spi_valid & CTS_SPI_VALID_SYNC_RATE)
+ cts__spi.sync_period = tp->tinfo.current.period;
+ if (spi_valid & CTS_SPI_VALID_SYNC_OFFSET)
+ cts__spi.sync_offset = tp->tinfo.current.offset;
+ if (spi_valid & CTS_SPI_VALID_BUS_WIDTH)
+ cts__spi.bus_width = tp->tinfo.current.width;
+ if (spi_valid & CTS_SPI_VALID_PPR_OPTIONS)
+ cts__spi.ppr_options = tp->tinfo.current.options;
+#undef cts__spi
+#undef cts__scsi
+#else
+ cts.valid = spi_valid;
+ if (spi_valid & CCB_TRANS_SYNC_RATE_VALID)
+ cts.sync_period = tp->tinfo.current.period;
+ if (spi_valid & CCB_TRANS_SYNC_OFFSET_VALID)
+ cts.sync_offset = tp->tinfo.current.offset;
+ if (spi_valid & CCB_TRANS_BUS_WIDTH_VALID)
+ cts.bus_width = tp->tinfo.current.width;
+#endif
+ xpt_setup_ccb(&cts.ccb_h, path, /*priority*/1);
+ xpt_async(AC_TRANSFER_NEG, path, &cts);
+ xpt_free_path(path);
+}
+
+#ifdef FreeBSD_New_Tran_Settings
+#define SYM_SPI_VALID_WDTR \
+ CTS_SPI_VALID_BUS_WIDTH | \
+ CTS_SPI_VALID_SYNC_RATE | \
+ CTS_SPI_VALID_SYNC_OFFSET
+#define SYM_SPI_VALID_SDTR \
+ CTS_SPI_VALID_SYNC_RATE | \
+ CTS_SPI_VALID_SYNC_OFFSET
+#define SYM_SPI_VALID_PPR \
+ CTS_SPI_VALID_PPR_OPTIONS | \
+ CTS_SPI_VALID_BUS_WIDTH | \
+ CTS_SPI_VALID_SYNC_RATE | \
+ CTS_SPI_VALID_SYNC_OFFSET
+#else
+#define SYM_SPI_VALID_WDTR \
+ CCB_TRANS_BUS_WIDTH_VALID | \
+ CCB_TRANS_SYNC_RATE_VALID | \
+ CCB_TRANS_SYNC_OFFSET_VALID
+#define SYM_SPI_VALID_SDTR \
+ CCB_TRANS_SYNC_RATE_VALID | \
+ CCB_TRANS_SYNC_OFFSET_VALID
+#define SYM_SPI_VALID_PPR \
+ CCB_TRANS_BUS_WIDTH_VALID | \
+ CCB_TRANS_SYNC_RATE_VALID | \
+ CCB_TRANS_SYNC_OFFSET_VALID
+#endif
+
+/*
* We received a WDTR.
* Let everything be aware of the changes.
*/
static void sym_setwide(hcb_p np, ccb_p cp, u_char wide)
{
- struct ccb_trans_settings neg;
- union ccb *ccb = cp->cam_ccb;
tcb_p tp = &np->target[cp->target];
sym_settrans(np, cp, 0, 0, 0, wide, 0, 0);
@@ -3647,14 +3744,8 @@ static void sym_setwide(hcb_p np, ccb_p cp, u_char wide)
tp->tinfo.current.offset = 0;
tp->tinfo.current.period = 0;
tp->tinfo.current.options = 0;
- neg.bus_width = wide ? BUS_16_BIT : BUS_8_BIT;
- neg.sync_period = tp->tinfo.current.period;
- neg.sync_offset = tp->tinfo.current.offset;
- neg.valid = CCB_TRANS_BUS_WIDTH_VALID
- | CCB_TRANS_SYNC_RATE_VALID
- | CCB_TRANS_SYNC_OFFSET_VALID;
- xpt_setup_ccb(&neg.ccb_h, ccb->ccb_h.path, /*priority*/1);
- xpt_async(AC_TRANSFER_NEG, ccb->ccb_h.path, &neg);
+
+ sym_xpt_async_transfer_neg(np, cp->target, SYM_SPI_VALID_WDTR);
}
/*
@@ -3664,8 +3755,6 @@ static void sym_setwide(hcb_p np, ccb_p cp, u_char wide)
static void
sym_setsync(hcb_p np, ccb_p cp, u_char ofs, u_char per, u_char div, u_char fak)
{
- struct ccb_trans_settings neg;
- union ccb *ccb = cp->cam_ccb;
tcb_p tp = &np->target[cp->target];
u_char wide = (cp->phys.select.sel_scntl3 & EWS) ? 1 : 0;
@@ -3677,12 +3766,8 @@ sym_setsync(hcb_p np, ccb_p cp, u_char ofs, u_char per, u_char div, u_char fak)
tp->tinfo.goal.period = tp->tinfo.current.period = per;
tp->tinfo.goal.offset = tp->tinfo.current.offset = ofs;
tp->tinfo.goal.options = tp->tinfo.current.options = 0;
- neg.sync_period = tp->tinfo.current.period;
- neg.sync_offset = tp->tinfo.current.offset;
- neg.valid = CCB_TRANS_SYNC_RATE_VALID
- | CCB_TRANS_SYNC_OFFSET_VALID;
- xpt_setup_ccb(&neg.ccb_h, ccb->ccb_h.path, /*priority*/1);
- xpt_async(AC_TRANSFER_NEG, ccb->ccb_h.path, &neg);
+
+ sym_xpt_async_transfer_neg(np, cp->target, SYM_SPI_VALID_SDTR);
}
/*
@@ -3692,8 +3777,6 @@ sym_setsync(hcb_p np, ccb_p cp, u_char ofs, u_char per, u_char div, u_char fak)
static void sym_setpprot(hcb_p np, ccb_p cp, u_char dt, u_char ofs,
u_char per, u_char wide, u_char div, u_char fak)
{
- struct ccb_trans_settings neg;
- union ccb *ccb = cp->cam_ccb;
tcb_p tp = &np->target[cp->target];
sym_settrans(np, cp, dt, ofs, per, wide, div, fak);
@@ -3705,14 +3788,8 @@ static void sym_setpprot(hcb_p np, ccb_p cp, u_char dt, u_char ofs,
tp->tinfo.goal.period = tp->tinfo.current.period = per;
tp->tinfo.goal.offset = tp->tinfo.current.offset = ofs;
tp->tinfo.goal.options = tp->tinfo.current.options = dt;
- neg.sync_period = tp->tinfo.current.period;
- neg.sync_offset = tp->tinfo.current.offset;
- neg.bus_width = wide ? BUS_16_BIT : BUS_8_BIT;
- neg.valid = CCB_TRANS_BUS_WIDTH_VALID
- | CCB_TRANS_SYNC_RATE_VALID
- | CCB_TRANS_SYNC_OFFSET_VALID;
- xpt_setup_ccb(&neg.ccb_h, ccb->ccb_h.path, /*priority*/1);
- xpt_async(AC_TRANSFER_NEG, ccb->ccb_h.path, &neg);
+
+ sym_xpt_async_transfer_neg(np, cp->target, SYM_SPI_VALID_PPR);
}
/*
@@ -4943,6 +5020,10 @@ static void sym_sir_bad_scsi_status(hcb_p np, int num, ccb_p cp)
*/
cp->sensecmd[0] = 0x03;
cp->sensecmd[1] = cp->lun << 5;
+#ifdef FreeBSD_New_Tran_Settings
+ if (tp->tinfo.current.scsi_version > 2 || cp->lun > 7)
+ cp->sensecmd[1] = 0;
+#endif
cp->sensecmd[4] = SYM_SNS_BBUF_LEN;
cp->data_len = SYM_SNS_BBUF_LEN;
@@ -8366,28 +8447,28 @@ static void sym_action2(struct cam_sim *sim, union ccb *ccb)
tp = &np->target[ccb_h->target_id];
/*
- * Update our transfer settings (basically WIDE/SYNC).
- * These features are to be handled in a per target
- * basis according to SCSI specifications.
- */
- if ((cts->flags & CCB_TRANS_USER_SETTINGS) != 0)
- sym_update_trans(np, tp, &tp->tinfo.user, cts);
-
- if ((cts->flags & CCB_TRANS_CURRENT_SETTINGS) != 0)
- sym_update_trans(np, tp, &tp->tinfo.goal, cts);
-
- /*
- * Update our disconnect and tag settings.
- * SCSI requires CmdQue feature to be handled in a per
- * device (logical unit) basis.
+ * Update SPI transport settings in TARGET control block.
+ * Update SCSI device settings in LUN control block.
*/
lp = sym_lp(np, tp, ccb_h->target_lun);
- if (lp) {
- if ((cts->flags & CCB_TRANS_USER_SETTINGS) != 0)
- sym_update_dflags(np, &lp->user_flags, cts);
- if ((cts->flags & CCB_TRANS_CURRENT_SETTINGS) != 0)
+#ifdef FreeBSD_New_Tran_Settings
+ if (cts->type == CTS_TYPE_CURRENT_SETTINGS) {
+#else
+ if ((cts->flags & CCB_TRANS_CURRENT_SETTINGS) != 0) {
+#endif
+ sym_update_trans(np, tp, &tp->tinfo.goal, cts);
+ if (lp)
sym_update_dflags(np, &lp->current_flags, cts);
}
+#ifdef FreeBSD_New_Tran_Settings
+ if (cts->type == CTS_TYPE_USER_SETTINGS) {
+#else
+ if ((cts->flags & CCB_TRANS_USER_SETTINGS) != 0) {
+#endif
+ sym_update_trans(np, tp, &tp->tinfo.user, cts);
+ if (lp)
+ sym_update_dflags(np, &lp->user_flags, cts);
+ }
sym_xpt_done2(np, ccb, CAM_REQ_CMP);
break;
@@ -8402,6 +8483,45 @@ static void sym_action2(struct cam_sim *sim, union ccb *ccb)
tp = &np->target[ccb_h->target_id];
lp = sym_lp(np, tp, ccb_h->target_lun);
+#ifdef FreeBSD_New_Tran_Settings
+#define cts__scsi (&cts->proto_specific.scsi)
+#define cts__spi (&cts->xport_specific.spi)
+ if (cts->type == CTS_TYPE_CURRENT_SETTINGS) {
+ tip = &tp->tinfo.current;
+ dflags = lp ? lp->current_flags : 0;
+ }
+ else {
+ tip = &tp->tinfo.user;
+ dflags = lp ? lp->user_flags : tp->usrflags;
+ }
+
+ cts->protocol = PROTO_SCSI;
+ cts->transport = XPORT_SPI;
+ cts->protocol_version = tip->scsi_version;
+ cts->transport_version = tip->spi_version;
+
+ cts__spi->sync_period = tip->period;
+ cts__spi->sync_offset = tip->offset;
+ cts__spi->bus_width = tip->width;
+ cts__spi->ppr_options = tip->options;
+
+ cts__spi->valid = CTS_SPI_VALID_SYNC_RATE
+ | CTS_SPI_VALID_SYNC_OFFSET
+ | CTS_SPI_VALID_BUS_WIDTH
+ | CTS_SPI_VALID_PPR_OPTIONS;
+
+ cts__spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
+ if (dflags & SYM_DISC_ENABLED)
+ cts__spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
+ cts__spi->valid |= CTS_SPI_VALID_DISC;
+
+ cts__scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
+ if (dflags & SYM_TAGS_ENABLED)
+ cts__scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
+ cts__scsi->valid |= CTS_SCSI_VALID_TQ;
+#undef cts__spi
+#undef cts__scsi
+#else
if ((cts->flags & CCB_TRANS_CURRENT_SETTINGS) != 0) {
tip = &tp->tinfo.current;
dflags = lp ? lp->current_flags : 0;
@@ -8419,19 +8539,17 @@ static void sym_action2(struct cam_sim *sim, union ccb *ccb)
| CCB_TRANS_SYNC_OFFSET_VALID
| CCB_TRANS_BUS_WIDTH_VALID;
- if (lp) {
- cts->flags &= ~(CCB_TRANS_DISC_ENB|CCB_TRANS_TAG_ENB);
+ cts->flags &= ~(CCB_TRANS_DISC_ENB|CCB_TRANS_TAG_ENB);
- if (dflags & SYM_DISC_ENABLED)
- cts->flags |= CCB_TRANS_DISC_ENB;
+ if (dflags & SYM_DISC_ENABLED)
+ cts->flags |= CCB_TRANS_DISC_ENB;
- if (dflags & SYM_TAGS_ENABLED)
- cts->flags |= CCB_TRANS_TAG_ENB;
-
- cts->valid |= CCB_TRANS_DISC_VALID;
- cts->valid |= CCB_TRANS_TQ_VALID;
- }
+ if (dflags & SYM_TAGS_ENABLED)
+ cts->flags |= CCB_TRANS_TAG_ENB;
+ cts->valid |= CCB_TRANS_DISC_VALID;
+ cts->valid |= CCB_TRANS_TQ_VALID;
+#endif
sym_xpt_done2(np, ccb, CAM_REQ_CMP);
break;
}
@@ -8488,6 +8606,19 @@ static void sym_action2(struct cam_sim *sim, union ccb *ccb)
strncpy(cpi->hba_vid, "Symbios", HBA_IDLEN);
strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
cpi->unit_number = cam_sim_unit(sim);
+
+#ifdef FreeBSD_New_Tran_Settings
+ cpi->protocol = PROTO_SCSI;
+ cpi->protocol_version = SCSI_REV_2;
+ cpi->transport = XPORT_SPI;
+ cpi->transport_version = 2;
+ cpi->xport_specific.spi.ppr_options = SID_SPI_CLOCK_ST;
+ if (np->features & FE_ULTRA3) {
+ cpi->transport_version = 3;
+ cpi->xport_specific.spi.ppr_options =
+ SID_SPI_CLOCK_DT_ST;
+ }
+#endif
sym_xpt_done2(np, ccb, CAM_REQ_CMP);
break;
}
@@ -8586,13 +8717,31 @@ static void sym_update_trans(hcb_p np, tcb_p tp, struct sym_trans *tip,
/*
* Update the infos.
*/
+#ifdef FreeBSD_New_Tran_Settings
+#define cts__spi (&cts->xport_specific.spi)
+ if ((cts__spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0)
+ tip->width = cts__spi->bus_width;
+ if ((cts__spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)
+ tip->offset = cts__spi->sync_offset;
+ if ((cts__spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0)
+ tip->period = cts__spi->sync_period;
+ if ((cts__spi->valid & CTS_SPI_VALID_PPR_OPTIONS) != 0)
+ tip->options = (cts__spi->ppr_options & PPR_OPT_DT);
+ if (cts->protocol_version != PROTO_VERSION_UNSPECIFIED &&
+ cts->protocol_version != PROTO_VERSION_UNKNOWN)
+ tip->scsi_version = cts->protocol_version;
+ if (cts->transport_version != XPORT_VERSION_UNSPECIFIED &&
+ cts->transport_version != XPORT_VERSION_UNKNOWN)
+ tip->spi_version = cts->transport_version;
+#undef cts__spi
+#else
if ((cts->valid & CCB_TRANS_BUS_WIDTH_VALID) != 0)
tip->width = cts->bus_width;
if ((cts->valid & CCB_TRANS_SYNC_OFFSET_VALID) != 0)
tip->offset = cts->sync_offset;
if ((cts->valid & CCB_TRANS_SYNC_RATE_VALID) != 0)
tip->period = cts->sync_period;
-
+#endif
/*
* Scale against driver configuration limits.
*/
@@ -8606,6 +8755,15 @@ static void sym_update_trans(hcb_p np, tcb_p tp, struct sym_trans *tip,
if (tip->width > np->maxwide)
tip->width = np->maxwide;
+#ifdef FreeBSD_New_Tran_Settings
+ /*
+ * Only accept DT if controller supports and SYNC/WIDE asked.
+ */
+ if (!((np->features & (FE_C10|FE_ULTRA3)) == (FE_C10|FE_ULTRA3)) ||
+ !(tip->width == BUS_16_BIT && tip->offset)) {
+ tip->options &= ~PPR_OPT_DT;
+ }
+#else
/*
* For now, only assume DT if period <= 9, BUS 16 and offset != 0.
*/
@@ -8614,6 +8772,7 @@ static void sym_update_trans(hcb_p np, tcb_p tp, struct sym_trans *tip,
tip->period <= 9 && tip->width == BUS_16_BIT && tip->offset) {
tip->options |= PPR_OPT_DT;
}
+#endif
/*
* Scale period factor and offset against controller limits.
@@ -8642,6 +8801,25 @@ static void sym_update_trans(hcb_p np, tcb_p tp, struct sym_trans *tip,
static void
sym_update_dflags(hcb_p np, u_char *flags, struct ccb_trans_settings *cts)
{
+#ifdef FreeBSD_New_Tran_Settings
+#define cts__scsi (&cts->proto_specific.scsi)
+#define cts__spi (&cts->xport_specific.spi)
+ if ((cts__spi->valid & CTS_SPI_VALID_DISC) != 0) {
+ if ((cts__spi->flags & CTS_SPI_FLAGS_DISC_ENB) != 0)
+ *flags |= SYM_DISC_ENABLED;
+ else
+ *flags &= ~SYM_DISC_ENABLED;
+ }
+
+ if ((cts__scsi->valid & CTS_SCSI_VALID_TQ) != 0) {
+ if ((cts__scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0)
+ *flags |= SYM_TAGS_ENABLED;
+ else
+ *flags &= ~SYM_TAGS_ENABLED;
+ }
+#undef cts__spi
+#undef cts__scsi
+#else
if ((cts->valid & CCB_TRANS_DISC_VALID) != 0) {
if ((cts->flags & CCB_TRANS_DISC_ENB) != 0)
*flags |= SYM_DISC_ENABLED;
@@ -8655,6 +8833,7 @@ sym_update_dflags(hcb_p np, u_char *flags, struct ccb_trans_settings *cts)
else
*flags &= ~SYM_TAGS_ENABLED;
}
+#endif
}
OpenPOWER on IntegriCloud