From fa9ed865067ef325f013a8174c94eff345a4f4ed Mon Sep 17 00:00:00 2001 From: Matt Jacob Date: Tue, 31 Oct 2006 05:53:29 +0000 Subject: The first of 3 major steps to move the CAM layer forward to using the CAM_NEW_TRAN_CODE that has been in the tree for some years now. This first step consists solely of adding to or correcting CAM_NEW_TRAN_CODE pieces in the kernel source tree such that a both a GENERIC (at least on i386) and a LINT build with CAM_NEW_TRAN_CODE as an option will compile correctly and run (at least with some the h/w I have). After a short settle time, the other pieces (making CAM_NEW_TRAN_CODE the default and updating libcam and camcontrol) will be brought in. This will be an incompatible change in that the size of structures related to XPT_PATH_INQ and XPT_{GET,SET}_TRAN_SETTINGS change in both size and content. However, basic system operation and basic system utilities work well enough with this change. Reviewed by: freebsd-scsi and specific stakeholders --- sys/cam/scsi/scsi_low.c | 53 ++++++++++++ sys/dev/aac/aac_cam.c | 24 +++++- sys/dev/advansys/advansys.c | 132 +++++++++++++++++++++++++++-- sys/dev/advansys/advlib.c | 17 +++- sys/dev/advansys/adwcam.c | 200 +++++++++++++++++++++++++++++++++++++++++++- sys/dev/aha/aha.c | 76 ++++++++++++++++- sys/dev/ahb/ahb.c | 60 +++++++++++-- sys/dev/aic/aic.c | 127 +++++++++++++++++++++++++--- sys/dev/amd/amd.c | 187 ++++++++++++++++++++++++++++++++++++++--- sys/dev/amr/amr_cam.c | 34 +++++++- sys/dev/arcmsr/arcmsr.c | 33 +++++++- sys/dev/asr/asr.c | 39 ++++++++- sys/dev/ata/atapi-cam.c | 21 ++++- sys/dev/ciss/ciss.c | 24 +++++- sys/dev/dpt/dpt_scsi.c | 43 +++++++++- sys/dev/esp/ncr53c9x.c | 95 +++++++++++++++++++-- sys/dev/firewire/sbp.c | 29 ++++++- sys/dev/iir/iir.c | 40 +++++++-- sys/dev/isp/isp_freebsd.c | 1 - sys/dev/mly/mly.c | 67 ++++++++++++++- sys/dev/mpt/mpt_cam.c | 28 +++++-- sys/dev/trm/trm.c | 166 ++++++++++++++++++++++++++++++++++-- sys/dev/twa/tw_osl_cam.c | 26 +++++- sys/dev/usb/umass.c | 8 ++ sys/pci/ncr.c | 182 ++++++++++++++++++++++++++++++++++++++-- 25 files changed, 1616 insertions(+), 96 deletions(-) (limited to 'sys') diff --git a/sys/cam/scsi/scsi_low.c b/sys/cam/scsi/scsi_low.c index dc9a492ab912..d767a1c63230 100644 --- a/sys/cam/scsi/scsi_low.c +++ b/sys/cam/scsi/scsi_low.c @@ -1084,6 +1084,10 @@ scsi_low_scsi_action_cam(sim, ccb) break; 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; u_int val; @@ -1102,6 +1106,7 @@ scsi_low_scsi_action_cam(sim, ccb) lun = 0; s = SCSI_LOW_SPLSCSI(); +#ifndef CAM_NEW_TRAN_CODE if ((cts->valid & (CCB_TRANS_BUS_WIDTH_VALID | CCB_TRANS_SYNC_RATE_VALID | CCB_TRANS_SYNC_OFFSET_VALID)) != 0) @@ -1151,6 +1156,54 @@ scsi_low_scsi_action_cam(sim, ccb) if ((slp->sl_show_result & SHOW_CALCF_RES) != 0) scsi_low_calcf_show(li); } +#else + scsi = &cts->proto_specific.scsi; + spi = &cts->xport_specific.spi; + if ((spi->valid & (CTS_SPI_VALID_BUS_WIDTH | + CTS_SPI_VALID_SYNC_RATE | + CTS_SPI_VALID_SYNC_OFFSET)) != 0) + { + if (spi->valid & CTS_SPI_VALID_BUS_WIDTH) { + val = spi->bus_width; + if (val < ti->ti_width) + ti->ti_width = val; + } + if (spi->valid & CTS_SPI_VALID_SYNC_RATE) { + val = spi->sync_period; + if (val == 0 || val > ti->ti_maxsynch.period) + ti->ti_maxsynch.period = val; + } + if (spi->valid & CTS_SPI_VALID_SYNC_OFFSET) { + val = spi->sync_offset; + if (val < ti->ti_maxsynch.offset) + ti->ti_maxsynch.offset = val; + } + ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_QUIRKS_VALID; + scsi_low_calcf_target(ti); + } + + if ((spi->valid & CTS_SPI_FLAGS_DISC_ENB) != 0 || + (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0) { + + li = scsi_low_alloc_li(ti, lun, 1); + if (spi->valid & CTS_SPI_FLAGS_DISC_ENB) { + li->li_quirks |= SCSI_LOW_DISK_DISC; + } else { + li->li_quirks &= ~SCSI_LOW_DISK_DISC; + } + + if (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) { + li->li_quirks |= SCSI_LOW_DISK_QTAG; + } else { + li->li_quirks &= ~SCSI_LOW_DISK_QTAG; + } + li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_QUIRKS_VALID; + scsi_low_calcf_target(ti); + scsi_low_calcf_lun(li); + if ((slp->sl_show_result & SHOW_CALCF_RES) != 0) + scsi_low_calcf_show(li); + } +#endif splx(s); ccb->ccb_h.status = CAM_REQ_CMP; diff --git a/sys/dev/aac/aac_cam.c b/sys/dev/aac/aac_cam.c index 8d2fc9b38dbc..f6dbb7ecd263 100644 --- a/sys/dev/aac/aac_cam.c +++ b/sys/dev/aac/aac_cam.c @@ -263,15 +263,37 @@ aac_cam_action(struct cam_sim *sim, union ccb *ccb) strncpy(cpi->hba_vid, "Adaptec", HBA_IDLEN); strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); cpi->unit_number = cam_sim_unit(sim); - +#ifdef CAM_NEW_TRAN_CODE + cpi->transport = XPORT_SPI; + cpi->transport_version = 2; + cpi->protocol = PROTO_SCSI; + cpi->protocol_version = SCSI_REV_2; +#endif ccb->ccb_h.status = CAM_REQ_CMP; xpt_done(ccb); return; } case XPT_GET_TRAN_SETTINGS: { +#ifdef CAM_NEW_TRAN_CODE + struct ccb_trans_settings_scsi *scsi = + &ccb->cts.proto_specific.scsi; + struct ccb_trans_settings_spi *spi = + &ccb->cts.xport_specific.spi; + ccb->cts.protocol = PROTO_SCSI; + ccb->cts.protocol_version = SCSI_REV_2; + ccb->cts.transport = XPORT_SPI; + ccb->cts.transport_version = 2; + if (ccb->ccb_h.target_lun != CAM_LUN_WILDCARD) { + scsi->valid = CTS_SCSI_VALID_TQ; + spi->valid |= CTS_SPI_VALID_DISC; + } else { + scsi->valid = 0; + } +#else ccb->cts.flags &= ~(CCB_TRANS_DISC_ENB | CCB_TRANS_TAG_ENB); ccb->cts.valid = CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID; +#endif ccb->ccb_h.status = CAM_REQ_CMP; xpt_done(ccb); return; 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; } diff --git a/sys/dev/advansys/advlib.c b/sys/dev/advansys/advlib.c index 565b8c2bc594..04c15a4940d1 100644 --- a/sys/dev/advansys/advlib.c +++ b/sys/dev/advansys/advlib.c @@ -1135,11 +1135,26 @@ adv_set_syncrate(struct adv_softc *adv, struct cam_path *path, * new transfer parameters. */ struct ccb_trans_settings neg; - + memset(&neg, 0, sizeof (neg)); +#ifdef CAM_NEW_TRAN_CODE + struct ccb_trans_settings_spi *spi = + &neg.xport_specific.spi; + + neg.protocol = PROTO_SCSI; + neg.protocol_version = SCSI_REV_2; + neg.transport = XPORT_SPI; + neg.transport_version = 2; + + spi->sync_offset = offset; + spi->sync_period = period; + spi->valid |= CTS_SPI_VALID_SYNC_OFFSET; + spi->valid |= CTS_SPI_VALID_SYNC_RATE; +#else neg.sync_period = period; neg.sync_offset = offset; neg.valid = CCB_TRANS_SYNC_RATE_VALID | CCB_TRANS_SYNC_OFFSET_VALID; +#endif xpt_setup_ccb(&neg.ccb_h, path, /*priority*/1); xpt_async(AC_TRANSFER_NEG, path, &neg); } diff --git a/sys/dev/advansys/adwcam.c b/sys/dev/advansys/adwcam.c index 5de2a48b08a8..2f3c33b4adc5 100644 --- a/sys/dev/advansys/adwcam.c +++ b/sys/dev/advansys/adwcam.c @@ -525,6 +525,10 @@ adw_action(struct cam_sim *sim, union ccb *ccb) break; 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; u_int target_mask; int s; @@ -533,6 +537,119 @@ adw_action(struct cam_sim *sim, union ccb *ccb) target_mask = 0x01 << ccb->ccb_h.target_id; s = splcam(); +#ifdef CAM_NEW_TRAN_CODE + scsi = &cts->proto_specific.scsi; + spi = &cts->xport_specific.spi; + if (cts->type == CTS_TYPE_CURRENT_SETTINGS) { + u_int sdtrdone; + + sdtrdone = adw_lram_read_16(adw, ADW_MC_SDTR_DONE); + if ((spi->valid & CTS_SPI_VALID_DISC) != 0) { + u_int discenb; + + discenb = + adw_lram_read_16(adw, ADW_MC_DISC_ENABLE); + + if ((spi->flags & CTS_SPI_FLAGS_DISC_ENB) != 0) + discenb |= target_mask; + else + discenb &= ~target_mask; + + adw_lram_write_16(adw, ADW_MC_DISC_ENABLE, + discenb); + } + + if ((scsi->valid & CTS_SCSI_VALID_TQ) != 0) { + + if ((scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0) + adw->tagenb |= target_mask; + else + adw->tagenb &= ~target_mask; + } + + if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) { + u_int wdtrenb_orig; + u_int wdtrenb; + u_int wdtrdone; + + wdtrenb_orig = + adw_lram_read_16(adw, ADW_MC_WDTR_ABLE); + wdtrenb = wdtrenb_orig; + wdtrdone = adw_lram_read_16(adw, + ADW_MC_WDTR_DONE); + switch (spi->bus_width) { + case MSG_EXT_WDTR_BUS_32_BIT: + case MSG_EXT_WDTR_BUS_16_BIT: + wdtrenb |= target_mask; + break; + case MSG_EXT_WDTR_BUS_8_BIT: + default: + wdtrenb &= ~target_mask; + break; + } + if (wdtrenb != wdtrenb_orig) { + adw_lram_write_16(adw, + ADW_MC_WDTR_ABLE, + wdtrenb); + wdtrdone &= ~target_mask; + adw_lram_write_16(adw, + ADW_MC_WDTR_DONE, + wdtrdone); + /* Wide negotiation forces async */ + sdtrdone &= ~target_mask; + adw_lram_write_16(adw, + ADW_MC_SDTR_DONE, + sdtrdone); + } + } + + if (((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) + || ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)) { + u_int sdtr_orig; + u_int sdtr; + u_int sdtrable_orig; + u_int sdtrable; + + sdtr = adw_get_chip_sdtr(adw, + ccb->ccb_h.target_id); + sdtr_orig = sdtr; + sdtrable = adw_lram_read_16(adw, + ADW_MC_SDTR_ABLE); + sdtrable_orig = sdtrable; + + if ((spi->valid + & CTS_SPI_VALID_SYNC_RATE) != 0) { + + sdtr = + adw_find_sdtr(adw, + spi->sync_period); + } + + if ((spi->valid + & CTS_SPI_VALID_SYNC_OFFSET) != 0) { + if (spi->sync_offset == 0) + sdtr = ADW_MC_SDTR_ASYNC; + } + + if (sdtr == ADW_MC_SDTR_ASYNC) + sdtrable &= ~target_mask; + else + sdtrable |= target_mask; + if (sdtr != sdtr_orig + || sdtrable != sdtrable_orig) { + adw_set_chip_sdtr(adw, + ccb->ccb_h.target_id, + sdtr); + sdtrdone &= ~target_mask; + adw_lram_write_16(adw, ADW_MC_SDTR_ABLE, + sdtrable); + adw_lram_write_16(adw, ADW_MC_SDTR_DONE, + sdtrdone); + + } + } + } +#else if ((cts->flags & CCB_TRANS_CURRENT_SETTINGS) != 0) { u_int sdtrdone; @@ -642,6 +759,7 @@ adw_action(struct cam_sim *sim, union ccb *ccb) } } } +#endif splx(s); ccb->ccb_h.status = CAM_REQ_CMP; xpt_done(ccb); @@ -650,12 +768,85 @@ adw_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; u_int target_mask; cts = &ccb->cts; target_mask = 0x01 << ccb->ccb_h.target_id; - if ((cts->flags & CCB_TRANS_USER_SETTINGS) != 0) { +#ifdef CAM_NEW_TRAN_CODE + cts->protocol = PROTO_SCSI; + cts->protocol_version = SCSI_REV_2; + cts->transport = XPORT_SPI; + cts->transport_version = 2; + + scsi = &cts->proto_specific.scsi; + spi = &cts->xport_specific.spi; + if (cts->type == CTS_TYPE_CURRENT_SETTINGS) { + u_int mc_sdtr; + + spi->flags = 0; + if ((adw->user_discenb & target_mask) != 0) + spi->flags |= CTS_SPI_FLAGS_DISC_ENB; + + if ((adw->user_tagenb & target_mask) != 0) + scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB; + + if ((adw->user_wdtr & target_mask) != 0) + spi->bus_width = MSG_EXT_WDTR_BUS_16_BIT; + else + spi->bus_width = MSG_EXT_WDTR_BUS_8_BIT; + + mc_sdtr = adw_get_user_sdtr(adw, ccb->ccb_h.target_id); + spi->sync_period = adw_find_period(adw, mc_sdtr); + if (spi->sync_period != 0) + spi->sync_offset = 15; /* XXX ??? */ + else + spi->sync_offset = 0; + + + } else { + u_int targ_tinfo; + + spi->flags = 0; + if ((adw_lram_read_16(adw, ADW_MC_DISC_ENABLE) + & target_mask) != 0) + spi->flags |= CTS_SPI_FLAGS_DISC_ENB; + + if ((adw->tagenb & target_mask) != 0) + scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB; + + targ_tinfo = + adw_lram_read_16(adw, + ADW_MC_DEVICE_HSHK_CFG_TABLE + + (2 * ccb->ccb_h.target_id)); + + if ((targ_tinfo & ADW_HSHK_CFG_WIDE_XFR) != 0) + spi->bus_width = MSG_EXT_WDTR_BUS_16_BIT; + else + spi->bus_width = MSG_EXT_WDTR_BUS_8_BIT; + + spi->sync_period = + adw_hshk_cfg_period_factor(targ_tinfo); + + spi->sync_offset = targ_tinfo & ADW_HSHK_CFG_OFFSET; + if (spi->sync_period == 0) + spi->sync_offset = 0; + + if (spi->sync_offset == 0) + spi->sync_period = 0; + } + + 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 + if ((cts->flags & CCB_TRANS_USER_SETTINGS) != 0) { u_int mc_sdtr; cts->flags = 0; @@ -719,6 +910,7 @@ adw_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; @@ -773,6 +965,12 @@ adw_action(struct cam_sim *sim, union ccb *ccb) strncpy(cpi->hba_vid, "AdvanSys", HBA_IDLEN); strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); cpi->unit_number = cam_sim_unit(sim); +#ifdef CAM_NEW_TRAN_CODE + cpi->transport = XPORT_SPI; + cpi->transport_version = 2; + cpi->protocol = PROTO_SCSI; + cpi->protocol_version = SCSI_REV_2; +#endif cpi->ccb_h.status = CAM_REQ_CMP; xpt_done(ccb); break; diff --git a/sys/dev/aha/aha.c b/sys/dev/aha/aha.c index b828a9daf84c..6678e1c39599 100644 --- a/sys/dev/aha/aha.c +++ b/sys/dev/aha/aha.c @@ -899,11 +899,44 @@ ahaaction(struct cam_sim *sim, union ccb *ccb) case XPT_GET_TRAN_SETTINGS: /* Get default/user set transfer settings for the target */ { - struct ccb_trans_settings *cts; - u_int target_mask; + struct ccb_trans_settings *cts = &ccb->cts; + u_int target_mask = 0x01 << ccb->ccb_h.target_id; +#ifdef CAM_NEW_TRAN_CODE + struct ccb_trans_settings_scsi *scsi = + &cts->proto_specific.scsi; + struct ccb_trans_settings_spi *spi = + &cts->xport_specific.spi; + + cts->protocol = PROTO_SCSI; + cts->protocol_version = SCSI_REV_2; + cts->transport = XPORT_SPI; + cts->transport_version = 2; + if (cts->type == CTS_TYPE_USER_SETTINGS) { + spi->flags = 0; + if ((aha->disc_permitted & target_mask) != 0) + spi->flags |= CTS_SPI_FLAGS_DISC_ENB; + spi->bus_width = MSG_EXT_WDTR_BUS_8_BIT; + if ((aha->sync_permitted & target_mask) != 0) { + if (aha->boardid >= BOARD_1542CF) + spi->sync_period = 25; + else + spi->sync_period = 50; + } else { + spi->sync_period = 0; + } - cts = &ccb->cts; - target_mask = 0x01 << ccb->ccb_h.target_id; + if (spi->sync_period != 0) + spi->sync_offset = 15; + + 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 { + ahafetchtransinfo(aha, cts); + } +#else if ((cts->flags & CCB_TRANS_USER_SETTINGS) != 0) { cts->flags = 0; if ((aha->disc_permitted & target_mask) != 0) @@ -928,6 +961,7 @@ ahaaction(struct cam_sim *sim, union ccb *ccb) } else { ahafetchtransinfo(aha, cts); } +#endif ccb->ccb_h.status = CAM_REQ_CMP; xpt_done(ccb); @@ -988,6 +1022,12 @@ ahaaction(struct cam_sim *sim, union ccb *ccb) strncpy(cpi->hba_vid, "Adaptec", HBA_IDLEN); strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); cpi->unit_number = cam_sim_unit(sim); +#ifdef CAM_NEW_TRAN_CODE + cpi->transport = XPORT_SPI; + cpi->transport_version = 2; + cpi->protocol = PROTO_SCSI; + cpi->protocol_version = SCSI_REV_2; +#endif cpi->ccb_h.status = CAM_REQ_CMP; xpt_done(ccb); break; @@ -1674,6 +1714,9 @@ ahafetchtransinfo(struct aha_softc *aha, struct ccb_trans_settings* cts) int error; uint8_t param; targ_syncinfo_t sync_info; +#ifdef CAM_NEW_TRAN_CODE + struct ccb_trans_settings_spi *spi = &cts->xport_specific.spi; +#endif target = cts->ccb_h.target_id; targ_offset = (target & 0x7); @@ -1695,6 +1738,30 @@ ahafetchtransinfo(struct aha_softc *aha, struct ccb_trans_settings* cts) sync_info = setup_info.syncinfo[targ_offset]; +#ifdef CAM_NEW_TRAN_CODE + if (sync_info.sync == 0) + spi->sync_offset = 0; + else + spi->sync_offset = sync_info.offset; + + spi->bus_width = MSG_EXT_WDTR_BUS_8_BIT; + + if (aha->boardid >= BOARD_1542CF) + sync_period = 1000; + else + sync_period = 2000; + sync_period += 500 * sync_info.period; + + /* Convert ns value to standard SCSI sync rate */ + if (spi->sync_offset != 0) + spi->sync_period = scsi_calc_syncparam(sync_period); + else + spi->sync_period = 0; + + spi->valid = CTS_SPI_VALID_SYNC_RATE + | CTS_SPI_VALID_SYNC_OFFSET + | CTS_SPI_VALID_BUS_WIDTH; +#else if (sync_info.sync == 0) cts->sync_offset = 0; else @@ -1717,6 +1784,7 @@ ahafetchtransinfo(struct aha_softc *aha, struct ccb_trans_settings* cts) cts->valid = CCB_TRANS_SYNC_RATE_VALID | CCB_TRANS_SYNC_OFFSET_VALID | CCB_TRANS_BUS_WIDTH_VALID; +#endif xpt_async(AC_TRANSFER_NEG, cts->ccb_h.path, cts); } diff --git a/sys/dev/ahb/ahb.c b/sys/dev/ahb/ahb.c index f056f08189e6..213fa1155eb2 100644 --- a/sys/dev/ahb/ahb.c +++ b/sys/dev/ahb/ahb.c @@ -728,12 +728,24 @@ ahbprocesserror(struct ahb_softc *ahb, struct ecb *ecb, union ccb *ccb) case HS_TAG_MSG_REJECTED: { struct ccb_trans_settings neg; +#ifdef CAM_NEW_TRAN_CODE + struct ccb_trans_settings_scsi *scsi = &neg.proto_specific.scsi; +#endif xpt_print_path(ccb->ccb_h.path); printf("refuses tagged commands. Performing " "non-tagged I/O\n"); + memset(&neg, 0, sizeof (neg)); +#ifdef CAM_NEW_TRAN_CODE + neg.protocol = PROTO_SCSI; + neg.protocol_version = SCSI_REV_2; + neg.transport = XPORT_SPI; + neg.transport_version = 2; + scsi->flags = CTS_SCSI_VALID_TQ; +#else neg.flags = 0; neg.valid = CCB_TRANS_TQ_VALID; +#endif xpt_setup_ccb(&neg.ccb_h, ccb->ccb_h.path, /*priority*/1); xpt_async(AC_TRANSFER_NEG, ccb->ccb_h.path, &neg); ahb->tags_permitted &= ~(0x01 << ccb->ccb_h.target_id); @@ -1128,11 +1140,42 @@ ahbaction(struct cam_sim *sim, union ccb *ccb) case XPT_GET_TRAN_SETTINGS: /* Get default/user set transfer settings for the target */ { - struct ccb_trans_settings *cts; - u_int target_mask; - - cts = &ccb->cts; - target_mask = 0x01 << ccb->ccb_h.target_id; + struct ccb_trans_settings *cts = &ccb->cts; + u_int target_mask = 0x01 << ccb->ccb_h.target_id; +#ifdef CAM_NEW_TRAN_CODE + struct ccb_trans_settings_scsi *scsi = + &cts->proto_specific.scsi; + struct ccb_trans_settings_spi *spi = + &cts->xport_specific.spi; + + if (cts->type == CTS_TYPE_USER_SETTINGS) { + 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; + if ((ahb->disc_permitted & target_mask) != 0) + spi->flags |= CTS_SPI_FLAGS_DISC_ENB; + if ((ahb->tags_permitted & target_mask) != 0) + scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB; + spi->bus_width = MSG_EXT_WDTR_BUS_8_BIT; + spi->sync_period = 25; /* 10MHz */ + + if (spi->sync_period != 0) + spi->sync_offset = 15; + + 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; + ccb->ccb_h.status = CAM_REQ_CMP; + } else { + ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; + } +#else if ((cts->flags & CCB_TRANS_USER_SETTINGS) != 0) { cts->flags = 0; if ((ahb->disc_permitted & target_mask) != 0) @@ -1154,6 +1197,7 @@ ahbaction(struct cam_sim *sim, union ccb *ccb) } else { ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; } +#endif xpt_done(ccb); break; } @@ -1215,6 +1259,12 @@ ahbaction(struct cam_sim *sim, union ccb *ccb) strncpy(cpi->hba_vid, "Adaptec", HBA_IDLEN); strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); cpi->unit_number = cam_sim_unit(sim); +#ifdef CAM_NEW_TRAN_CODE + cpi->transport = XPORT_SPI; + cpi->transport_version = 2; + cpi->protocol = PROTO_SCSI; + cpi->protocol_version = SCSI_REV_2; +#endif cpi->ccb_h.status = CAM_REQ_CMP; xpt_done(ccb); break; diff --git a/sys/dev/aic/aic.c b/sys/dev/aic/aic.c index b09d3e82bc07..c912153ad1ce 100644 --- a/sys/dev/aic/aic.c +++ b/sys/dev/aic/aic.c @@ -165,14 +165,56 @@ aic_action(struct cam_sim *sim, union ccb *ccb) } case XPT_SET_TRAN_SETTINGS: { - struct ccb_trans_settings *cts; - struct aic_tinfo *ti; - - cts = &ccb->cts; - ti = &aic->tinfo[ccb->ccb_h.target_id]; + struct ccb_trans_settings *cts = cts = &ccb->cts; + struct aic_tinfo *ti = &aic->tinfo[ccb->ccb_h.target_id]; +#ifdef CAM_NEW_TRAN_CODE + struct ccb_trans_settings_scsi *scsi = + &cts->proto_specific.scsi; + struct ccb_trans_settings_spi *spi = + &cts->xport_specific.spi; s = splcam(); + if ((spi->valid & CTS_SPI_VALID_DISC) != 0 && + (aic->flags & AIC_DISC_ENABLE) != 0) { + if ((spi->flags & CTS_SPI_FLAGS_DISC_ENB) != 0) + ti->flags |= TINFO_DISC_ENB; + else + ti->flags &= ~TINFO_DISC_ENB; + } + + if ((scsi->valid & CTS_SCSI_VALID_TQ) != 0) { + if ((scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0) + ti->flags |= TINFO_TAG_ENB; + else + ti->flags &= ~TINFO_TAG_ENB; + } + + if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) { + ti->goal.period = spi->sync_period; + + if (ti->goal.period > aic->min_period) { + ti->goal.period = 0; + ti->goal.offset = 0; + } else if (ti->goal.period < aic->max_period) + ti->goal.period = aic->max_period; + } + + if ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0) { + ti->goal.offset = spi->sync_offset; + if (ti->goal.offset == 0) + ti->goal.period = 0; + else if (ti->goal.offset > AIC_SYNC_OFFSET) + ti->goal.offset = AIC_SYNC_OFFSET; + } + + if ((ti->goal.period != ti->current.period) + || (ti->goal.offset != ti->current.offset)) + ti->flags |= TINFO_SDTR_NEGO; + + splx(s); +#else + s = splcam(); if ((cts->valid & CCB_TRANS_DISC_VALID) != 0 && (aic->flags & AIC_DISC_ENABLE) != 0) { if ((cts->flags & CCB_TRANS_DISC_ENB) != 0) @@ -211,20 +253,51 @@ aic_action(struct cam_sim *sim, union ccb *ccb) ti->flags |= TINFO_SDTR_NEGO; splx(s); +#endif ccb->ccb_h.status = CAM_REQ_CMP; xpt_done(ccb); break; } case XPT_GET_TRAN_SETTINGS: { - struct ccb_trans_settings *cts; - struct aic_tinfo *ti; - - cts = &ccb->cts; - ti = &aic->tinfo[ccb->ccb_h.target_id]; + struct ccb_trans_settings *cts = &ccb->cts; + struct aic_tinfo *ti = &aic->tinfo[ccb->ccb_h.target_id]; +#ifdef CAM_NEW_TRAN_CODE + struct ccb_trans_settings_scsi *scsi = + &cts->proto_specific.scsi; + struct ccb_trans_settings_spi *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 ((ti->flags & TINFO_DISC_ENB) != 0) + spi->flags |= CTS_SPI_FLAGS_DISC_ENB; + if ((ti->flags & TINFO_TAG_ENB) != 0) + scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB; + if (cts->type == CTS_TYPE_CURRENT_SETTINGS) { + spi->sync_period = ti->current.period; + spi->sync_offset = ti->current.offset; + } else { + spi->sync_period = ti->user.period; + spi->sync_offset = ti->user.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 + s = splcam(); cts->flags &= ~(CCB_TRANS_DISC_ENB|CCB_TRANS_TAG_ENB); if ((ti->flags & TINFO_DISC_ENB) != 0) cts->flags |= CCB_TRANS_DISC_ENB; @@ -247,6 +320,7 @@ aic_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); @@ -281,6 +355,12 @@ aic_action(struct cam_sim *sim, union ccb *ccb) strncpy(cpi->hba_vid, "Adaptec", HBA_IDLEN); strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); cpi->unit_number = cam_sim_unit(sim); +#ifdef CAM_NEW_TRAN_CODE + cpi->transport = XPORT_SPI; + cpi->transport_version = 2; + cpi->protocol = PROTO_SCSI; + cpi->protocol_version = SCSI_REV_2; +#endif cpi->ccb_h.status = CAM_REQ_CMP; xpt_done(ccb); break; @@ -598,6 +678,9 @@ aic_handle_msgin(struct aic_softc *aic) struct ccb_hdr *ccb_h; struct aic_tinfo *ti; struct ccb_trans_settings neg; +#ifdef CAM_NEW_TRAN_CODE + struct ccb_trans_settings_spi *spi = &neg.xport_specific.spi; +#endif if (aic->state == AIC_RESELECTED) { if (!MSG_ISIDENTIFY(aic->msg_buf[0])) { @@ -683,10 +766,22 @@ aic_handle_msgin(struct aic_softc *aic) ti->scsirate = ti->current.offset ? ti->current.offset | ((ti->current.period * 4 + 49) / 50 - 2) << 4 : 0; aic_outb(aic, SCSIRATE, ti->scsirate); + memset(&neg, 0, sizeof (neg)); +#ifdef CAM_NEW_TRAN_CODE + neg.protocol = PROTO_SCSI; + neg.protocol_version = SCSI_REV_2; + neg.transport = XPORT_SPI; + neg.transport_version = 2; + spi->sync_period = ti->goal.period = ti->current.period; + spi->sync_offset = ti->goal.offset = ti->current.offset; + spi->valid = CTS_SPI_VALID_SYNC_RATE + | CTS_SPI_VALID_SYNC_OFFSET; +#else neg.sync_period = ti->goal.period = ti->current.period; neg.sync_offset = ti->goal.offset = ti->current.offset; neg.valid = CCB_TRANS_SYNC_RATE_VALID | CCB_TRANS_SYNC_OFFSET_VALID; +#endif ccb_h = &scb->ccb->ccb_h; xpt_setup_ccb(&neg.ccb_h, ccb_h->path, 1); xpt_async(AC_TRANSFER_NEG, ccb_h->path, &neg); @@ -722,10 +817,22 @@ aic_handle_msgin(struct aic_softc *aic) ti->flags &= ~(TINFO_SDTR_SENT|TINFO_SDTR_NEGO); ti->scsirate = 0; aic_outb(aic, SCSIRATE, ti->scsirate); + memset(&neg, 0, sizeof (neg)); +#ifdef CAM_NEW_TRAN_CODE + neg.protocol = PROTO_SCSI; + neg.protocol_version = SCSI_REV_2; + neg.transport = XPORT_SPI; + neg.transport_version = 2; + spi->sync_period = ti->current.period; + spi->sync_offset = ti->current.offset; + spi->valid = CTS_SPI_VALID_SYNC_RATE + | CTS_SPI_VALID_SYNC_OFFSET; +#else neg.sync_period = ti->current.period; neg.sync_offset = ti->current.offset; neg.valid = CCB_TRANS_SYNC_RATE_VALID | CCB_TRANS_SYNC_OFFSET_VALID; +#endif ccb_h = &scb->ccb->ccb_h; xpt_setup_ccb(&neg.ccb_h, ccb_h->path, 1); xpt_async(AC_TRANSFER_NEG, ccb_h->path, &neg); diff --git a/sys/dev/amd/amd.c b/sys/dev/amd/amd.c index a91bd68487c4..c92645ae14b3 100644 --- a/sys/dev/amd/amd.c +++ b/sys/dev/amd/amd.c @@ -504,6 +504,12 @@ amd_action(struct cam_sim * psim, union ccb * pccb) strncpy(cpi->hba_vid, "TRM-AMD", HBA_IDLEN); strncpy(cpi->dev_name, cam_sim_name(psim), DEV_IDLEN); cpi->unit_number = cam_sim_unit(psim); +#ifdef CAM_NEW_TRAN_CODE + cpi->transport = XPORT_SPI; + cpi->transport_version = 2; + cpi->protocol = PROTO_SCSI; + cpi->protocol_version = SCSI_REV_2; +#endif cpi->ccb_h.status = CAM_REQ_CMP; xpt_done(pccb); break; @@ -536,17 +542,64 @@ amd_action(struct cam_sim * psim, union ccb * pccb) case XPT_TERM_IO: pccb->ccb_h.status = CAM_REQ_INVALID; xpt_done(pccb); - /* XXX: intentional fall-through ?? */ + break; case XPT_GET_TRAN_SETTINGS: { - struct ccb_trans_settings *cts; - struct amd_target_info *targ_info; + struct ccb_trans_settings *cts = &pccb->cts; + struct amd_target_info *targ_info = &amd->tinfo[target_id]; struct amd_transinfo *tinfo; int intflag; +#ifdef CAM_NEW_TRAN_CODE + struct ccb_trans_settings_scsi *scsi = + &cts->proto_specific.scsi; + struct ccb_trans_settings_spi *spi = + &cts->xport_specific.spi; + + cts->protocol = PROTO_SCSI; + cts->protocol_version = SCSI_REV_2; + cts->transport = XPORT_SPI; + cts->transport_version = 2; - cts = &pccb->cts; intflag = splcam(); - targ_info = &amd->tinfo[target_id]; + if (cts->type == CTS_TYPE_CURRENT_SETTINGS) { + /* current transfer settings */ + if (targ_info->disc_tag & AMD_CUR_DISCENB) { + spi->flags = CTS_SPI_FLAGS_DISC_ENB; + } else { + spi->flags = 0; + } + if (targ_info->disc_tag & AMD_CUR_TAGENB) { + scsi->flags = CTS_SCSI_FLAGS_TAG_ENB; + } else { + scsi->flags = 0; + } + tinfo = &targ_info->current; + } else { + /* default(user) transfer settings */ + if (targ_info->disc_tag & AMD_USR_DISCENB) { + spi->flags = CTS_SPI_FLAGS_DISC_ENB; + } else { + spi->flags = 0; + } + if (targ_info->disc_tag & AMD_USR_TAGENB) { + scsi->flags = CTS_SCSI_FLAGS_TAG_ENB; + } else { + scsi->flags = 0; + } + tinfo = &targ_info->user; + } + spi->sync_period = tinfo->period; + spi->sync_offset = tinfo->offset; + splx(intflag); + + 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 + intflag = splcam(); if ((cts->flags & CCB_TRANS_CURRENT_SETTINGS) != 0) { /* current transfer settings */ if (targ_info->disc_tag & AMD_CUR_DISCENB) { @@ -575,28 +628,40 @@ amd_action(struct cam_sim * psim, union ccb * pccb) cts->sync_offset = tinfo->offset; cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT; splx(intflag); + cts->valid = CCB_TRANS_SYNC_RATE_VALID | CCB_TRANS_SYNC_OFFSET_VALID | CCB_TRANS_BUS_WIDTH_VALID | CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID; +#endif pccb->ccb_h.status = CAM_REQ_CMP; xpt_done(pccb); 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: { - struct ccb_trans_settings *cts; + struct ccb_trans_settings *cts = &pccb->cts; struct amd_target_info *targ_info; - u_int update_type; + u_int update_type = 0; int intflag; int last_entry; - - cts = &pccb->cts; - update_type = 0; - if ((cts->flags & CCB_TRANS_CURRENT_SETTINGS) != 0) { +#ifdef CAM_NEW_TRAN_CODE + struct ccb_trans_settings_scsi *scsi = + &cts->proto_specific.scsi; + struct ccb_trans_settings_spi *spi = + &cts->xport_specific.spi; +#endif + if (IS_CURRENT_SETTINGS(cts)) { update_type |= AMD_TRANS_GOAL; - } else if ((cts->flags & CCB_TRANS_USER_SETTINGS) != 0) { + } else if (IS_USER_SETTINGS(cts)) { update_type |= AMD_TRANS_USER; } if (update_type == 0 @@ -605,6 +670,82 @@ amd_action(struct cam_sim * psim, union ccb * pccb) xpt_done(pccb); } +#ifdef CAM_NEW_TRAN_CODE + intflag = splcam(); + targ_info = &amd->tinfo[target_id]; + + if ((spi->valid & CTS_SPI_VALID_DISC) != 0) { + if (update_type & AMD_TRANS_GOAL) { + if ((spi->flags & CTS_SPI_FLAGS_DISC_ENB) + != 0) { + targ_info->disc_tag |= AMD_CUR_DISCENB; + } else { + targ_info->disc_tag &= ~AMD_CUR_DISCENB; + } + } + if (update_type & AMD_TRANS_USER) { + if ((spi->flags & CTS_SPI_FLAGS_DISC_ENB) + != 0) { + targ_info->disc_tag |= AMD_USR_DISCENB; + } else { + targ_info->disc_tag &= ~AMD_USR_DISCENB; + } + } + } + if ((scsi->valid & CTS_SCSI_VALID_TQ) != 0) { + if (update_type & AMD_TRANS_GOAL) { + if ((scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) + != 0) { + targ_info->disc_tag |= AMD_CUR_TAGENB; + } else { + targ_info->disc_tag &= ~AMD_CUR_TAGENB; + } + } + if (update_type & AMD_TRANS_USER) { + if ((scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) + != 0) { + targ_info->disc_tag |= AMD_USR_TAGENB; + } else { + targ_info->disc_tag &= ~AMD_USR_TAGENB; + } + } + } + + if ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) == 0) { + if (update_type & AMD_TRANS_GOAL) + spi->sync_offset = targ_info->goal.offset; + else + spi->sync_offset = targ_info->user.offset; + } + + if (spi->sync_offset > AMD_MAX_SYNC_OFFSET) + spi->sync_offset = AMD_MAX_SYNC_OFFSET; + + if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) == 0) { + if (update_type & AMD_TRANS_GOAL) + spi->sync_period = targ_info->goal.period; + else + spi->sync_period = targ_info->user.period; + } + + last_entry = sizeof(tinfo_sync_period) - 1; + if ((spi->sync_period != 0) + && (spi->sync_period < tinfo_sync_period[0])) + spi->sync_period = tinfo_sync_period[0]; + if (spi->sync_period > tinfo_sync_period[last_entry]) + spi->sync_period = 0; + if (spi->sync_offset == 0) + spi->sync_period = 0; + + if ((update_type & AMD_TRANS_USER) != 0) { + targ_info->user.period = spi->sync_period; + targ_info->user.offset = spi->sync_offset; + } + if ((update_type & AMD_TRANS_GOAL) != 0) { + targ_info->goal.period = spi->sync_period; + targ_info->goal.offset = spi->sync_offset; + } +#else intflag = splcam(); targ_info = &amd->tinfo[target_id]; @@ -675,6 +816,7 @@ amd_action(struct cam_sim * psim, union ccb * pccb) targ_info->goal.period = cts->sync_period; targ_info->goal.offset = cts->sync_offset; } +#endif splx(intflag); pccb->ccb_h.status = CAM_REQ_CMP; xpt_done(pccb); @@ -817,12 +959,23 @@ amdsetsync(struct amd_softc *amd, u_int target, u_int clockrate, cam_sim_path(amd->psim), target, CAM_LUN_WILDCARD) == CAM_REQ_CMP) { struct ccb_trans_settings neg; - +#ifdef CAM_NEW_TRAN_CODE + struct ccb_trans_settings_spi *spi = + &neg.xport_specific.spi; +#endif xpt_setup_ccb(&neg.ccb_h, path, /*priority*/1); + memset(&neg, 0, sizeof (neg)); +#ifdef CAM_NEW_TRAN_CODE + spi->sync_period = period; + spi->sync_offset = offset; + spi->valid = CTS_SPI_VALID_SYNC_RATE + | CTS_SPI_VALID_SYNC_OFFSET; +#else neg.sync_period = period; neg.sync_offset = offset; neg.valid = CCB_TRANS_SYNC_RATE_VALID | CCB_TRANS_SYNC_OFFSET_VALID; +#endif xpt_async(AC_TRANSFER_NEG, path, &neg); xpt_free_path(path); } @@ -1474,13 +1627,21 @@ amdhandlemsgreject(struct amd_softc *amd) } else if ((srb != NULL) && (srb->pccb->ccb_h.flags & CAM_TAG_ACTION_VALID) != 0) { struct ccb_trans_settings neg; +#ifdef CAM_NEW_TRAN_CODE + struct ccb_trans_settings_scsi *scsi = &neg.proto_specific.scsi; +#endif printf("amd%d:%d: refuses tagged commands. Performing " "non-tagged I/O\n", amd->unit, amd->cur_target); amdsettags(amd, amd->cur_target, FALSE); + memset(&neg, 0, sizeof (neg)); +#ifdef CAM_NEW_TRAN_CODE + scsi->valid = CTS_SCSI_VALID_TQ; +#else neg.flags = 0; neg.valid = CCB_TRANS_TQ_VALID; +#endif xpt_setup_ccb(&neg.ccb_h, srb->pccb->ccb_h.path, /*priority*/1); xpt_async(AC_TRANSFER_NEG, srb->pccb->ccb_h.path, &neg); diff --git a/sys/dev/amr/amr_cam.c b/sys/dev/amr/amr_cam.c index 251ec6b693ec..7b37ec09bb29 100644 --- a/sys/dev/amr/amr_cam.c +++ b/sys/dev/amr/amr_cam.c @@ -291,6 +291,12 @@ amr_cam_action(struct cam_sim *sim, union ccb *ccb) cpi->unit_number = cam_sim_unit(sim); cpi->bus_id = cam_sim_bus(sim); cpi->base_transfer_speed = 132 * 1024; /* XXX get from controller? */ +#ifdef CAM_NEW_TRAN_CODE + cpi->transport = XPORT_SPI; + cpi->transport_version = 2; + cpi->protocol = PROTO_SCSI; + cpi->protocol_version = SCSI_REV_2; +#endif cpi->ccb_h.status = CAM_REQ_CMP; break; @@ -314,12 +320,35 @@ amr_cam_action(struct cam_sim *sim, union ccb *ccb) case XPT_GET_TRAN_SETTINGS: { - struct ccb_trans_settings *cts; + struct ccb_trans_settings *cts = &(ccb->cts); debug(3, "XPT_GET_TRAN_SETTINGS"); - cts = &(ccb->cts); +#ifdef CAM_NEW_TRAN_CODE + struct ccb_trans_settings_scsi *scsi = &cts->proto_specific.scsi; + struct ccb_trans_settings_spi *spi = &cts->xport_specific.spi; + cts->protocol = PROTO_SCSI; + cts->protocol_version = SCSI_REV_2; + cts->transport = XPORT_SPI; + cts->transport_version = 2; + + if (cts->type == CTS_TYPE_USER_SETTINGS) { + ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; + break; + } + + spi->flags = CTS_SPI_FLAGS_DISC_ENB; + spi->bus_width = MSG_EXT_WDTR_BUS_32_BIT; + spi->sync_period = 6; /* 40MHz how wide is this bus? */ + spi->sync_offset = 31; /* How to extract this from board? */ + + 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 if ((cts->flags & CCB_TRANS_USER_SETTINGS) == 0) { ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; break; @@ -335,6 +364,7 @@ amr_cam_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; break; } diff --git a/sys/dev/arcmsr/arcmsr.c b/sys/dev/arcmsr/arcmsr.c index 317c9224f22e..557791e098a7 100644 --- a/sys/dev/arcmsr/arcmsr.c +++ b/sys/dev/arcmsr/arcmsr.c @@ -1891,6 +1891,12 @@ static VOID arcmsr_action(struct cam_sim * psim,union ccb * pccb) strncpy(cpi->dev_name,cam_sim_name(psim),DEV_IDLEN); cpi->unit_number=cam_sim_unit(psim); 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(pccb); break; } @@ -1958,20 +1964,43 @@ static VOID arcmsr_action(struct cam_sim * psim,union ccb * pccb) } case XPT_GET_TRAN_SETTINGS: { - struct ccb_trans_settings *cts; + struct ccb_trans_settings *cts = &pccb->cts; ULONG s; +#ifdef CAM_NEW_TRAN_CODE + struct ccb_trans_settings_scsi *scsi = + &cts->proto_specific.scsi; + struct ccb_trans_settings_spi *spi = + &cts->xport_specific.spi; + + cts->protocol = PROTO_SCSI; + cts->protocol_version = SCSI_REV_2; + cts->transport = XPORT_SPI; + cts->transport_version = 2; + +#endif #if ARCMSR_DEBUG0 printf("arcmsr_action: XPT_GET_TRAN_SETTINGS\n" ); #endif - cts=&pccb->cts; s=splcam(); +#ifdef CAM_NEW_TRAN_CODE + spi->flags = CTS_SPI_FLAGS_DISC_ENB; + spi->sync_period=3; + spi->sync_offset=32; + spi->bus_width=MSG_EXT_WDTR_BUS_16_BIT; + scsi->flags = CTS_SCSI_FLAGS_TAG_ENB; + spi->valid = CTS_SPI_VALID_SYNC_RATE + | CTS_SPI_VALID_SYNC_OFFSET + | CTS_SPI_VALID_BUS_WIDTH; + scsi->valid = CTS_SCSI_VALID_TQ; +#else cts->flags=(CCB_TRANS_DISC_ENB | CCB_TRANS_TAG_ENB); cts->sync_period=3; cts->sync_offset=32; cts->bus_width=MSG_EXT_WDTR_BUS_16_BIT; cts->valid=CCB_TRANS_SYNC_RATE_VALID | CCB_TRANS_SYNC_OFFSET_VALID | CCB_TRANS_BUS_WIDTH_VALID | CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID; +#endif splx(s); pccb->ccb_h.status=CAM_REQ_CMP; xpt_done(pccb); diff --git a/sys/dev/asr/asr.c b/sys/dev/asr/asr.c index 66b5146b67dd..6a4599a222b5 100644 --- a/sys/dev/asr/asr.c +++ b/sys/dev/asr/asr.c @@ -2791,11 +2791,35 @@ asr_action(struct cam_sim *sim, union ccb *ccb) case XPT_GET_TRAN_SETTINGS: /* Get default/user set transfer settings for the target */ { - struct ccb_trans_settings *cts; - u_int target_mask; + struct ccb_trans_settings *cts = &(ccb->cts); +#ifdef CAM_NEW_TRAN_CODE + struct ccb_trans_settings_scsi *scsi = + &cts->proto_specific.scsi; + struct ccb_trans_settings_spi *spi = + &cts->xport_specific.spi; + + if (cts->type == CTS_TYPE_USER_SETTINGS) { + 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; + spi->bus_width = MSG_EXT_WDTR_BUS_16_BIT; + spi->sync_period = 6; /* 40MHz */ + spi->sync_offset = 15; + 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; - cts = &(ccb->cts); - target_mask = 0x01 << ccb->ccb_h.target_id; + ccb->ccb_h.status = CAM_REQ_CMP; + } else { + ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; + } +#else if ((cts->flags & CCB_TRANS_USER_SETTINGS) != 0) { cts->flags = CCB_TRANS_DISC_ENB|CCB_TRANS_TAG_ENB; cts->bus_width = MSG_EXT_WDTR_BUS_16_BIT; @@ -2811,6 +2835,7 @@ asr_action(struct cam_sim *sim, union ccb *ccb) } else { ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; } +#endif xpt_done(ccb); break; } @@ -2877,6 +2902,12 @@ asr_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; } diff --git a/sys/dev/ata/atapi-cam.c b/sys/dev/ata/atapi-cam.c index 8a2463898c24..e9ef5785b6f7 100644 --- a/sys/dev/ata/atapi-cam.c +++ b/sys/dev/ata/atapi-cam.c @@ -363,6 +363,12 @@ atapi_action(struct cam_sim *sim, union ccb *ccb) cpi->unit_number = cam_sim_unit(sim); cpi->bus_id = cam_sim_bus(sim); cpi->base_transfer_speed = 3300; +#ifdef CAM_NEW_TRAN_CODE + cpi->transport = XPORT_ATA; + cpi->transport_version = 2; + cpi->protocol = PROTO_SCSI; + cpi->protocol_version = SCSI_REV_2; +#endif if (softc->ata_ch && tid != CAM_TARGET_WILDCARD) { mtx_lock(&softc->state_lock); @@ -436,16 +442,25 @@ atapi_action(struct cam_sim *sim, union ccb *ccb) case XPT_GET_TRAN_SETTINGS: { struct ccb_trans_settings *cts = &ccb->cts; - +#ifdef CAM_NEW_TRAN_CODE + cts->protocol = PROTO_SCSI; + cts->protocol_version = SCSI_REV_2; + cts->transport = XPORT_ATA; + cts->transport_version = XPORT_VERSION_UNSPECIFIED; + cts->proto_specific.valid = 0; + cts->xport_specific.valid = 0; + /* nothing more to do */ +#else /* - * XXX The default CAM transport code is very SCSI-specific and + * The default CAM transport code is very SCSI-specific and * doesn't understand IDE speeds very well. Be silent about it * here and let it default to what is set in XPT_PATH_INQ */ - CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_SUBTRACE, ("GET_TRAN_SETTINGS\n")); cts->valid = (CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID); cts->flags &= ~(CCB_TRANS_DISC_ENB | CCB_TRANS_TAG_ENB); +#endif ccb->ccb_h.status = CAM_REQ_CMP; + CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_SUBTRACE, ("GET_TRAN_SETTINGS\n")); xpt_done(ccb); return; } diff --git a/sys/dev/ciss/ciss.c b/sys/dev/ciss/ciss.c index ed61632cb10b..cd90d7e8a7b3 100644 --- a/sys/dev/ciss/ciss.c +++ b/sys/dev/ciss/ciss.c @@ -2648,6 +2648,12 @@ ciss_cam_action(struct cam_sim *sim, union ccb *ccb) cpi->unit_number = cam_sim_unit(sim); cpi->bus_id = cam_sim_bus(sim); cpi->base_transfer_speed = 132 * 1024; /* XXX what to set this to? */ +#ifdef CAM_NEW_TRAN_CODE + cpi->transport = XPORT_SPI; + cpi->transport_version = 2; + cpi->protocol = PROTO_SCSI; + cpi->protocol_version = SCSI_REV_2; +#endif ccb->ccb_h.status = CAM_REQ_CMP; break; } @@ -2656,16 +2662,28 @@ ciss_cam_action(struct cam_sim *sim, union ccb *ccb) { struct ccb_trans_settings *cts = &ccb->cts; int bus, target; +#ifdef CAM_NEW_TRAN_CODE + struct ccb_trans_settings_spi *spi = + &cts->xport_specific.spi; +#endif bus = cam_sim_bus(sim); target = cts->ccb_h.target_id; debug(1, "XPT_GET_TRAN_SETTINGS %d:%d", bus, target); - cts->valid = 0; - /* disconnect always OK */ +#ifdef CAM_NEW_TRAN_CODE + cts->protocol = PROTO_SCSI; + cts->protocol_version = SCSI_REV_2; + cts->transport = XPORT_SPI; + cts->transport_version = 2; + + spi->valid = CTS_SPI_VALID_DISC; + spi->flags = CTS_SPI_FLAGS_DISC_ENB; +#else cts->flags |= CCB_TRANS_DISC_ENB; - cts->valid |= CCB_TRANS_DISC_VALID; + cts->valid = CCB_TRANS_DISC_VALID; +#endif cts->ccb_h.status = CAM_REQ_CMP; break; diff --git a/sys/dev/dpt/dpt_scsi.c b/sys/dev/dpt/dpt_scsi.c index 4d3d9876d02f..2afb3b9e75d2 100644 --- a/sys/dev/dpt/dpt_scsi.c +++ b/sys/dev/dpt/dpt_scsi.c @@ -1004,11 +1004,39 @@ dpt_action(struct cam_sim *sim, union ccb *ccb) case XPT_GET_TRAN_SETTINGS: /* Get default/user set transfer settings for the target */ { - struct ccb_trans_settings *cts; - u_int target_mask; + struct ccb_trans_settings *cts = &ccb->cts; +#ifdef CAM_NEW_TRAN_CODE + struct ccb_trans_settings_scsi *scsi = + &cts->proto_specific.scsi; + struct ccb_trans_settings_spi *spi = + &cts->xport_specific.spi; + + cts->protocol = PROTO_SCSI; + cts->protocol_version = SCSI_REV_2; + cts->transport = XPORT_SPI; + cts->transport_version = 2; - cts = &ccb->cts; - target_mask = 0x01 << ccb->ccb_h.target_id; + if (cts->type == CTS_TYPE_USER_SETTINGS) { + spi->flags = CTS_SPI_FLAGS_DISC_ENB; + spi->bus_width = (dpt->max_id > 7) + ? MSG_EXT_WDTR_BUS_8_BIT + : MSG_EXT_WDTR_BUS_16_BIT; + spi->sync_period = 25; /* 10MHz */ + if (spi->sync_period != 0) + spi->sync_offset = 15; + scsi->flags = CTS_SCSI_FLAGS_TAG_ENB; + + spi->valid = CTS_SPI_VALID_SYNC_RATE + | CTS_SPI_VALID_SYNC_OFFSET + | CTS_SPI_VALID_SYNC_RATE + | CTS_SPI_VALID_BUS_WIDTH + | CTS_SPI_VALID_DISC; + scsi->valid = CTS_SCSI_VALID_TQ; + ccb->ccb_h.status = CAM_REQ_CMP; + } else { + ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; + } +#else if ((cts->flags & CCB_TRANS_USER_SETTINGS) != 0) { cts->flags = CCB_TRANS_DISC_ENB|CCB_TRANS_TAG_ENB; cts->bus_width = (dpt->max_id > 7) @@ -1028,6 +1056,7 @@ dpt_action(struct cam_sim *sim, union ccb *ccb) } else { ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; } +#endif xpt_done(ccb); break; } @@ -1073,6 +1102,12 @@ dpt_action(struct cam_sim *sim, union ccb *ccb) strncpy(cpi->hba_vid, "DPT", HBA_IDLEN); strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); cpi->unit_number = cam_sim_unit(sim); +#ifdef CAM_NEW_TRAN_CODE + cpi->transport = XPORT_SPI; + cpi->transport_version = 2; + cpi->protocol = PROTO_SCSI; + cpi->protocol_version = SCSI_REV_2; +#endif cpi->ccb_h.status = CAM_REQ_CMP; xpt_done(ccb); break; diff --git a/sys/dev/esp/ncr53c9x.c b/sys/dev/esp/ncr53c9x.c index c9ac5e808b8e..79e977895569 100644 --- a/sys/dev/esp/ncr53c9x.c +++ b/sys/dev/esp/ncr53c9x.c @@ -928,6 +928,12 @@ ncr53c9x_action(struct cam_sim *sim, union ccb *ccb) strncpy(cpi->hba_vid, "Sun", HBA_IDLEN); strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); cpi->unit_number = cam_sim_unit(sim); +#ifdef CAM_NEW_TRAN_CODE + cpi->transport = XPORT_SPI; + cpi->transport_version = 2; + cpi->protocol = PROTO_SCSI; + cpi->protocol_version = SCSI_REV_2; +#endif ccb->ccb_h.status = CAM_REQ_CMP; mtx_unlock(&sc->sc_lock); xpt_done(ccb); @@ -936,10 +942,43 @@ ncr53c9x_action(struct cam_sim *sim, union ccb *ccb) case XPT_GET_TRAN_SETTINGS: { struct ccb_trans_settings *cts = &ccb->cts; - struct ncr53c9x_tinfo *ti; - - ti = &sc->sc_tinfo[ccb->ccb_h.target_id]; - + struct ncr53c9x_tinfo *ti = &sc->sc_tinfo[ccb->ccb_h.target_id]; +#ifdef CAM_NEW_TRAN_CODE + struct ccb_trans_settings_scsi *scsi = + &cts->proto_specific.scsi; + struct ccb_trans_settings_spi *spi = + &cts->xport_specific.spi; + + cts->protocol = PROTO_SCSI; + cts->protocol_version = SCSI_REV_2; + cts->transport = XPORT_SPI; + cts->transport_version = 2; + + if (cts->type == CTS_TYPE_CURRENT_SETTINGS) { + spi->sync_period = ti->period; + spi->sync_offset = ti->offset; + spi->bus_width = ti->width; + if ((ti->flags & T_TAG) != 0) { + spi->flags |= CTS_SPI_FLAGS_DISC_ENB; + scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB; + } else { + spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB; + scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB; + } + } else { + spi->sync_period = sc->sc_maxsync; + spi->sync_offset = sc->sc_maxoffset; + spi->bus_width = sc->sc_maxwidth; + spi->flags |= CTS_SPI_FLAGS_DISC_ENB; + scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB; + } + spi->valid = + CTS_SPI_VALID_BUS_WIDTH | + CTS_SPI_VALID_SYNC_RATE | + CTS_SPI_VALID_SYNC_OFFSET | + CTS_SPI_VALID_DISC; + scsi->valid = CTS_SCSI_VALID_TQ; +#else if ((cts->flags & CCB_TRANS_CURRENT_SETTINGS) != 0) { cts->sync_period = ti->period; cts->sync_offset = ti->offset; @@ -961,6 +1000,7 @@ ncr53c9x_action(struct cam_sim *sim, union ccb *ccb) CCB_TRANS_SYNC_OFFSET_VALID | CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID; +#endif ccb->ccb_h.status = CAM_REQ_CMP; mtx_unlock(&sc->sc_lock); xpt_done(ccb); @@ -1038,12 +1078,54 @@ ncr53c9x_action(struct cam_sim *sim, union ccb *ccb) case XPT_SET_TRAN_SETTINGS: { - struct ncr53c9x_tinfo *ti; struct ccb_trans_settings *cts = &ccb->cts; int target = ccb->ccb_h.target_id; + struct ncr53c9x_tinfo *ti = &sc->sc_tinfo[target]; +#ifdef CAM_NEW_TRAN_CODE + struct ccb_trans_settings_scsi *scsi = + &cts->proto_specific.scsi; + struct ccb_trans_settings_spi *spi = + &cts->xport_specific.spi; + + if ((scsi->valid & CTS_SCSI_VALID_TQ) != 0) { + if ((sc->sc_cfflags & (1<<((target & 7) + 16))) == 0 && + (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB)) { + NCR_MISC(("%s: target %d: tagged queuing\n", + device_get_nameunit(sc->sc_dev), target)); + ti->flags |= T_TAG; + } else + ti->flags &= ~T_TAG; + } - ti = &sc->sc_tinfo[target]; + if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) { + if (spi->bus_width != 0) { + NCR_MISC(("%s: target %d: wide negotiation\n", + device_get_nameunit(sc->sc_dev), target)); + if (sc->sc_rev == NCR_VARIANT_FAS366) { + ti->flags |= T_WIDE; + ti->width = 1; + } + } else { + ti->flags &= ~T_WIDE; + ti->width = 0; + } + ti->flags |= T_NEGOTIATE; + } + if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) { + NCR_MISC(("%s: target %d: sync period negotiation\n", + device_get_nameunit(sc->sc_dev), target)); + ti->flags |= T_NEGOTIATE; + ti->period = spi->sync_period; + } + + if ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0) { + NCR_MISC(("%s: target %d: sync offset negotiation\n", + device_get_nameunit(sc->sc_dev), target)); + ti->flags |= T_NEGOTIATE; + ti->offset = spi->sync_offset; + } +#else if ((cts->valid & CCB_TRANS_TQ_VALID) != 0) { if ((sc->sc_cfflags & (1<<((target & 7) + 16))) == 0 && (cts->flags & CCB_TRANS_TAG_ENB)) { @@ -1082,6 +1164,7 @@ ncr53c9x_action(struct cam_sim *sim, union ccb *ccb) ti->flags |= T_NEGOTIATE; ti->offset = cts->sync_offset; } +#endif mtx_unlock(&sc->sc_lock); ccb->ccb_h.status = CAM_REQ_CMP; diff --git a/sys/dev/firewire/sbp.c b/sys/dev/firewire/sbp.c index 51e93c9153ff..d112ffca0dc6 100644 --- a/sys/dev/firewire/sbp.c +++ b/sys/dev/firewire/sbp.c @@ -2527,6 +2527,12 @@ END_DEBUG strncpy(cpi->hba_vid, "SBP", HBA_IDLEN); strncpy(cpi->dev_name, sim->sim_name, DEV_IDLEN); cpi->unit_number = sim->unit_number; +#ifdef CAM_NEW_TRAN_CODE + cpi->transport = XPORT_SPI; /* XX should have a FireWire */ + cpi->transport_version = 2; + cpi->protocol = PROTO_SCSI; + cpi->protocol_version = SCSI_REV_2; +#endif cpi->ccb_h.status = CAM_REQ_CMP; xpt_done(ccb); @@ -2535,15 +2541,30 @@ END_DEBUG case XPT_GET_TRAN_SETTINGS: { struct ccb_trans_settings *cts = &ccb->cts; +#ifdef CAM_NEW_TRAN_CODE + struct ccb_trans_settings_scsi *scsi = + &cts->proto_specific.scsi; + struct ccb_trans_settings_spi *spi = + &cts->xport_specific.spi; + + cts->protocol = PROTO_SCSI; + cts->protocol_version = SCSI_REV_2; + cts->transport = XPORT_SPI; /* should have a FireWire */ + cts->transport_version = 2; + spi->valid = CTS_SPI_VALID_DISC; + spi->flags = CTS_SPI_FLAGS_DISC_ENB; + scsi->valid = CTS_SCSI_VALID_TQ; + scsi->flags = CTS_SCSI_FLAGS_TAG_ENB; +#else + /* Enable disconnect and tagged queuing */ + cts->valid = CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID; + cts->flags = CCB_TRANS_DISC_ENB | CCB_TRANS_TAG_ENB; +#endif SBP_DEBUG(1) printf("%s:%d:%d XPT_GET_TRAN_SETTINGS:.\n", device_get_nameunit(sbp->fd.dev), ccb->ccb_h.target_id, ccb->ccb_h.target_lun); END_DEBUG - /* Enable disconnect and tagged queuing */ - cts->valid = CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID; - cts->flags = CCB_TRANS_DISC_ENB | CCB_TRANS_TAG_ENB; - cts->ccb_h.status = CAM_REQ_CMP; xpt_done(ccb); break; diff --git a/sys/dev/iir/iir.c b/sys/dev/iir/iir.c index ebbaa1098d81..885400d4fb68 100644 --- a/sys/dev/iir/iir.c +++ b/sys/dev/iir/iir.c @@ -1348,11 +1348,34 @@ iir_action( struct cam_sim *sim, union ccb *ccb ) case XPT_GET_TRAN_SETTINGS: /* Get default/user set transfer settings for the target */ { - struct ccb_trans_settings *cts; - u_int target_mask; - - cts = &ccb->cts; - target_mask = 0x01 << target; + struct ccb_trans_settings *cts = &ccb->cts; +#ifdef CAM_NEW_TRAN_CODE + struct ccb_trans_settings_scsi *scsi = &cts->proto_specific.scsi; + struct ccb_trans_settings_spi *spi = &cts->xport_specific.spi; + + cts->protocol = PROTO_SCSI; + cts->protocol_version = SCSI_REV_2; + cts->transport = XPORT_SPI; + cts->transport_version = 2; + + if (cts->type == CTS_TYPE_USER_SETTINGS) { + spi->flags = CTS_SPI_FLAGS_DISC_ENB; + scsi->flags = CTS_SCSI_FLAGS_TAG_ENB; + spi->bus_width = MSG_EXT_WDTR_BUS_16_BIT; + spi->sync_period = 25; /* 10MHz */ + if (spi->sync_period != 0) + spi->sync_offset = 15; + + 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; + ccb->ccb_h.status = CAM_REQ_CMP; + } else { + ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; + } +#else if ((cts->flags & CCB_TRANS_USER_SETTINGS) != 0) { cts->flags = CCB_TRANS_DISC_ENB|CCB_TRANS_TAG_ENB; cts->bus_width = MSG_EXT_WDTR_BUS_16_BIT; @@ -1369,6 +1392,7 @@ iir_action( struct cam_sim *sim, union ccb *ccb ) } else { ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; } +#endif --gdt_stat.io_count_act; xpt_done(ccb); break; @@ -1430,6 +1454,12 @@ iir_action( struct cam_sim *sim, union ccb *ccb ) else strncpy(cpi->hba_vid, "ICP vortex ", HBA_IDLEN); strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); +#ifdef CAM_NEW_TRAN_CODE + cpi->transport = XPORT_SPI; + cpi->transport_version = 2; + cpi->protocol = PROTO_SCSI; + cpi->protocol_version = SCSI_REV_2; +#endif cpi->ccb_h.status = CAM_REQ_CMP; --gdt_stat.io_count_act; xpt_done(ccb); diff --git a/sys/dev/isp/isp_freebsd.c b/sys/dev/isp/isp_freebsd.c index a22596352ee0..bf00206e8981 100644 --- a/sys/dev/isp/isp_freebsd.c +++ b/sys/dev/isp/isp_freebsd.c @@ -2924,7 +2924,6 @@ isp_async(ispsoftc_t *isp, ispasync_t cmd, void *arg) if (flags & DPARM_TQING) { scsi->valid |= CTS_SCSI_VALID_TQ; scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB; - spi->flags |= CTS_SPI_FLAGS_TAG_ENB; } if (flags & DPARM_DISC) { diff --git a/sys/dev/mly/mly.c b/sys/dev/mly/mly.c index f00c147dd446..ac72582fec22 100644 --- a/sys/dev/mly/mly.c +++ b/sys/dev/mly/mly.c @@ -2097,6 +2097,12 @@ mly_cam_action(struct cam_sim *sim, union ccb *ccb) cpi->unit_number = cam_sim_unit(sim); cpi->bus_id = cam_sim_bus(sim); cpi->base_transfer_speed = 132 * 1024; /* XXX what to set this to? */ +#ifdef CAM_NEW_TRAN_CODE + cpi->transport = XPORT_SPI; + cpi->transport_version = 2; + cpi->protocol = PROTO_SCSI; + cpi->protocol_version = SCSI_REV_2; +#endif ccb->ccb_h.status = CAM_REQ_CMP; break; } @@ -2105,13 +2111,71 @@ mly_cam_action(struct cam_sim *sim, union ccb *ccb) { struct ccb_trans_settings *cts = &ccb->cts; int bus, target; +#ifdef CAM_NEW_TRAN_CODE + struct ccb_trans_settings_scsi *scsi = &cts->proto_specific.scsi; + struct ccb_trans_settings_spi *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 = 0; + scsi->valid = 0; + spi->flags = 0; + spi->valid = 0; + + bus = cam_sim_bus(sim); + target = cts->ccb_h.target_id; + debug(2, "XPT_GET_TRAN_SETTINGS %d:%d", bus, target); + /* logical device? */ + if (sc->mly_btl[bus][target].mb_flags & MLY_BTL_LOGICAL) { + /* nothing special for these */ + /* physical device? */ + } else if (sc->mly_btl[bus][target].mb_flags & MLY_BTL_PHYSICAL) { + /* allow CAM to try tagged transactions */ + scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB; + scsi->valid |= CTS_SCSI_VALID_TQ; + + /* convert speed (MHz) to usec */ + if (sc->mly_btl[bus][target].mb_speed == 0) { + spi->sync_period = 1000000 / 5; + } else { + spi->sync_period = 1000000 / sc->mly_btl[bus][target].mb_speed; + } + + /* convert bus width to CAM internal encoding */ + switch (sc->mly_btl[bus][target].mb_width) { + case 32: + spi->bus_width = MSG_EXT_WDTR_BUS_32_BIT; + break; + case 16: + spi->bus_width = MSG_EXT_WDTR_BUS_16_BIT; + break; + case 8: + default: + spi->bus_width = MSG_EXT_WDTR_BUS_8_BIT; + break; + } + spi->valid |= CTS_SPI_VALID_SYNC_RATE | CTS_SPI_VALID_BUS_WIDTH; + + /* not a device, bail out */ + } else { + cts->ccb_h.status = CAM_REQ_CMP_ERR; + break; + } + + /* disconnect always OK */ + spi->flags |= CTS_SPI_FLAGS_DISC_ENB; + spi->valid |= CTS_SPI_VALID_DISC; +#else + cts->valid = 0; bus = cam_sim_bus(sim); target = cts->ccb_h.target_id; /* XXX validate bus/target? */ debug(2, "XPT_GET_TRAN_SETTINGS %d:%d", bus, target); - cts->valid = 0; /* logical device? */ if (sc->mly_btl[bus][target].mb_flags & MLY_BTL_LOGICAL) { @@ -2154,6 +2218,7 @@ mly_cam_action(struct cam_sim *sim, union ccb *ccb) /* disconnect always OK */ cts->flags |= CCB_TRANS_DISC_ENB; cts->valid |= CCB_TRANS_DISC_VALID; +#endif cts->ccb_h.status = CAM_REQ_CMP; break; diff --git a/sys/dev/mpt/mpt_cam.c b/sys/dev/mpt/mpt_cam.c index 8beaa408fa68..d597d8302bdc 100644 --- a/sys/dev/mpt/mpt_cam.c +++ b/sys/dev/mpt/mpt_cam.c @@ -3035,12 +3035,12 @@ mpt_action(struct cam_sim *sim, union ccb *ccb) spi = &cts->xport_specific.spi; if ((spi->valid & CTS_SPI_VALID_DISC) != 0) { - dval |= (spi->flags & CTS_SPI_FLAGS_DISC_ENB) != 0) ? + dval |= ((spi->flags & CTS_SPI_FLAGS_DISC_ENB) != 0) ? DP_DISC_ENABLE : DP_DISC_DISABL; } if ((scsi->valid & CTS_SCSI_VALID_TQ) != 0) { - dval |= (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0) ? + dval |= ((scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0) ? DP_TQING_ENABLE : DP_TQING_DISABL; } @@ -3074,7 +3074,9 @@ mpt_action(struct cam_sim *sim, union ccb *ccb) if (dval & DP_SYNC) { mpt_setsync(mpt, tgt, period, offset); } - + mpt_lprt(mpt, MPT_PRT_NEGOTIATION, + "Set Settings[%d]: 0x%x period 0x%x offset %d\n", tgt, + dval, period , offset); if (mpt_update_spi_config(mpt, tgt)) { mpt_set_ccb_status(ccb, CAM_REQ_CMP_ERR); } else { @@ -3105,7 +3107,7 @@ mpt_action(struct cam_sim *sim, union ccb *ccb) &cts->xport_specific.fc; cts->protocol = PROTO_SCSI; - cts->protocol_version = SCSI_REV_2; + cts->protocol_version = SCSI_REV_SPC; cts->transport = XPORT_FC; cts->transport_version = 0; @@ -3130,7 +3132,7 @@ mpt_action(struct cam_sim *sim, union ccb *ccb) &cts->xport_specific.sas; cts->protocol = PROTO_SCSI; - cts->protocol_version = SCSI_REV_3; + cts->protocol_version = SCSI_REV_SPC2; cts->transport = XPORT_SAS; cts->transport_version = 0; @@ -3195,16 +3197,32 @@ mpt_action(struct cam_sim *sim, union ccb *ccb) cpi->base_transfer_speed = mpt->mpt_fcport_speed * 100000; cpi->hba_inquiry = PI_TAG_ABLE; +#ifdef CAM_NEW_TRAN_CODE + cpi->transport = XPORT_FC; + cpi->transport_version = 0; +#endif } else if (mpt->is_sas) { cpi->hba_misc = PIM_NOBUSRESET; cpi->base_transfer_speed = 300000; cpi->hba_inquiry = PI_TAG_ABLE; +#ifdef CAM_NEW_TRAN_CODE + cpi->transport = XPORT_SAS; + cpi->transport_version = 0; +#endif } else { cpi->hba_misc = PIM_SEQSCAN; cpi->base_transfer_speed = 3300; cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE|PI_WIDE_16; +#ifdef CAM_NEW_TRAN_CODE + cpi->transport = XPORT_SPI; + cpi->transport_version = 2; +#endif } +#ifdef CAM_NEW_TRAN_CODE + cpi->protocol = PROTO_SCSI; + cpi->protocol_version = SCSI_REV_2; +#endif /* * We give our fake RAID passhtru bus a width that is MaxVolumes * wide, restrict it to one lun and have it *not* be a bus diff --git a/sys/dev/trm/trm.c b/sys/dev/trm/trm.c index cc0cba703a94..591e7206f47d 100644 --- a/sys/dev/trm/trm.c +++ b/sys/dev/trm/trm.c @@ -711,6 +711,12 @@ trm_action(struct cam_sim *psim, union ccb *pccb) strncpy(cpi->hba_vid, "Tekram_TRM", HBA_IDLEN); strncpy(cpi->dev_name, cam_sim_name(psim), DEV_IDLEN); cpi->unit_number = cam_sim_unit(psim); +#ifdef CAM_NEW_TRAN_CODE + cpi->transport = XPORT_SPI; + cpi->transport_version = 2; + cpi->protocol = PROTO_SCSI; + cpi->protocol_version = SCSI_REV_2; +#endif cpi->ccb_h.status = CAM_REQ_CMP; xpt_done(pccb); } @@ -829,13 +835,68 @@ trm_action(struct cam_sim *psim, union ccb *pccb) * (GET) default/user transfer settings for the target */ case XPT_GET_TRAN_SETTINGS: { - struct ccb_trans_settings *cts; + struct ccb_trans_settings *cts = &pccb->cts; int intflag; struct trm_transinfo *tinfo; PDCB pDCB; - +#ifdef CAM_NEW_TRAN_CODE + struct ccb_trans_settings_scsi *scsi = + &cts->proto_specific.scsi; + struct ccb_trans_settings_spi *spi = + &cts->xport_specific.spi; + + cts->protocol = PROTO_SCSI; + cts->protocol_version = SCSI_REV_2; + cts->transport = XPORT_SPI; + cts->transport_version = 2; + + TRM_DPRINTF(" XPT_GET_TRAN_SETTINGS \n"); + pDCB = &pACB->DCBarray[target_id][target_lun]; + intflag = splcam(); + /* + * disable interrupt + */ + if (cts->type == CTS_TYPE_CURRENT_SETTINGS) { + /* current transfer settings */ + if (pDCB->tinfo.disc_tag & TRM_CUR_DISCENB) + spi->flags = CTS_SPI_FLAGS_DISC_ENB; + else + spi->flags = 0;/* no tag & disconnect */ + if (pDCB->tinfo.disc_tag & TRM_CUR_TAGENB) + scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB; + tinfo = &pDCB->tinfo.current; + TRM_DPRINTF("CURRENT: cts->flags= %2x \n", + cts->flags); + } else { + /* default(user) transfer settings */ + if (pDCB->tinfo.disc_tag & TRM_USR_DISCENB) + spi->flags = CTS_SPI_FLAGS_DISC_ENB; + else + spi->flags = 0; + if (pDCB->tinfo.disc_tag & TRM_USR_TAGENB) + scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB; + tinfo = &pDCB->tinfo.user; + TRM_DPRINTF("USER: cts->flags= %2x \n", + cts->flags); + } + spi->sync_period = tinfo->period; + spi->sync_offset = tinfo->offset; + spi->bus_width = tinfo->width; + TRM_DPRINTF("pDCB->SyncPeriod: %d \n", + pDCB->SyncPeriod); + TRM_DPRINTF("period: %d \n", tinfo->period); + TRM_DPRINTF("offset: %d \n", tinfo->offset); + TRM_DPRINTF("width: %d \n", tinfo->width); + + splx(intflag); + 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 + TRM_DPRINTF(" XPT_GET_TRAN_SETTINGS \n"); - cts = &pccb->cts; pDCB = &pACB->DCBarray[target_id][target_lun]; intflag = splcam(); /* @@ -879,6 +940,7 @@ trm_action(struct cam_sim *psim, union ccb *pccb) CCB_TRANS_BUS_WIDTH_VALID | CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID; +#endif pccb->ccb_h.status = CAM_REQ_CMP; xpt_done(pccb); } @@ -889,13 +951,98 @@ trm_action(struct cam_sim *psim, union ccb *pccb) * (Set) transfer rate/width negotiation settings */ case XPT_SET_TRAN_SETTINGS: { - struct ccb_trans_settings *cts; + struct ccb_trans_settings *cts = &pccb->cts; u_int update_type; int intflag; PDCB pDCB; +#ifdef CAM_NEW_TRAN_CODE + struct ccb_trans_settings_scsi *scsi = + &cts->proto_specific.scsi; + struct ccb_trans_settings_spi *spi = + &cts->xport_specific.spi; + + TRM_DPRINTF(" XPT_SET_TRAN_SETTINGS \n"); + update_type = 0; + if (cts->type == CTS_TYPE_CURRENT_SETTINGS) + update_type |= TRM_TRANS_GOAL; + if (cts->type == CTS_TYPE_USER_SETTINGS) + update_type |= TRM_TRANS_USER; + intflag = splcam(); + pDCB = &pACB->DCBarray[target_id][target_lun]; + + if ((spi->valid & CTS_SPI_VALID_DISC) != 0) { + /*ccb disc enables */ + if (update_type & TRM_TRANS_GOAL) { + if ((spi->flags & CTS_SPI_FLAGS_DISC_ENB) + != 0) + pDCB->tinfo.disc_tag + |= TRM_CUR_DISCENB; + else + pDCB->tinfo.disc_tag &= + ~TRM_CUR_DISCENB; + } + if (update_type & TRM_TRANS_USER) { + if ((spi->flags & CTS_SPI_FLAGS_DISC_ENB) + != 0) + pDCB->tinfo.disc_tag + |= TRM_USR_DISCENB; + else + pDCB->tinfo.disc_tag &= + ~TRM_USR_DISCENB; + } + } + if ((scsi->valid & CTS_SCSI_VALID_TQ) != 0) { + /* if ccb tag q active */ + if (update_type & TRM_TRANS_GOAL) { + if ((scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) + != 0) + pDCB->tinfo.disc_tag |= + TRM_CUR_TAGENB; + else + pDCB->tinfo.disc_tag &= + ~TRM_CUR_TAGENB; + } + if (update_type & TRM_TRANS_USER) { + if ((scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) + != 0) + pDCB->tinfo.disc_tag |= + TRM_USR_TAGENB; + else + pDCB->tinfo.disc_tag &= + ~TRM_USR_TAGENB; + } + } + /* Minimum sync period factor */ + if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) { + /* if ccb sync active */ + /* TRM-S1040 MinSyncPeriod = 4 clocks/byte */ + if ((spi->sync_period != 0) && + (spi->sync_period < 125)) + spi->sync_period = 125; + /* 1/(125*4) minsync 2 MByte/sec */ + if ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) + != 0) { + if (spi->sync_offset == 0) + spi->sync_period = 0; + /* TRM-S1040 MaxSyncOffset = 15 bytes*/ + if (spi->sync_offset > 15) + spi->sync_offset = 15; + } + } + if ((update_type & TRM_TRANS_USER) != 0) { + pDCB->tinfo.user.period = spi->sync_period; + pDCB->tinfo.user.offset = spi->sync_offset; + pDCB->tinfo.user.width = spi->bus_width; + } + if ((update_type & TRM_TRANS_GOAL) != 0) { + pDCB->tinfo.goal.period = spi->sync_period; + pDCB->tinfo.goal.offset = spi->sync_offset; + pDCB->tinfo.goal.width = spi->bus_width; + } + splx(intflag); +#else TRM_DPRINTF(" XPT_SET_TRAN_SETTINGS \n"); - cts = &pccb->cts; update_type = 0; if ((cts->flags & CCB_TRANS_CURRENT_SETTINGS) != 0) update_type |= TRM_TRANS_GOAL; @@ -975,6 +1122,7 @@ trm_action(struct cam_sim *psim, union ccb *pccb) pDCB->tinfo.goal.width = cts->bus_width; } splx(intflag); +#endif pccb->ccb_h.status = CAM_REQ_CMP; xpt_done(pccb); break; @@ -2282,9 +2430,17 @@ trm_SetXferRate(PACB pACB,PSRB pSRB, PDCB pDCB) */ TRM_DPRINTF("trm_SetXferRate\n"); pccb = pSRB->pccb; + memset(&neg, 0, sizeof (neg)); +#ifdef CAM_NEW_TRAN_CODE + neg.xport_specific.spi.sync_period = pDCB->tinfo.goal.period; + neg.xport_specific.spi.sync_offset = pDCB->tinfo.goal.offset; + neg.xport_specific.spi.valid = + CTS_SPI_VALID_SYNC_RATE | CTS_SPI_VALID_SYNC_OFFSET; +#else neg.sync_period = pDCB->tinfo.goal.period; neg.sync_offset = pDCB->tinfo.goal.offset; neg.valid = CCB_TRANS_SYNC_RATE_VALID | CCB_TRANS_SYNC_OFFSET_VALID; +#endif xpt_setup_ccb(&neg.ccb_h, pccb->ccb_h.path, /* priority */1); xpt_async(AC_TRANSFER_NEG, pccb->ccb_h.path, &neg); if (!(pDCB->IdentifyMsg & 0x07)) { diff --git a/sys/dev/twa/tw_osl_cam.c b/sys/dev/twa/tw_osl_cam.c index 457b539114e7..1dfa60f90d4b 100644 --- a/sys/dev/twa/tw_osl_cam.c +++ b/sys/dev/twa/tw_osl_cam.c @@ -420,10 +420,26 @@ twa_action(struct cam_sim *sim, union ccb *ccb) case XPT_GET_TRAN_SETTINGS: { struct ccb_trans_settings *cts = &ccb->cts; - - tw_osli_dbg_dprintf(3, sc, "XPT_GET_TRAN_SETTINGS"); +#ifdef CAM_NEW_TRAN_CODE + struct ccb_trans_settings_scsi *scsi = + &cts->proto_specific.scsi; + struct ccb_trans_settings_spi *spi = + &cts->xport_specific.spi; + + cts->protocol = PROTO_SCSI; + cts->protocol_version = SCSI_REV_2; + cts->transport = XPORT_SPI; + cts->transport_version = 2; + + spi->valid = CTS_SPI_VALID_DISC; + spi->flags = CTS_SPI_FLAGS_DISC_ENB; + scsi->valid = CTS_SCSI_VALID_TQ; + scsi->flags = CTS_SCSI_FLAGS_TAG_ENB; +#else cts->valid = (CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID); cts->flags &= ~(CCB_TRANS_DISC_ENB | CCB_TRANS_TAG_ENB); +#endif + tw_osli_dbg_dprintf(3, sc, "XPT_GET_TRAN_SETTINGS"); ccb_h->status = CAM_REQ_CMP; xpt_done(ccb); break; @@ -455,6 +471,12 @@ twa_action(struct cam_sim *sim, union ccb *ccb) strncpy(path_inq->sim_vid, "FreeBSD", SIM_IDLEN); strncpy(path_inq->hba_vid, "3ware", HBA_IDLEN); strncpy(path_inq->dev_name, cam_sim_name(sim), DEV_IDLEN); +#ifdef CAM_NEW_TRAN_CODE + path_inq->transport = XPORT_SPI; + path_inq->transport_version = 2; + path_inq->protocol = PROTO_SCSI; + path_inq->protocol_version = SCSI_REV_2; +#endif ccb_h->status = CAM_REQ_CMP; xpt_done(ccb); break; diff --git a/sys/dev/usb/umass.c b/sys/dev/usb/umass.c index 9ad1d5d5917f..216992031f2a 100644 --- a/sys/dev/usb/umass.c +++ b/sys/dev/usb/umass.c @@ -2606,13 +2606,21 @@ umass_cam_action(struct cam_sim *sim, union ccb *ccb) case XPT_GET_TRAN_SETTINGS: { struct ccb_trans_settings *cts = &ccb->cts; +#ifdef CAM_NEW_TRAN_CODE + cts->protocol = PROTO_SCSI; + cts->protocol_version = SCSI_REV_2; + cts->transport = XPORT_USB; + cts->transport_version = XPORT_VERSION_UNSPECIFIED; + cts->xport_specific.valid = 0; +#else DPRINTF(UDMASS_SCSI, ("%s:%d:%d:%d:XPT_GET_TRAN_SETTINGS:.\n", device_get_nameunit(sc->sc_dev), cam_sim_path(sc->umass_sim), ccb->ccb_h.target_id, ccb->ccb_h.target_lun)); cts->valid = 0; cts->flags = 0; /* no disconnection, tagging */ +#endif ccb->ccb_h.status = CAM_REQ_CMP; xpt_done(ccb); diff --git a/sys/pci/ncr.c b/sys/pci/ncr.c index bd8538d3017f..48b2756a51fb 100644 --- a/sys/pci/ncr.c +++ b/sys/pci/ncr.c @@ -4186,13 +4186,100 @@ ncr_action (struct cam_sim *sim, union ccb *ccb) break; case XPT_SET_TRAN_SETTINGS: { - struct ccb_trans_settings *cts; + struct ccb_trans_settings *cts = &ccb->cts; tcb_p tp; u_int update_type; int s; +#ifdef CAM_NEW_TRAN_CODE + struct ccb_trans_settings_scsi *scsi = + &cts->proto_specific.scsi; + struct ccb_trans_settings_spi *spi = + &cts->xport_specific.spi; +#endif - cts = &ccb->cts; update_type = 0; +#ifdef CAM_NEW_TRAN_CODE + if (cts->type == CTS_TYPE_CURRENT_SETTINGS) + update_type |= NCR_TRANS_GOAL; + if (cts->type == CTS_TYPE_USER_SETTINGS) + update_type |= NCR_TRANS_USER; + + s = splcam(); + tp = &np->target[ccb->ccb_h.target_id]; + /* Tag and disc enables */ + if ((spi->valid & CTS_SPI_VALID_DISC) != 0) { + if (update_type & NCR_TRANS_GOAL) { + if ((spi->flags & CTS_SPI_FLAGS_DISC_ENB) != 0) + tp->tinfo.disc_tag |= NCR_CUR_DISCENB; + else + tp->tinfo.disc_tag &= ~NCR_CUR_DISCENB; + } + + if (update_type & NCR_TRANS_USER) { + if ((spi->flags & CTS_SPI_FLAGS_DISC_ENB) != 0) + tp->tinfo.disc_tag |= NCR_USR_DISCENB; + else + tp->tinfo.disc_tag &= ~NCR_USR_DISCENB; + } + + } + + if ((scsi->valid & CTS_SCSI_VALID_TQ) != 0) { + if (update_type & NCR_TRANS_GOAL) { + if ((scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0) + tp->tinfo.disc_tag |= NCR_CUR_TAGENB; + else + tp->tinfo.disc_tag &= ~NCR_CUR_TAGENB; + } + + if (update_type & NCR_TRANS_USER) { + if ((scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0) + tp->tinfo.disc_tag |= NCR_USR_TAGENB; + else + tp->tinfo.disc_tag &= ~NCR_USR_TAGENB; + } + } + + /* Filter bus width and sync negotiation settings */ + if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) { + if (spi->bus_width > np->maxwide) + spi->bus_width = np->maxwide; + } + + if (((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) + || ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0)) { + if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) { + if (spi->sync_period != 0 + && (spi->sync_period < np->minsync)) + spi->sync_period = np->minsync; + } + if ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0) { + if (spi->sync_offset == 0) + spi->sync_period = 0; + if (spi->sync_offset > np->maxoffs) + spi->sync_offset = np->maxoffs; + } + } + if ((update_type & NCR_TRANS_USER) != 0) { + if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) + tp->tinfo.user.period = spi->sync_period; + if ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0) + tp->tinfo.user.offset = spi->sync_offset; + if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) + tp->tinfo.user.width = spi->bus_width; + } + if ((update_type & NCR_TRANS_GOAL) != 0) { + if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) != 0) + tp->tinfo.goal.period = spi->sync_period; + + if ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0) + tp->tinfo.goal.offset = spi->sync_offset; + + if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) + tp->tinfo.goal.width = spi->bus_width; + } + splx(s); +#else if ((cts->flags & CCB_TRANS_CURRENT_SETTINGS) != 0) update_type |= NCR_TRANS_GOAL; if ((cts->flags & CCB_TRANS_USER_SETTINGS) != 0) @@ -4273,6 +4360,7 @@ ncr_action (struct cam_sim *sim, union ccb *ccb) tp->tinfo.goal.width = cts->bus_width; } splx(s); +#endif ccb->ccb_h.status = CAM_REQ_CMP; xpt_done(ccb); break; @@ -4280,14 +4368,57 @@ ncr_action (struct cam_sim *sim, union ccb *ccb) case XPT_GET_TRAN_SETTINGS: /* Get default/user set transfer settings for the target */ { - struct ccb_trans_settings *cts; + struct ccb_trans_settings *cts = &ccb->cts; struct ncr_transinfo *tinfo; - tcb_p tp; + tcb_p tp = &np->target[ccb->ccb_h.target_id]; int s; +#ifdef CAM_NEW_TRAN_CODE + struct ccb_trans_settings_scsi *scsi = + &cts->proto_specific.scsi; + struct ccb_trans_settings_spi *spi = + &cts->xport_specific.spi; + + cts->protocol = PROTO_SCSI; + cts->protocol_version = SCSI_REV_2; + cts->transport = XPORT_SPI; + cts->transport_version = 2; - cts = &ccb->cts; - tp = &np->target[ccb->ccb_h.target_id]; - + s = splcam(); + if (cts->type == CTS_TYPE_CURRENT_SETTINGS) { + tinfo = &tp->tinfo.current; + if (tp->tinfo.disc_tag & NCR_CUR_DISCENB) + spi->flags |= CTS_SPI_FLAGS_DISC_ENB; + else + spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB; + + if (tp->tinfo.disc_tag & NCR_CUR_TAGENB) + scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB; + else + scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB; + } else { + tinfo = &tp->tinfo.user; + if (tp->tinfo.disc_tag & NCR_USR_DISCENB) + spi->flags |= CTS_SPI_FLAGS_DISC_ENB; + else + spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB; + + if (tp->tinfo.disc_tag & NCR_USR_TAGENB) + scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB; + else + scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB; + } + + spi->sync_period = tinfo->period; + spi->sync_offset = tinfo->offset; + spi->bus_width = tinfo->width; + + splx(s); + 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 s = splcam(); if ((cts->flags & CCB_TRANS_CURRENT_SETTINGS) != 0) { tinfo = &tp->tinfo.current; @@ -4324,6 +4455,7 @@ ncr_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); @@ -4372,6 +4504,12 @@ ncr_action (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 CAM_NEW_TRAN_CODE + cpi->transport = XPORT_SPI; + cpi->transport_version = 2; + cpi->protocol = PROTO_SCSI; + cpi->protocol_version = SCSI_REV_2; +#endif cpi->ccb_h.status = CAM_REQ_CMP; xpt_done(ccb); break; @@ -4946,10 +5084,22 @@ ncr_setsync(ncb_p np, nccb_p cp, u_char scntl3, u_char sxfer, u_char period) ** Tell the SCSI layer about the ** new transfer parameters. */ + memset(&neg, 0, sizeof (neg)); +#ifdef CAM_NEW_TRAN_CODE + neg.protocol = PROTO_SCSI; + neg.protocol_version = SCSI_REV_2; + neg.transport = XPORT_SPI; + neg.transport_version = 2; + neg.xport_specific.spi.sync_period = period; + neg.xport_specific.spi.sync_offset = sxfer & 0x1f; + neg.xport_specific.spi.valid = CTS_SPI_VALID_SYNC_RATE + | CTS_SPI_VALID_SYNC_OFFSET; +#else neg.sync_period = period; neg.sync_offset = sxfer & 0x1f; neg.valid = CCB_TRANS_SYNC_RATE_VALID | CCB_TRANS_SYNC_OFFSET_VALID; +#endif xpt_setup_ccb(&neg.ccb_h, ccb->ccb_h.path, /*priority*/1); xpt_async(AC_TRANSFER_NEG, ccb->ccb_h.path, &neg); @@ -5018,6 +5168,20 @@ static void ncr_setwide (ncb_p np, nccb_p cp, u_char wide, u_char ack) tp->tinfo.wval = scntl3; /* Tell the SCSI layer about the new transfer params */ + memset(&neg, 0, sizeof (neg)); +#ifdef CAM_NEW_TRAN_CODE + neg.protocol = PROTO_SCSI; + neg.protocol_version = SCSI_REV_2; + neg.transport = XPORT_SPI; + neg.transport_version = 2; + neg.xport_specific.spi.bus_width = (scntl3 & EWS) ? + MSG_EXT_WDTR_BUS_16_BIT : MSG_EXT_WDTR_BUS_8_BIT; + neg.xport_specific.spi.sync_period = 0; + neg.xport_specific.spi.sync_offset = 0; + neg.xport_specific.spi.valid = CTS_SPI_VALID_SYNC_RATE + | CTS_SPI_VALID_SYNC_OFFSET + | CTS_SPI_VALID_BUS_WIDTH; +#else neg.bus_width = (scntl3 & EWS) ? MSG_EXT_WDTR_BUS_16_BIT : MSG_EXT_WDTR_BUS_8_BIT; neg.sync_period = 0; @@ -5025,8 +5189,8 @@ static void ncr_setwide (ncb_p np, nccb_p cp, u_char wide, u_char ack) 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); +#endif + xpt_setup_ccb(&neg.ccb_h, ccb->ccb_h.path, /*priority*/1); xpt_async(AC_TRANSFER_NEG, ccb->ccb_h.path, &neg); /* -- cgit v1.2.3