From c55984e606afc88e81ab9525ea302647d0e9fab9 Mon Sep 17 00:00:00 2001 From: mjacob Date: Sun, 25 Jun 2006 04:23:26 +0000 Subject: [PATCH] Major Fixes: Don't enable/disable I/O space except for SAS adapters. This fixes a problem with VMware 4.5 Workstation. Fix an egregious bug introduced to target mode so it actually will not panic when you first enable a lun. Minor fixes: Take more infor from port facts and configuration pages. MFC after: 1 week --- sys/dev/mpt/mpt.c | 24 ++++++++++++---------- sys/dev/mpt/mpt.h | 2 ++ sys/dev/mpt/mpt_cam.c | 47 ++++++++++++++++++++++++++----------------- sys/dev/mpt/mpt_pci.c | 4 +++- 4 files changed, 47 insertions(+), 30 deletions(-) diff --git a/sys/dev/mpt/mpt.c b/sys/dev/mpt/mpt.c index 096cec2c932c..2c289d3a76f4 100644 --- a/sys/dev/mpt/mpt.c +++ b/sys/dev/mpt/mpt.c @@ -1484,13 +1484,7 @@ mpt_send_ioc_init(struct mpt_softc *mpt, uint32_t who) memset(&init, 0, sizeof init); init.WhoInit = who; init.Function = MPI_FUNCTION_IOC_INIT; - if (mpt->is_fc) { - init.MaxDevices = 255; - } else if (mpt->is_sas) { - init.MaxDevices = mpt->mpt_max_devices; - } else { - init.MaxDevices = 16; - } + init.MaxDevices = mpt->mpt_max_devices; init.MaxBuses = 1; init.MsgVersion = htole16(MPI_VERSION); @@ -2189,13 +2183,17 @@ mpt_diag_outsl(struct mpt_softc *mpt, uint32_t addr, uint32_t *data_end; data_end = data + (roundup2(len, sizeof(uint32_t)) / 4); - pci_enable_io(mpt->dev, SYS_RES_IOPORT); + if (mpt->is_sas) { + pci_enable_io(mpt->dev, SYS_RES_IOPORT); + } mpt_pio_write(mpt, MPT_OFFSET_DIAG_ADDR, addr); while (data != data_end) { mpt_pio_write(mpt, MPT_OFFSET_DIAG_DATA, *data); data++; } - pci_disable_io(mpt->dev, SYS_RES_IOPORT); + if (mpt->is_sas) { + pci_disable_io(mpt->dev, SYS_RES_IOPORT); + } } static int @@ -2233,7 +2231,9 @@ mpt_download_fw(struct mpt_softc *mpt) ext->ImageSize); } - pci_enable_io(mpt->dev, SYS_RES_IOPORT); + if (mpt->is_sas) { + pci_enable_io(mpt->dev, SYS_RES_IOPORT); + } /* Setup the address to jump to on reset. */ mpt_pio_write(mpt, MPT_OFFSET_DIAG_ADDR, fw_hdr->IopResetRegAddr); mpt_pio_write(mpt, MPT_OFFSET_DIAG_DATA, fw_hdr->IopResetVectorValue); @@ -2248,7 +2248,9 @@ mpt_download_fw(struct mpt_softc *mpt) mpt_pio_write(mpt, MPT_OFFSET_DIAG_ADDR, MPT_DIAG_MEM_CFG_BASE); mpt_pio_write(mpt, MPT_OFFSET_DIAG_DATA, data); - pci_disable_io(mpt->dev, SYS_RES_IOPORT); + if (mpt->is_sas) { + pci_disable_io(mpt->dev, SYS_RES_IOPORT); + } /* * Re-enable the processor and clear the boot halt flag. diff --git a/sys/dev/mpt/mpt.h b/sys/dev/mpt/mpt.h index 21ef5d8bfcc9..bfc134949d43 100644 --- a/sys/dev/mpt/mpt.h +++ b/sys/dev/mpt/mpt.h @@ -551,7 +551,9 @@ struct mpt_softc { #define mpt_disc_enable cfg.spi._disc_enable struct mpi_fc_cfg { CONFIG_PAGE_FC_PORT_0 _port_page0; + uint32_t _port_speed; #define mpt_fcport_page0 cfg.fc._port_page0 +#define mpt_fcport_speed cfg.fc._port_speed } fc; } cfg; diff --git a/sys/dev/mpt/mpt_cam.c b/sys/dev/mpt/mpt_cam.c index 83510b835e6d..b8eb81b3e9a9 100644 --- a/sys/dev/mpt/mpt_cam.c +++ b/sys/dev/mpt/mpt_cam.c @@ -371,7 +371,7 @@ static int mpt_read_config_info_fc(struct mpt_softc *mpt) { char *topology = NULL; - int rv, speed = 0; + int rv; rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_FC_PORT, 0, 0, &mpt->mpt_fcport_page0.Header, FALSE, 5000); @@ -392,12 +392,12 @@ mpt_read_config_info_fc(struct mpt_softc *mpt) return (-1); } - speed = mpt->mpt_fcport_page0.CurrentSpeed; + mpt->mpt_fcport_speed = mpt->mpt_fcport_page0.CurrentSpeed; switch (mpt->mpt_fcport_page0.Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_TYPE_MASK) { case MPI_FCPORTPAGE0_FLAGS_ATTACH_NO_INIT: - speed = 0; + mpt->mpt_fcport_speed = 0; topology = ""; break; case MPI_FCPORTPAGE0_FLAGS_ATTACH_POINT_TO_POINT: @@ -413,7 +413,7 @@ mpt_read_config_info_fc(struct mpt_softc *mpt) topology = "FL-Port"; break; default: - speed = 0; + mpt->mpt_fcport_speed = 0; topology = "?"; break; } @@ -425,7 +425,7 @@ mpt_read_config_info_fc(struct mpt_softc *mpt) mpt->mpt_fcport_page0.WWNN.Low, mpt->mpt_fcport_page0.WWPN.High, mpt->mpt_fcport_page0.WWPN.Low, - speed); + mpt->mpt_fcport_speed); return (0); } @@ -3017,26 +3017,36 @@ mpt_action(struct cam_sim *sim, union ccb *ccb) cpi->version_num = 1; cpi->target_sprt = 0; cpi->hba_eng_cnt = 0; - cpi->max_lun = 7; - cpi->bus_id = cam_sim_bus(sim); - /* XXX Report base speed more accurately for FC/SAS, etc.*/ - if (mpt->is_fc) { - /* XXX SHOULD BE BASED UPON IOC FACTS XXX XXX */ + cpi->max_target = mpt->mpt_max_devices - 1; + /* + * XXX: FC cards report MAX_DEVICES of 512- but we + * XXX: seem to hang when going higher than 255. + */ + if (cpi->max_target > 255) cpi->max_target = 255; + cpi->max_lun = 7; + cpi->initiator_id = mpt->mpt_ini_id; + + cpi->bus_id = cam_sim_bus(sim); + /* + * Actual speed for each device varies. + * + * The base speed is the speed of the underlying connection. + * This is strictly determined for SPI (async, narrow). If + * link is up for Fibre Channel, then speed can be gotten + * from that. + */ + if (mpt->is_fc) { cpi->hba_misc = PIM_NOBUSRESET; - cpi->initiator_id = mpt->mpt_ini_id; - cpi->base_transfer_speed = 100000; + cpi->base_transfer_speed = + mpt->mpt_fcport_speed * 100000; cpi->hba_inquiry = PI_TAG_ABLE; } else if (mpt->is_sas) { - cpi->max_target = 63; /* XXX */ cpi->hba_misc = PIM_NOBUSRESET; - cpi->initiator_id = mpt->mpt_ini_id; cpi->base_transfer_speed = 300000; cpi->hba_inquiry = PI_TAG_ABLE; } else { - cpi->max_target = 15; cpi->hba_misc = PIM_SEQSCAN; - cpi->initiator_id = mpt->mpt_ini_id; cpi->base_transfer_speed = 3300; cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE|PI_WIDE_16; } @@ -3126,13 +3136,14 @@ mpt_action(struct cam_sim *sim, union ccb *ccb) } mpt_set_ccb_status(ccb, CAM_REQ_INPROG); MPTLOCK_2_CAMLOCK(mpt); - break; + return; } case XPT_CONT_TARGET_IO: CAMLOCK_2_MPTLOCK(mpt); mpt_target_start_io(mpt, ccb); MPTLOCK_2_CAMLOCK(mpt); - break; + return; + default: ccb->ccb_h.status = CAM_REQ_INVALID; break; diff --git a/sys/dev/mpt/mpt_pci.c b/sys/dev/mpt/mpt_pci.c index a5978d1f29e5..32f2ebe0b6d8 100644 --- a/sys/dev/mpt/mpt_pci.c +++ b/sys/dev/mpt/mpt_pci.c @@ -524,7 +524,9 @@ mpt_pci_attach(device_t dev) /* * Disable PIO until we need it */ - pci_disable_io(dev, SYS_RES_IOPORT); + if (mpt->is_sas) { + pci_disable_io(dev, SYS_RES_IOPORT); + } /* Initialize the hardware */ if (mpt->disabled == 0) {