diff options
Diffstat (limited to 'sys/dev/advansys/advansys.c')
| -rw-r--r-- | sys/dev/advansys/advansys.c | 132 |
1 files changed, 127 insertions, 5 deletions
diff --git a/sys/dev/advansys/advansys.c b/sys/dev/advansys/advansys.c index 6209d9d8fc80..dd14a65e72ce 100644 --- a/sys/dev/advansys/advansys.c +++ b/sys/dev/advansys/advansys.c @@ -288,8 +288,19 @@ adv_action(struct cam_sim *sim, union ccb *ccb) ccb->ccb_h.status = CAM_REQ_INVALID; xpt_done(ccb); break; +#ifdef CAM_NEW_TRAN_CODE +#define IS_CURRENT_SETTINGS(c) (c->type == CTS_TYPE_CURRENT_SETTINGS) +#define IS_USER_SETTINGS(c) (c->type == CTS_TYPE_USER_SETTINGS) +#else +#define IS_CURRENT_SETTINGS(c) (c->flags & CCB_TRANS_CURRENT_SETTINGS) +#define IS_USER_SETTINGS(c) (c->flags & CCB_TRANS_USER_SETTINGS) +#endif case XPT_SET_TRAN_SETTINGS: { +#ifdef CAM_NEW_TRAN_CODE + struct ccb_trans_settings_scsi *scsi; + struct ccb_trans_settings_spi *spi; +#endif struct ccb_trans_settings *cts; target_bit_vector targ_mask; struct adv_transinfo *tconf; @@ -304,12 +315,10 @@ adv_action(struct cam_sim *sim, union ccb *ccb) * The user must specify which type of settings he wishes * to change. */ - if (((cts->flags & CCB_TRANS_CURRENT_SETTINGS) != 0) - && ((cts->flags & CCB_TRANS_USER_SETTINGS) == 0)) { + if (IS_CURRENT_SETTINGS(cts) && !IS_USER_SETTINGS(cts)) { tconf = &adv->tinfo[cts->ccb_h.target_id].current; update_type |= ADV_TRANS_GOAL; - } else if (((cts->flags & CCB_TRANS_USER_SETTINGS) != 0) - && ((cts->flags & CCB_TRANS_CURRENT_SETTINGS) == 0)) { + } else if (IS_USER_SETTINGS(cts) && !IS_CURRENT_SETTINGS(cts)) { tconf = &adv->tinfo[cts->ccb_h.target_id].user; update_type |= ADV_TRANS_USER; } else { @@ -318,7 +327,73 @@ adv_action(struct cam_sim *sim, union ccb *ccb) } s = splcam(); +#ifdef CAM_NEW_TRAN_CODE + scsi = &cts->proto_specific.scsi; + spi = &cts->xport_specific.spi; + if ((update_type & ADV_TRANS_GOAL) != 0) { + if ((spi->valid & CTS_SPI_VALID_DISC) != 0) { + if ((spi->flags & CTS_SPI_FLAGS_DISC_ENB) != 0) + adv->disc_enable |= targ_mask; + else + adv->disc_enable &= ~targ_mask; + adv_write_lram_8(adv, ADVV_DISC_ENABLE_B, + adv->disc_enable); + } + + if ((scsi->valid & CTS_SCSI_VALID_TQ) != 0) { + if ((scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0) + adv->cmd_qng_enabled |= targ_mask; + else + adv->cmd_qng_enabled &= ~targ_mask; + } + } + + if ((update_type & ADV_TRANS_USER) != 0) { + if ((spi->valid & CTS_SPI_VALID_DISC) != 0) { + if ((spi->flags & CTS_SPI_VALID_DISC) != 0) + adv->user_disc_enable |= targ_mask; + else + adv->user_disc_enable &= ~targ_mask; + } + + if ((scsi->valid & CTS_SCSI_VALID_TQ) != 0) { + if ((scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0) + adv->user_cmd_qng_enabled |= targ_mask; + else + adv->user_cmd_qng_enabled &= ~targ_mask; + } + } + + /* + * If the user specifies either the sync rate, or offset, + * but not both, the unspecified parameter defaults to its + * current value in transfer negotiations. + */ + if (((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) + || ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)) { + /* + * If the user provided a sync rate but no offset, + * use the current offset. + */ + if ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) == 0) + spi->sync_offset = tconf->offset; + + /* + * If the user provided an offset but no sync rate, + * use the current sync rate. + */ + if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) == 0) + spi->sync_period = tconf->period; + adv_period_offset_to_sdtr(adv, &spi->sync_period, + &spi->sync_offset, + cts->ccb_h.target_id); + + adv_set_syncrate(adv, /*struct cam_path */NULL, + cts->ccb_h.target_id, spi->sync_period, + spi->sync_offset, update_type); + } +#else if ((update_type & ADV_TRANS_GOAL) != 0) { if ((cts->valid & CCB_TRANS_DISC_VALID) != 0) { if ((cts->flags & CCB_TRANS_DISC_ENB) != 0) @@ -382,6 +457,7 @@ adv_action(struct cam_sim *sim, union ccb *ccb) cts->ccb_h.target_id, cts->sync_period, cts->sync_offset, update_type); } +#endif splx(s); ccb->ccb_h.status = CAM_REQ_CMP; @@ -391,6 +467,10 @@ adv_action(struct cam_sim *sim, union ccb *ccb) case XPT_GET_TRAN_SETTINGS: /* Get default/user set transfer settings for the target */ { +#ifdef CAM_NEW_TRAN_CODE + struct ccb_trans_settings_scsi *scsi; + struct ccb_trans_settings_spi *spi; +#endif struct ccb_trans_settings *cts; struct adv_transinfo *tconf; target_bit_vector target_mask; @@ -399,8 +479,43 @@ adv_action(struct cam_sim *sim, union ccb *ccb) cts = &ccb->cts; target_mask = ADV_TID_TO_TARGET_MASK(cts->ccb_h.target_id); - cts->flags &= ~(CCB_TRANS_DISC_ENB|CCB_TRANS_TAG_ENB); +#ifdef CAM_NEW_TRAN_CODE + scsi = &cts->proto_specific.scsi; + spi = &cts->xport_specific.spi; + + cts->protocol = PROTO_SCSI; + cts->protocol_version = SCSI_REV_2; + cts->transport = XPORT_SPI; + cts->transport_version = 2; + scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB; + spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB; + + s = splcam(); + if (cts->type == CTS_TYPE_CURRENT_SETTINGS) { + tconf = &adv->tinfo[cts->ccb_h.target_id].current; + if ((adv->disc_enable & target_mask) != 0) + spi->flags |= CTS_SPI_FLAGS_DISC_ENB; + if ((adv->cmd_qng_enabled & target_mask) != 0) + scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB; + } else { + tconf = &adv->tinfo[cts->ccb_h.target_id].user; + if ((adv->user_disc_enable & target_mask) != 0) + spi->flags |= CTS_SPI_FLAGS_DISC_ENB; + if ((adv->user_cmd_qng_enabled & target_mask) != 0) + scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB; + } + spi->sync_period = tconf->period; + spi->sync_offset = tconf->offset; + splx(s); + spi->bus_width = MSG_EXT_WDTR_BUS_8_BIT; + spi->valid = CTS_SPI_VALID_SYNC_RATE + | CTS_SPI_VALID_SYNC_OFFSET + | CTS_SPI_VALID_BUS_WIDTH + | CTS_SPI_VALID_DISC; + scsi->valid = CTS_SCSI_VALID_TQ; +#else + cts->flags &= ~(CCB_TRANS_DISC_ENB|CCB_TRANS_TAG_ENB); s = splcam(); if ((cts->flags & CCB_TRANS_CURRENT_SETTINGS) != 0) { tconf = &adv->tinfo[cts->ccb_h.target_id].current; @@ -426,6 +541,7 @@ adv_action(struct cam_sim *sim, union ccb *ccb) | CCB_TRANS_BUS_WIDTH_VALID | CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID; +#endif ccb->ccb_h.status = CAM_REQ_CMP; xpt_done(ccb); break; @@ -477,6 +593,12 @@ adv_action(struct cam_sim *sim, union ccb *ccb) strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); cpi->unit_number = cam_sim_unit(sim); cpi->ccb_h.status = CAM_REQ_CMP; +#ifdef CAM_NEW_TRAN_CODE + cpi->transport = XPORT_SPI; + cpi->transport_version = 2; + cpi->protocol = PROTO_SCSI; + cpi->protocol_version = SCSI_REV_2; +#endif xpt_done(ccb); break; } |
