aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMatt Jacob <mjacob@FreeBSD.org>2006-05-29 20:30:40 +0000
committerMatt Jacob <mjacob@FreeBSD.org>2006-05-29 20:30:40 +0000
commit800d362b5da7d9c404e6687a97e467066e4eef95 (patch)
tree3cd48e7743456d76cf8ba1f6ad92c3262bc24ea9 /sys
parenta0e4c26aae1bc9f3a98440d787db8dec79bf1a47 (diff)
Notes
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/mpt/mpt_cam.c153
1 files changed, 79 insertions, 74 deletions
diff --git a/sys/dev/mpt/mpt_cam.c b/sys/dev/mpt/mpt_cam.c
index f1a3f4ccb25b..f23dd44fcd63 100644
--- a/sys/dev/mpt/mpt_cam.c
+++ b/sys/dev/mpt/mpt_cam.c
@@ -647,7 +647,7 @@ mpt_read_config_info_spi(struct mpt_softc *mpt)
static int
mpt_set_initial_config_spi(struct mpt_softc *mpt)
{
- int i, pp1val = ((1 << mpt->mpt_ini_id) << 16) | mpt->mpt_ini_id;
+ int i, j, pp1val = ((1 << mpt->mpt_ini_id) << 16) | mpt->mpt_ini_id;
int error;
mpt->mpt_disc_enable = 0xff;
@@ -682,12 +682,17 @@ mpt_set_initial_config_spi(struct mpt_softc *mpt)
* The purpose of this exercise is to get
* all targets back to async/narrow.
*
- * We skip this if the BIOS has already negotiated speeds with targets.
+ * We skip this step if the BIOS has already negotiated
+ * speeds with the targets and does not require us to
+ * do Domain Validation.
*/
i = mpt->mpt_port_page2.PortSettings &
MPI_SCSIPORTPAGE2_PORT_MASK_NEGO_MASTER_SETTINGS;
- if (i == MPI_SCSIPORTPAGE2_PORT_ALL_MASTER_SETTINGS) {
- mpt_lprt(mpt, /* MPT_PRT_INFO */ MPT_PRT_ALWAYS,
+ j = mpt->mpt_port_page2.PortFlags &
+ MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
+ if (i == MPI_SCSIPORTPAGE2_PORT_ALL_MASTER_SETTINGS &&
+ j == MPI_SCSIPORTPAGE2_PORT_FLAGS_OFF_DV) {
+ mpt_lprt(mpt, MPT_PRT_NEGOTIATION,
"honoring BIOS transfer negotiations\n");
return (0);
}
@@ -2782,7 +2787,7 @@ mpt_action(struct cam_sim *sim, union ccb *ccb)
uint8_t dval;
u_int period;
u_int offset;
- int m;
+ int i, j;
cts = &ccb->cts;
if (!IS_CURRENT_SETTINGS(cts)) {
@@ -2790,27 +2795,37 @@ mpt_action(struct cam_sim *sim, union ccb *ccb)
mpt_set_ccb_status(ccb, CAM_REQ_INVALID);
break;
}
+
if (mpt->is_fc || mpt->is_sas) {
mpt_set_ccb_status(ccb, CAM_REQ_CMP);
break;
}
- if (mpt->ioc_page2 && mpt->ioc_page2->MaxPhysDisks != 0 &&
- raid_passthru == 0) {
+ /*
+ * Skip attempting settings on RAID volume disks.
+ * Other devices on the bus get the normal treatment.
+ */
+ if (mpt->phydisk_sim && raid_passthru == 0 &&
+ mpt_is_raid_volume(mpt, tgt) != 0) {
+ mpt_lprt(mpt, MPT_PRT_ALWAYS,
+ "skipping transfer settings for RAID volumes\n");
mpt_set_ccb_status(ccb, CAM_REQ_CMP);
break;
}
- m = mpt->mpt_port_page2.PortSettings;
- if ((m & MPI_SCSIPORTPAGE2_PORT_MASK_NEGO_MASTER_SETTINGS) ==
- MPI_SCSIPORTPAGE2_PORT_ALL_MASTER_SETTINGS) {
-mpt_prt(mpt, "master settings\n");
-if (raid_passthru == 0) {
+ i = mpt->mpt_port_page2.PortSettings &
+ MPI_SCSIPORTPAGE2_PORT_MASK_NEGO_MASTER_SETTINGS;
+ j = mpt->mpt_port_page2.PortFlags &
+ MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
+ if (i == MPI_SCSIPORTPAGE2_PORT_ALL_MASTER_SETTINGS &&
+ j == MPI_SCSIPORTPAGE2_PORT_FLAGS_OFF_DV) {
+ mpt_lprt(mpt, MPT_PRT_ALWAYS,
+ "honoring BIOS transfer negotiations\n");
mpt_set_ccb_status(ccb, CAM_REQ_CMP);
break;
-}
}
+
dval = 0;
period = 0;
offset = 0;
@@ -2846,24 +2861,27 @@ if (raid_passthru == 0) {
spi = &cts->xport_specific.spi;
if ((spi->valid & CTS_SPI_VALID_DISC) != 0) {
- if ((spi->flags & CTS_SPI_FLAGS_DISC_ENB) != 0)
+ if ((spi->flags & CTS_SPI_FLAGS_DISC_ENB) != 0) {
dval |= DP_DISC_ENABLE;
- else
+ } else {
dval |= DP_DISC_DISABL;
+ }
}
if ((scsi->valid & CTS_SCSI_VALID_TQ) != 0) {
- if ((scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0)
+ if ((scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0) {
dval |= DP_TQING_ENABLE;
- else
+ } else {
dval |= DP_TQING_DISABL;
+ }
}
if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) {
- if (spi->bus_width == MSG_EXT_WDTR_BUS_16_BIT)
+ if (spi->bus_width == MSG_EXT_WDTR_BUS_16_BIT) {
dval |= DP_WIDE;
- else
+ } else {
dval |= DP_NARROW;
+ }
}
if ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) &&
@@ -2874,6 +2892,9 @@ if (raid_passthru == 0) {
offset = spi->sync_offset;
}
#endif
+ mpt_lprt(mpt, MPT_PRT_NEGOTIATION,
+ "mpt_action: SET tgt %d flags %x period %x off %x\n",
+ tgt, dval, period, offset);
CAMLOCK_2_MPTLOCK(mpt);
if (dval & DP_DISC_ENABLE) {
mpt->mpt_disc_enable |= (1 << tgt);
@@ -2891,10 +2912,12 @@ if (raid_passthru == 0) {
if (dval & DP_SYNC) {
mpt_setsync(mpt, tgt, period, offset);
}
+ if (mpt_update_spi_config(mpt, tgt)) {
+ MPTLOCK_2_CAMLOCK(mpt);
+ mpt_set_ccb_status(ccb, CAM_REQ_CMP_ERR);
+ break;
+ }
MPTLOCK_2_CAMLOCK(mpt);
- mpt_lprt(mpt, MPT_PRT_DEBUG,
- "SET tgt %d flags %x period %x off %x\n",
- tgt, dval, period, offset);
mpt_set_ccb_status(ccb, CAM_REQ_CMP);
break;
}
@@ -2952,11 +2975,9 @@ if (raid_passthru == 0) {
sas->valid = CTS_SAS_VALID_SPEED;
sas->bitrate = 300000; /* XXX: Default 3Gbps */
#endif
- } else {
- if (mpt_get_spi_settings(mpt, cts) != 0) {
- mpt_set_ccb_status(ccb, CAM_REQ_CMP_ERR);
- break;
- }
+ } else if (mpt_get_spi_settings(mpt, cts) != 0) {
+ mpt_set_ccb_status(ccb, CAM_REQ_CMP_ERR);
+ break;
}
mpt_set_ccb_status(ccb, CAM_REQ_CMP);
break;
@@ -3005,10 +3026,17 @@ if (raid_passthru == 0) {
cpi->base_transfer_speed = 3300;
cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE|PI_WIDE_16;
}
+
+ /*
+ * 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
+ * that can have a SCSI bus reset.
+ */
if (raid_passthru) {
+ cpi->max_target = mpt->ioc_page2->MaxPhysDisks - 1;
+ cpi->initiator_id = cpi->max_target+1;
cpi->max_lun = 0;
cpi->hba_misc = PIM_NOBUSRESET;
- cpi->initiator_id = cpi->max_target+1;
}
if ((mpt->role & MPT_ROLE_INITIATOR) == 0) {
@@ -3109,30 +3137,12 @@ mpt_get_spi_settings(struct mpt_softc *mpt, struct ccb_trans_settings *cts)
uint8_t dval, pval, oval;
int rv;
- /*
- * Check to see if this is an Integrated Raid card.
- *
- * If it is, and we're the RAID bus side, both current
- * and goal settings are synthesized as we only look at
- * or change actual settings for the physical disk side.
- *
- * NB: In the future we can just do this on the blacked out
- * NB: portion that the RAID volume covers- there may be
- * NB: other entities on this bus as well.
- */
-
- if (mpt->phydisk_sim) {
- if (xpt_path_sim(cts->ccb_h.path) != mpt->phydisk_sim) {
- dval = DP_WIDE|DP_DISC|DP_TQING;
- oval = (mpt->mpt_port_page0.Capabilities >> 16);
- pval = (mpt->mpt_port_page0.Capabilities >> 8);
- tgt = cts->ccb_h.target_id;
- goto skip;
+ if (xpt_path_sim(cts->ccb_h.path) == mpt->phydisk_sim) {
+ if (mpt_map_physdisk(mpt, (union ccb *)cts, &tgt)) {
+ return (-1);
}
- }
-
- if (mpt_map_physdisk(mpt, (union ccb *)cts, &tgt) != 0) {
- return (-1);
+ } else {
+ tgt = cts->ccb_h.target_id;
}
/*
@@ -3156,10 +3166,6 @@ mpt_get_spi_settings(struct mpt_softc *mpt, struct ccb_trans_settings *cts)
return (rv);
}
MPTLOCK_2_CAMLOCK(mpt);
-
- mpt_lprt(mpt, MPT_PRT_DEBUG,
- "mpt_get_spi: SPI Tgt %d Page 0: NParms %x Info %x\n",
- tgt, tmp.NegotiatedParameters, tmp.Information);
if (tmp.NegotiatedParameters & MPI_SCSIDEVPAGE0_NP_WIDE) {
dval |= DP_WIDE;
}
@@ -3181,7 +3187,6 @@ mpt_get_spi_settings(struct mpt_softc *mpt, struct ccb_trans_settings *cts)
oval = (mpt->mpt_port_page0.Capabilities >> 16);
pval = (mpt->mpt_port_page0.Capabilities >> 8);
}
- skip:
#ifndef CAM_NEW_TRAN_CODE
cts->flags &= ~(CCB_TRANS_DISC_ENB|CCB_TRANS_TAG_ENB);
if (dval & DP_DISC_ENABLE) {
@@ -3236,9 +3241,9 @@ mpt_get_spi_settings(struct mpt_softc *mpt, struct ccb_trans_settings *cts)
scsi->valid = 0;
}
#endif
- mpt_lprt(mpt, MPT_PRT_DEBUG,
- "mpt_get_spi: tgt %d %s settings flags %x period %x offset %x\n",
- tgt, IS_CURRENT_SETTINGS(cts)? "ACTIVE" : "NVRAM",
+ mpt_lprt(mpt, MPT_PRT_NEGOTIATION,
+ "mpt_get_spi_settings: tgt %d %s settings flags 0x%x period 0x%x "
+ "offset %x\n", tgt, IS_CURRENT_SETTINGS(cts)? "ACTIVE" : "NVRAM ",
dval, pval, oval);
return (0);
}
@@ -3246,27 +3251,27 @@ mpt_get_spi_settings(struct mpt_softc *mpt, struct ccb_trans_settings *cts)
static void
mpt_setwidth(struct mpt_softc *mpt, int tgt, int onoff)
{
- PTR_CONFIG_PAGE_SCSI_DEVICE_1 tmp;
+ PTR_CONFIG_PAGE_SCSI_DEVICE_1 ptr;
- tmp = &mpt->mpt_dev_page1[tgt];
+ ptr = &mpt->mpt_dev_page1[tgt];
if (onoff) {
- tmp->RequestedParameters |= MPI_SCSIDEVPAGE1_RP_WIDE;
+ ptr->RequestedParameters |= MPI_SCSIDEVPAGE1_RP_WIDE;
} else {
- tmp->RequestedParameters &= ~MPI_SCSIDEVPAGE1_RP_WIDE;
+ ptr->RequestedParameters &= ~MPI_SCSIDEVPAGE1_RP_WIDE;
}
}
static void
mpt_setsync(struct mpt_softc *mpt, int tgt, int period, int offset)
{
- PTR_CONFIG_PAGE_SCSI_DEVICE_1 tmp;
+ PTR_CONFIG_PAGE_SCSI_DEVICE_1 ptr;
- tmp = &mpt->mpt_dev_page1[tgt];
- tmp->RequestedParameters &= ~MPI_SCSIDEVPAGE1_RP_MIN_SYNC_PERIOD_MASK;
- tmp->RequestedParameters &= ~MPI_SCSIDEVPAGE1_RP_MAX_SYNC_OFFSET_MASK;
- tmp->RequestedParameters &= ~MPI_SCSIDEVPAGE1_RP_DT;
- tmp->RequestedParameters &= ~MPI_SCSIDEVPAGE1_RP_QAS;
- tmp->RequestedParameters &= ~MPI_SCSIDEVPAGE1_RP_IU;
+ ptr = &mpt->mpt_dev_page1[tgt];
+ ptr->RequestedParameters &= ~MPI_SCSIDEVPAGE1_RP_MIN_SYNC_PERIOD_MASK;
+ ptr->RequestedParameters &= ~MPI_SCSIDEVPAGE1_RP_MAX_SYNC_OFFSET_MASK;
+ ptr->RequestedParameters &= ~MPI_SCSIDEVPAGE1_RP_DT;
+ ptr->RequestedParameters &= ~MPI_SCSIDEVPAGE1_RP_QAS;
+ ptr->RequestedParameters &= ~MPI_SCSIDEVPAGE1_RP_IU;
/*
* XXX: For now, we're ignoring specific settings
@@ -3284,7 +3289,7 @@ mpt_setsync(struct mpt_softc *mpt, int tgt, int period, int offset)
np |= MPI_SCSIDEVPAGE1_RP_DT;
}
np |= (factor << 8) | (offset << 16);
- tmp->RequestedParameters |= np;
+ ptr->RequestedParameters |= np;
}
}
@@ -3308,9 +3313,9 @@ mpt_update_spi_config(struct mpt_softc *mpt, int tgt)
return (-1);
}
mpt->mpt_dev_page1[tgt] = tmp;
- mpt_lprt(mpt, MPT_PRT_DEBUG,
- "mpt_update_spi_config[%d]: Page 1: RParams %x Config %x\n", tgt,
- mpt->mpt_dev_page1[tgt].RequestedParameters,
+ mpt_lprt(mpt, MPT_PRT_NEGOTIATION,
+ "mpt_update_spi_config[%d].page1: RParams 0x%x Config 0x%x\n",
+ tgt, mpt->mpt_dev_page1[tgt].RequestedParameters,
mpt->mpt_dev_page1[tgt].Configuration);
return (0);
}