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
This commit is contained in:
Matt Jacob 2006-10-31 05:53:29 +00:00
parent 9df92bda76
commit fa9ed86506
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=163816
25 changed files with 1610 additions and 90 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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;

View File

@ -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 = &ccb->cts;
target_mask = 0x01 << ccb->ccb_h.target_id;
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;
}
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);
}

View File

@ -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;
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 = &ccb->cts;
target_mask = 0x01 << ccb->ccb_h.target_id;
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;

View File

@ -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;
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 = &ccb->cts;
ti = &aic->tinfo[ccb->ccb_h.target_id];
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);

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
cts = &(ccb->cts);
target_mask = 0x01 << ccb->ccb_h.target_id;
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;
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;
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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;
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;
ti = &sc->sc_tinfo[ccb->ccb_h.target_id];
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;
ti = &sc->sc_tinfo[target];
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;
}
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;

View File

@ -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;

View File

@ -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);

View File

@ -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) {

View File

@ -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;

View File

@ -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

View File

@ -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");
cts = &pccb->cts;
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");
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)) {

View File

@ -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;
#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;
tw_osli_dbg_dprintf(3, sc, "XPT_GET_TRAN_SETTINGS");
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;

View File

@ -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);

View File

@ -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 = &ccb->cts;
tp = &np->target[ccb->ccb_h.target_id];
cts->protocol = PROTO_SCSI;
cts->protocol_version = SCSI_REV_2;
cts->transport = XPORT_SPI;
cts->transport_version = 2;
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);
/*