summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarco Peereboom <marco@cvs.openbsd.org>2010-04-15 20:18:12 +0000
committerMarco Peereboom <marco@cvs.openbsd.org>2010-04-15 20:18:12 +0000
commit15e3b25a33b1be4381bc79cabdef947bb3839be2 (patch)
treeccf12b08ae93830ac4f95bf387c6f3aad2bef1c8
parent00739d88334e2d483eaeb6cd6fd1af1fc485a744 (diff)
- fix bunch of use-after-free bugs found by splint;
- support sharing a phy port by devices (should work fine with sas expanders that share phy port number if such exist); - remove dead timeout_xs stuff; - make mpii_push_reply take a struct mpii_rcb argument instead of an address (like mpi does); - use SLIST instead of TAILQ to manage ccbs (ala mpi); - rototil openfirmware attachment code as it was copied verbatim (but with an error) from mpi and clearly wasn't tested; - increase reset delay to 240ms for stability purposes; - sprinkle some 'default' cases in a bunch of switch statements; - remove several splbio's from the code that runs on boot; - clarify/simplify the code that deals with sc_vd_id_low; - some slight cleanup.
-rw-r--r--sys/dev/pci/mpii.c260
1 files changed, 105 insertions, 155 deletions
diff --git a/sys/dev/pci/mpii.c b/sys/dev/pci/mpii.c
index 8dbb5d14a06..c06f0fee7c2 100644
--- a/sys/dev/pci/mpii.c
+++ b/sys/dev/pci/mpii.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mpii.c,v 1.16 2010/04/10 12:42:17 marco Exp $ */
+/* $OpenBSD: mpii.c,v 1.17 2010/04/15 20:18:11 marco Exp $ */
/*
* Copyright (c) 2010 Mike Belopuhov <mkb@crypt.org.ru>
* Copyright (c) 2009 James Giannoules
@@ -37,10 +37,6 @@
#include <dev/pci/pcivar.h>
#include <dev/pci/pcidevs.h>
-#ifdef __sparc64__
-#include <dev/ofw/openfirm.h>
-#endif
-
#include <scsi/scsi_all.h>
#include <scsi/scsiconf.h>
@@ -264,13 +260,13 @@ struct mpii_fw_tce {
/* Diagnostic Tools values */
#define MPII_IOCSTATUS_DIAGNOSTIC_RELEASED (0x00a0)
-#define MPII_REP_IOCLOGINFO_TYPE (0xf<<28) /* log info type */
+#define MPII_REP_IOCLOGINFO_TYPE (0xf<<28)
#define MPII_REP_IOCLOGINFO_TYPE_NONE (0x0<<28)
#define MPII_REP_IOCLOGINFO_TYPE_SCSI (0x1<<28)
#define MPII_REP_IOCLOGINFO_TYPE_FC (0x2<<28)
#define MPII_REP_IOCLOGINFO_TYPE_SAS (0x3<<28)
#define MPII_REP_IOCLOGINFO_TYPE_ISCSI (0x4<<28)
-#define MPII_REP_IOCLOGINFO_DATA (0x0fffffff) /* log info data */
+#define MPII_REP_IOCLOGINFO_DATA (0x0fffffff)
/* event notification types */
#define MPII_EVENT_NONE (0x00)
@@ -301,9 +297,6 @@ struct mpii_fw_tce {
#define MPII_WHOINIT_HOST_DRIVER (0x04)
#define MPII_WHOINIT_MANUFACTURER (0x05)
-/* page address fields */
-#define MPII_PAGE_ADDRESS_FC_BTID (1<<24) /* Bus Target ID */
-
/* default messages */
struct mpii_msg_request {
@@ -1673,7 +1666,7 @@ struct mpii_evt_ir_cfg_element {
#define MPII_D_CFG (0x0800)
#define MPII_D_MAP (0x1000)
-uint32_t mpii_debug = 0
+u_int32_t mpii_debug = 0
| MPII_D_CMD
| MPII_D_INTR
| MPII_D_MISC
@@ -1767,10 +1760,10 @@ struct mpii_ccb {
void (*ccb_done)(struct mpii_ccb *);
struct mpii_rcb *ccb_rcb;
- TAILQ_ENTRY(mpii_ccb) ccb_link;
+ SLIST_ENTRY(mpii_ccb) ccb_link;
};
-TAILQ_HEAD(mpii_ccb_list, mpii_ccb);
+SLIST_HEAD(mpii_ccb_list, mpii_ccb);
struct mpii_softc {
struct device sc_dev;
@@ -1804,15 +1797,10 @@ struct mpii_softc {
u_int8_t sc_max_volumes;
u_int16_t sc_max_devices;
u_int16_t sc_max_dpm_entries;
- u_int8_t sc_dpm_enabled;
- u_int8_t sc_num_reserved_entries;
- u_int8_t sc_reserve_tid0;
u_int16_t sc_vd_count;
u_int16_t sc_vd_id_low;
- u_int16_t sc_vd_id_hi;
u_int16_t sc_pd_id_start;
u_int8_t sc_num_channels;
- int sc_target;
int sc_ioc_number;
u_int8_t sc_vf_id;
u_int8_t sc_num_ports;
@@ -1887,16 +1875,11 @@ mpii_pci_attach(struct device *parent, struct device *self, void *aux)
int r;
pci_intr_handle_t ih;
const char *intrstr;
-#ifdef __sparc64__
- int node;
-#endif
psc->psc_pc = pa->pa_pc;
psc->psc_tag = pa->pa_tag;
psc->psc_ih = NULL;
sc->sc_dmat = pa->pa_dmat;
- sc->sc_ios = 0;
- sc->sc_target = -1;
/* find the appropriate memory base */
for (r = PCI_MAPREG_START; r < PCI_MAPREG_END; r += sizeof(memtype)) {
@@ -1934,21 +1917,6 @@ mpii_pci_attach(struct device *parent, struct device *self, void *aux)
}
printf(": %s", intrstr);
-#ifdef __sparc64__
- /*
- * Walk up the Open Firmware device tree until we find a
- * "scsi-initiator-id" property.
- */
- node = PCITAG_NODE(pa->pa_tag);
- while (node) {
- if (OF_getprop(node, "scsi-initiator-id",
- &sc->sc_target, sizeof(sc->sc_target)) ==
- sizeof(sc->sc_target))
- break;
- node = OF_parent(node);
- }
-#endif
-
if (mpii_attach(sc) != 0) {
/* error printed by mpii_attach */
goto deintr;
@@ -2020,7 +1988,7 @@ struct mpii_ccb *mpii_get_ccb(struct mpii_softc *);
void mpii_put_ccb(struct mpii_softc *, struct mpii_ccb *);
int mpii_alloc_replies(struct mpii_softc *);
int mpii_alloc_queues(struct mpii_softc *);
-void mpii_push_reply(struct mpii_softc *, u_int32_t);
+void mpii_push_reply(struct mpii_softc *, struct mpii_rcb *);
void mpii_push_replies(struct mpii_softc *);
int mpii_alloc_dev(struct mpii_softc *);
@@ -2035,7 +2003,6 @@ int mpii_reply(struct mpii_softc *, struct mpii_reply_descr *);
void mpii_init_queues(struct mpii_softc *);
-void mpii_timeout_xs(void *);
int mpii_load_xs(struct mpii_ccb *);
u_int32_t mpii_read(struct mpii_softc *, bus_size_t);
@@ -2090,7 +2057,7 @@ int mpii_ioctl_inq(struct mpii_softc *, struct bioc_inq *);
int mpii_ioctl_vol(struct mpii_softc *, struct bioc_vol *);
int mpii_ioctl_disk(struct mpii_softc *, struct bioc_disk *);
int mpii_bio_hs(struct mpii_softc *, struct bioc_disk *, int,
- u_int8_t, int *);
+ int, int *);
int mpii_bio_disk(struct mpii_softc *, struct bioc_disk *,
u_int8_t);
struct mpii_device *mpii_find_vol(struct mpii_softc *, int);
@@ -2216,7 +2183,7 @@ mpii_attach(struct mpii_softc *sc)
/* XXX bail on unsupported porttype? */
if ((sc->sc_porttype == MPII_PORTFACTS_PORTTYPE_SAS_PHYSICAL) ||
- (sc->sc_porttype == MPII_PORTFACTS_PORTTYPE_SAS_VIRTUAL)) {
+ (sc->sc_porttype == MPII_PORTFACTS_PORTTYPE_SAS_VIRTUAL)) {
if (mpii_eventnotify(sc) != 0) {
printf("%s: unable to enable events\n", DEVNAME(sc));
goto free_queues;
@@ -2240,7 +2207,7 @@ mpii_attach(struct mpii_softc *sc)
sc->sc_link.device = &mpii_dev;
sc->sc_link.adapter = &mpii_switch;
sc->sc_link.adapter_softc = sc;
- sc->sc_link.adapter_target = sc->sc_target;
+ sc->sc_link.adapter_target = -1;
sc->sc_link.adapter_buswidth = sc->sc_max_devices;
sc->sc_link.openings = sc->sc_request_depth - 1;
@@ -2343,12 +2310,6 @@ mpii_intr(void *arg)
return (rv);
}
-void
-mpii_timeout_xs(void *arg)
-{
- /* nothing smart could be done here */
-}
-
int
mpii_load_xs(struct mpii_ccb *ccb)
{
@@ -2356,8 +2317,8 @@ mpii_load_xs(struct mpii_ccb *ccb)
struct scsi_xfer *xs = ccb->ccb_xs;
struct mpii_ccb_bundle *mcb = ccb->ccb_cmd;
struct mpii_msg_scsi_io *io = &mcb->mcb_io;
- struct mpii_sge *sge, *nsge = &mcb->mcb_sgl[0];
- struct mpii_sge *ce = NULL, *nce;
+ struct mpii_sge *sge = NULL, *nsge = &mcb->mcb_sgl[0];
+ struct mpii_sge *ce = NULL, *nce = NULL;
u_int64_t ce_dva;
bus_dmamap_t dmap = ccb->ccb_dmamap;
u_int32_t addr, flags;
@@ -2659,8 +2620,8 @@ mpii_reset_hard(struct mpii_softc *sc)
/* reset ioc */
mpii_write(sc, MPII_HOSTDIAG, MPII_HOSTDIAG_RESET_ADAPTER);
- /* 200 milliseconds */
- delay(200000);
+ /* 240 milliseconds */
+ delay(240000);
/* XXX this whole function should be more robust */
@@ -3011,12 +2972,15 @@ mpii_iocinit(struct mpii_softc *sc)
}
void
-mpii_push_reply(struct mpii_softc *sc, u_int32_t rdva)
+mpii_push_reply(struct mpii_softc *sc, struct mpii_rcb *rcb)
{
u_int32_t *rfp;
+ if (rcb == NULL)
+ return;
+
rfp = MPII_DMA_KVA(sc->sc_reply_freeq);
- rfp[sc->sc_reply_free_host_index] = rdva;
+ rfp[sc->sc_reply_free_host_index] = rcb->rcb_reply_dva;
sc->sc_reply_free_host_index = (sc->sc_reply_free_host_index + 1) %
sc->sc_reply_free_qdepth;
@@ -3029,14 +2993,12 @@ mpii_portfacts(struct mpii_softc *sc)
{
struct mpii_msg_portfacts_request *pfq;
struct mpii_msg_portfacts_reply *pfp;
- int rv = 1, s;
struct mpii_ccb *ccb;
+ int rv = 1;
DNPRINTF(MPII_D_MISC, "%s: mpii_portfacts\n", DEVNAME(sc));
- s = splbio();
ccb = mpii_get_ccb(sc);
- splx(s);
if (ccb == NULL) {
DNPRINTF(MPII_D_MISC, "%s: mpii_portfacts mpii_get_ccb fail\n",
DEVNAME(sc));
@@ -3056,7 +3018,8 @@ mpii_portfacts(struct mpii_softc *sc)
pfq->vf_id = 0;
if (mpii_poll(sc, ccb, 50000) != 0) {
- DNPRINTF(MPII_D_MISC, "%s: mpii_portfacts poll\n", DEVNAME(sc));
+ DNPRINTF(MPII_D_MISC, "%s: mpii_portfacts poll\n",
+ DEVNAME(sc));
goto err;
}
@@ -3073,8 +3036,8 @@ mpii_portfacts(struct mpii_softc *sc)
DEVNAME(sc), pfp->function, pfp->msg_length);
DNPRINTF(MPII_D_MISC, "%s: msg_flags: 0x%02x port_number: %d\n",
DEVNAME(sc), pfp->msg_flags, pfp->port_number);
- DNPRINTF(MPII_D_MISC, "%s: vf_id: 0x%02x vp_id: 0x%02x\n", DEVNAME(sc),
- pfp->vf_id, pfp->vp_id);
+ DNPRINTF(MPII_D_MISC, "%s: vf_id: 0x%02x vp_id: 0x%02x\n",
+ DEVNAME(sc), pfp->vf_id, pfp->vp_id);
DNPRINTF(MPII_D_MISC, "%s: ioc_status: 0x%04x\n", DEVNAME(sc),
letoh16(pfp->ioc_status));
DNPRINTF(MPII_D_MISC, "%s: ioc_loginfo: 0x%08x\n", DEVNAME(sc),
@@ -3086,7 +3049,7 @@ mpii_portfacts(struct mpii_softc *sc)
sc->sc_porttype = pfp->port_type;
- mpii_push_reply(sc, ccb->ccb_rcb->rcb_reply_dva);
+ mpii_push_reply(sc, ccb->ccb_rcb);
rv = 0;
err:
mpii_put_ccb(sc, ccb);
@@ -3097,12 +3060,13 @@ err:
void
mpii_eventack(struct mpii_softc *sc, struct mpii_msg_event_reply *enp)
{
- struct mpii_ccb *ccb;
struct mpii_msg_eventack_request *eaq;
+ struct mpii_ccb *ccb;
ccb = mpii_get_ccb(sc);
if (ccb == NULL) {
- DNPRINTF(MPII_D_EVT, "%s: mpii_eventack ccb_get\n", DEVNAME(sc));
+ DNPRINTF(MPII_D_EVT, "%s: mpii_eventack ccb_get\n",
+ DEVNAME(sc));
return;
}
@@ -3125,7 +3089,7 @@ mpii_eventack_done(struct mpii_ccb *ccb)
DNPRINTF(MPII_D_EVT, "%s: event ack done\n", DEVNAME(sc));
- mpii_push_reply(sc, ccb->ccb_rcb->rcb_reply_dva);
+ mpii_push_reply(sc, ccb->ccb_rcb);
mpii_put_ccb(sc, ccb);
}
@@ -3134,14 +3098,11 @@ mpii_portenable(struct mpii_softc *sc)
{
struct mpii_msg_portenable_request *peq;
struct mpii_msg_portenable_repy *pep;
- struct mpii_ccb *ccb;
- int s;
+ struct mpii_ccb *ccb;
DNPRINTF(MPII_D_MISC, "%s: mpii_portenable\n", DEVNAME(sc));
- s = splbio();
ccb = mpii_get_ccb(sc);
- splx(s);
if (ccb == NULL) {
DNPRINTF(MPII_D_MISC, "%s: mpii_portenable ccb_get\n",
DEVNAME(sc));
@@ -3154,8 +3115,9 @@ mpii_portenable(struct mpii_softc *sc)
peq->function = MPII_FUNCTION_PORT_ENABLE;
peq->vf_id = sc->sc_vf_id;
- if (mpii_poll(sc, ccb, 50000) != 0) {
- DNPRINTF(MPII_D_MISC, "%s: mpii_portenable poll\n", DEVNAME(sc));
+ if (mpii_poll(sc, ccb, 80000) != 0) {
+ DNPRINTF(MPII_D_MISC, "%s: mpii_portenable poll\n",
+ DEVNAME(sc));
return (1);
}
@@ -3166,7 +3128,7 @@ mpii_portenable(struct mpii_softc *sc)
}
pep = ccb->ccb_rcb->rcb_reply;
- mpii_push_reply(sc, ccb->ccb_rcb->rcb_reply_dva);
+ mpii_push_reply(sc, ccb->ccb_rcb);
mpii_put_ccb(sc, ccb);
return (0);
@@ -3175,14 +3137,13 @@ mpii_portenable(struct mpii_softc *sc)
int
mpii_cfg_coalescing(struct mpii_softc *sc)
{
- struct mpii_cfg_hdr hdr;
- struct mpii_cfg_ioc_pg1 pg;
- u_int32_t flags;
+ struct mpii_cfg_hdr hdr;
+ struct mpii_cfg_ioc_pg1 pg;
if (mpii_cfg_header(sc, MPII_CONFIG_REQ_PAGE_TYPE_IOC, 1, 0,
&hdr) != 0) {
- DNPRINTF(MPII_D_MISC, "%s: unable to fetch IOC page 1 header\n",
- DEVNAME(sc));
+ DNPRINTF(MPII_D_MISC, "%s: unable to fetch IOC page 1 "
+ "header\n", DEVNAME(sc));
return (1);
}
@@ -3200,8 +3161,7 @@ mpii_cfg_coalescing(struct mpii_softc *sc)
DNPRINTF(MPII_D_MISC, "%s: coalescing_depth: %d pci_slot_num: %d\n",
DEVNAME(sc), pg.coalescing_timeout, pg.pci_slot_num);
- flags = letoh32(pg.flags);
- if (!ISSET(flags, MPII_CFG_IOC_1_REPLY_COALESCING))
+ if (!ISSET(letoh32(pg.flags), MPII_CFG_IOC_1_REPLY_COALESCING))
return (0);
CLR(pg.flags, htole32(MPII_CFG_IOC_1_REPLY_COALESCING));
@@ -3229,13 +3189,10 @@ mpii_cfg_coalescing(struct mpii_softc *sc)
int
mpii_eventnotify(struct mpii_softc *sc)
{
- struct mpii_ccb *ccb;
struct mpii_msg_event_request *enq;
- int s;
+ struct mpii_ccb *ccb;
- s = splbio();
ccb = mpii_get_ccb(sc);
- splx(s);
if (ccb == NULL) {
DNPRINTF(MPII_D_MISC, "%s: mpii_eventnotify ccb_get\n",
DEVNAME(sc));
@@ -3270,9 +3227,7 @@ mpii_eventnotify(struct mpii_softc *sc)
MPII_EVENT_UNMASK(enq, MPII_EVENT_IR_PHYSICAL_DISK);
MPII_EVENT_UNMASK(enq, MPII_EVENT_IR_OPERATION_STATUS);
- s = splbio();
mpii_start(sc, ccb);
- splx(s);
return (0);
}
@@ -3286,7 +3241,7 @@ mpii_eventnotify_done(struct mpii_ccb *ccb)
mpii_event_process(sc, ccb->ccb_rcb->rcb_reply);
- mpii_push_reply(sc, ccb->ccb_rcb->rcb_reply_dva);
+ mpii_push_reply(sc, ccb->ccb_rcb);
mpii_put_ccb(sc, ccb);
}
@@ -3333,7 +3288,7 @@ mpii_event_raid(struct mpii_softc *sc, struct mpii_msg_event_reply *enp)
break;
}
SET(dev->flags, MPII_DF_VOLUME);
- dev->slot = sc->sc_vd_id_low + sc->sc_vd_count;
+ dev->slot = sc->sc_vd_id_low;
dev->dev_handle = letoh16(ce->vol_dev_handle);
if (mpii_insert_dev(sc, dev)) {
free(dev, M_DEVBUF);
@@ -3471,7 +3426,7 @@ mpii_event_process(struct mpii_softc *sc, struct mpii_msg_reply *prm)
MPII_EVENT_SAS_DISC_REASON_CODE_COMPLETED &&
esd->discovery_status != 0)
printf("%s: sas discovery completed with status %#x\n",
- esd->discovery_status);
+ DEVNAME(sc), esd->discovery_status);
}
break;
case MPII_EVENT_SAS_TOPOLOGY_CHANGE_LIST:
@@ -3562,9 +3517,10 @@ mpii_event_defer(void *xsc, void *arg)
if (ISSET(dev->flags, MPII_DF_DETACH)) {
mpii_sas_remove_device(sc, dev->dev_handle);
free(dev, M_DEVBUF);
+ return;
}
- CLR(dev->flags, MPII_DF_ATTACH | MPII_DF_DETACH);
+ CLR(dev->flags, MPII_DF_ATTACH);
}
void
@@ -3592,7 +3548,7 @@ mpii_sas_remove_device(struct mpii_softc *sc, u_int16_t handle)
while (ccb->ccb_state != MPII_CCB_READY)
tsleep(ccb, PRIBIO, "mpiitskmgmt", 0);
if (ccb->ccb_rcb != NULL)
- mpii_push_reply(sc, ccb->ccb_rcb->rcb_reply_dva);
+ mpii_push_reply(sc, ccb->ccb_rcb);
splx(s);
/* reuse a ccb */
@@ -3611,7 +3567,7 @@ mpii_sas_remove_device(struct mpii_softc *sc, u_int16_t handle)
while (ccb->ccb_state != MPII_CCB_READY)
tsleep(ccb, PRIBIO, "mpiisasop", 0);
if (ccb->ccb_rcb != NULL)
- mpii_push_reply(sc, ccb->ccb_rcb->rcb_reply_dva);
+ mpii_push_reply(sc, ccb->ccb_rcb);
splx(s);
}
@@ -3622,13 +3578,14 @@ mpii_get_ioc_pg8(struct mpii_softc *sc)
struct mpii_cfg_ioc_pg8 *page;
size_t pagelen;
u_int16_t flags;
- int rv = 0;
+ int pad = 0, rv = 0;
DNPRINTF(MPII_D_RAID, "%s: mpii_get_ioc_pg8\n", DEVNAME(sc));
- if (mpii_cfg_header(sc, MPII_CONFIG_REQ_PAGE_TYPE_IOC, 8, 0, &hdr) != 0) {
- DNPRINTF(MPII_D_CFG, "%s: mpii_get_ioc_pg8 unable to fetch header"
- "for IOC page 8\n", DEVNAME(sc));
+ if (mpii_cfg_header(sc, MPII_CONFIG_REQ_PAGE_TYPE_IOC, 8, 0,
+ &hdr) != 0) {
+ DNPRINTF(MPII_D_CFG, "%s: mpii_get_ioc_pg8 unable to fetch "
+ "header for IOC page 8\n", DEVNAME(sc));
return (1);
}
@@ -3652,39 +3609,32 @@ mpii_get_ioc_pg8(struct mpii_softc *sc)
page->num_devs_per_enclosure);
DNPRINTF(MPII_D_CFG, "%s: maxpersistententries: 0x%04x "
"maxnumphysicalmappedids: 0x%04x\n", DEVNAME(sc),
- letoh16(page->max_persistent_entries),
+ letoh16(page->max_persistent_entries),
letoh16(page->max_num_physical_mapped_ids));
DNPRINTF(MPII_D_CFG, "%s: flags: 0x%04x\n", DEVNAME(sc),
letoh16(page->flags));
- DNPRINTF(MPII_D_CFG, "%s: irvolumemappingflags: 0x%04x\n",
+ DNPRINTF(MPII_D_CFG, "%s: irvolumemappingflags: 0x%04x\n",
DEVNAME(sc), letoh16(page->ir_volume_mapping_flags));
- sc->sc_pd_id_start = 0;
-
- if (page->flags & MPII_IOC_PG8_FLAGS_RESERVED_TARGETID_0) {
- sc->sc_reserve_tid0 = 1;
- sc->sc_num_reserved_entries = 1;
- sc->sc_pd_id_start = 1;
- } else
- sc->sc_num_reserved_entries = 0;
+ if (page->flags & MPII_IOC_PG8_FLAGS_RESERVED_TARGETID_0)
+ pad = 1;
- flags = page->ir_volume_mapping_flags &&
+ flags = page->ir_volume_mapping_flags &
MPII_IOC_PG8_IRFLAGS_VOLUME_MAPPING_MODE_MASK;
if (ISSET(sc->sc_flags, MPII_F_RAID)) {
if (flags == MPII_IOC_PG8_IRFLAGS_LOW_VOLUME_MAPPING) {
- sc->sc_num_reserved_entries += sc->sc_max_volumes;
- sc->sc_vd_id_low = 0;
- if (page->flags & MPII_IOC_PG8_FLAGS_RESERVED_TARGETID_0)
- sc->sc_vd_id_low = 1;
+ sc->sc_vd_id_low += pad;
+ pad = sc->sc_max_volumes; /* for sc_pd_id_start */
} else
- sc->sc_vd_id_low = sc->sc_max_devices - sc->sc_max_volumes;
- sc->sc_vd_id_hi = sc->sc_vd_id_low + sc->sc_max_volumes - 1;
- sc->sc_pd_id_start = sc->sc_vd_id_hi + 1;
+ sc->sc_vd_id_low = sc->sc_max_devices -
+ sc->sc_max_volumes;
}
+ sc->sc_pd_id_start += pad;
+
DNPRINTF(MPII_D_MAP, "%s: mpii_get_ioc_pg8 mapping: sc_pd_id_start: %d "
- "sc_vd_id_low: %d sc_vd_id_hi: %d\n", DEVNAME(sc),
- sc->sc_pd_id_start, sc->sc_vd_id_low, sc->sc_vd_id_hi);
+ "sc_vd_id_low: %d sc_max_volumes: %d\n", DEVNAME(sc),
+ sc->sc_pd_id_start, sc->sc_vd_id_low, sc->sc_max_volumes);
out:
free(page, M_TEMP);
@@ -3793,7 +3743,7 @@ mpii_req_cfg_header(struct mpii_softc *sc, u_int8_t type, u_int8_t number,
*hdr = cp->config_header;
s = splbio();
- mpii_push_reply(sc, ccb->ccb_rcb->rcb_reply_dva);
+ mpii_push_reply(sc, ccb->ccb_rcb);
mpii_put_ccb(sc, ccb);
splx(s);
@@ -3815,8 +3765,8 @@ mpii_req_cfg_page(struct mpii_softc *sc, u_int32_t address, int flags,
int rv = 0;
int s;
- DNPRINTF(MPII_D_MISC, "%s: mpii_cfg_page address: %d read: %d type: %x\n",
- DEVNAME(sc), address, read, hdr->page_type);
+ DNPRINTF(MPII_D_MISC, "%s: mpii_cfg_page address: %d read: %d "
+ "type: %x\n", DEVNAME(sc), address, read, hdr->page_type);
page_length = ISSET(flags, MPII_PG_EXTENDED) ?
letoh16(ehdr->ext_page_length) : hdr->page_length;
@@ -3829,7 +3779,8 @@ mpii_req_cfg_page(struct mpii_softc *sc, u_int32_t address, int flags,
ccb = mpii_get_ccb(sc);
splx(s);
if (ccb == NULL) {
- DNPRINTF(MPII_D_MISC, "%s: mpii_cfg_page ccb_get\n", DEVNAME(sc));
+ DNPRINTF(MPII_D_MISC, "%s: mpii_cfg_page ccb_get\n",
+ DEVNAME(sc));
return (1);
}
@@ -3917,7 +3868,7 @@ mpii_req_cfg_page(struct mpii_softc *sc, u_int32_t address, int flags,
bcopy(kva, page, len);
s = splbio();
- mpii_push_reply(sc, ccb->ccb_rcb->rcb_reply_dva);
+ mpii_push_reply(sc, ccb->ccb_rcb);
mpii_put_ccb(sc, ccb);
splx(s);
@@ -3959,12 +3910,13 @@ mpii_reply(struct mpii_softc *sc, struct mpii_reply_descr *rdp)
if (smid) {
ccb = &sc->sc_ccbs[smid - 1];
- ccb->ccb_state = MPII_CCB_READY;
+ if (ccb->ccb_state == MPII_CCB_QUEUED)
+ ccb->ccb_state = MPII_CCB_READY;
ccb->ccb_rcb = rcb;
ccb->ccb_done(ccb);
} else {
mpii_event_process(sc, rcb->rcb_reply);
- mpii_push_reply(sc, rcb->rcb_reply_dva);
+ mpii_push_reply(sc, rcb);
}
return (smid);
@@ -4043,14 +3995,16 @@ mpii_alloc_dev(struct mpii_softc *sc)
int
mpii_insert_dev(struct mpii_softc *sc, struct mpii_device *dev)
{
- if (!dev || dev->slot < 0 || dev->slot >= sc->sc_max_devices)
+ int slot = dev->slot; /* initial hint */
+
+ if (!dev || slot < 0)
return (1);
- if (sc->sc_devs[dev->slot]) {
- printf("%s: slot %d is occupied by the dev %p\n", DEVNAME(sc),
- dev->slot, sc->sc_devs[dev->slot]);
+ while (slot < sc->sc_max_devices && sc->sc_devs[slot] != NULL)
+ slot++;
+ if (slot >= sc->sc_max_devices)
return (1);
- }
- sc->sc_devs[dev->slot] = dev;
+ dev->slot = slot;
+ sc->sc_devs[slot] = dev;
return (0);
}
@@ -4088,7 +4042,7 @@ mpii_alloc_ccbs(struct mpii_softc *sc)
u_int8_t *cmd;
int i;
- TAILQ_INIT(&sc->sc_ccb_free);
+ SLIST_INIT(&sc->sc_ccb_free);
sc->sc_ccbs = malloc(sizeof(*ccb) * (sc->sc_request_depth-1),
M_DEVBUF, M_NOWAIT | M_ZERO);
@@ -4162,7 +4116,7 @@ mpii_put_ccb(struct mpii_softc *sc, struct mpii_ccb *ccb)
ccb->ccb_done = NULL;
ccb->ccb_rcb = NULL;
bzero(ccb->ccb_cmd, MPII_REQUEST_SIZE);
- TAILQ_INSERT_TAIL(&sc->sc_ccb_free, ccb, ccb_link);
+ SLIST_INSERT_HEAD(&sc->sc_ccb_free, ccb, ccb_link);
}
struct mpii_ccb *
@@ -4170,16 +4124,12 @@ mpii_get_ccb(struct mpii_softc *sc)
{
struct mpii_ccb *ccb;
- ccb = TAILQ_FIRST(&sc->sc_ccb_free);
- if (ccb == NULL) {
- DNPRINTF(MPII_D_CCB, "%s: mpii_get_ccb == NULL\n", DEVNAME(sc));
- return (NULL);
+ ccb = SLIST_FIRST(&sc->sc_ccb_free);
+ if (ccb != NULL) {
+ SLIST_REMOVE_HEAD(&sc->sc_ccb_free, ccb_link);
+ ccb->ccb_state = MPII_CCB_READY;
}
- TAILQ_REMOVE(&sc->sc_ccb_free, ccb, ccb_link);
-
- ccb->ccb_state = MPII_CCB_READY;
-
DNPRINTF(MPII_D_CCB, "%s: mpii_get_ccb %#x\n", DEVNAME(sc), ccb);
return (ccb);
@@ -4221,7 +4171,7 @@ mpii_push_replies(struct mpii_softc *sc)
rcb->rcb_reply = kva + MPII_REPLY_SIZE * i;
rcb->rcb_reply_dva = (u_int32_t)MPII_DMA_DVA(sc->sc_replies) +
MPII_REPLY_SIZE * i;
- mpii_push_reply(sc, rcb->rcb_reply_dva);
+ mpii_push_reply(sc, rcb);
}
}
@@ -4230,7 +4180,7 @@ mpii_start(struct mpii_softc *sc, struct mpii_ccb *ccb)
{
struct mpii_request_header *rhp;
struct mpii_request_descr descr;
- u_int32_t *rdp = (uint32_t *)&descr;
+ u_int32_t *rdp = (u_int32_t *)&descr;
DNPRINTF(MPII_D_RW, "%s: mpii_start %#x\n", DEVNAME(sc),
ccb->ccb_cmd_dva);
@@ -4513,11 +4463,8 @@ mpii_scsi_cmd(struct scsi_xfer *xs)
return;
}
- timeout_set(&xs->stimeout, mpii_timeout_xs, ccb);
- timeout_add_msec(&xs->stimeout, xs->timeout);
-
- DNPRINTF(MPII_D_CMD, "%s: mpii_scsi_cmd(): opcode: %02x datalen: %d "
- "req_sense_len: %d\n", DEVNAME(sc), xs->cmd->opcode,
+ DNPRINTF(MPII_D_CMD, "%s: mpii_scsi_cmd(): opcode: %02x "
+ "datalen: %d req_sense_len: %d\n", DEVNAME(sc), xs->cmd->opcode,
xs->datalen, xs->req_sense_length);
s = splbio();
@@ -4542,8 +4489,6 @@ mpii_scsi_cmd_done(struct mpii_ccb *ccb)
bus_dmamap_unload(sc->sc_dmat, dmap);
}
- if (!(xs->flags & SCSI_POLL))
- timeout_del(&xs->stimeout);
xs->error = XS_NOERROR;
xs->resid = 0;
@@ -4633,7 +4578,7 @@ mpii_scsi_cmd_done(struct mpii_ccb *ccb)
DNPRINTF(MPII_D_CMD, "%s: xs err: %d status: %#x\n", DEVNAME(sc),
xs->error, xs->status);
- mpii_push_reply(sc, ccb->ccb_rcb->rcb_reply_dva);
+ mpii_push_reply(sc, ccb->ccb_rcb);
mpii_put_ccb(sc, ccb);
scsi_done(xs);
}
@@ -4759,6 +4704,7 @@ mpii_ioctl_vol(struct mpii_softc *sc, struct bioc_vol *bv)
bv->bv_status = BIOC_SVBUILDING;
break;
case MPII_CFG_RAID_VOL_0_STATE_MISSING:
+ default:
bv->bv_status = BIOC_SVINVALID;
break;
}
@@ -4839,10 +4785,11 @@ mpii_ioctl_disk(struct mpii_softc *sc, struct bioc_disk *bd)
}
if (bd->bd_diskid >= vpg->num_phys_disks) {
- u_int8_t hsmap = vpg->hot_spare_pool;
+ int nvdsk = vpg->num_phys_disks;
+ int hsmap = vpg->hot_spare_pool;
free(vpg, M_TEMP);
- return (mpii_bio_hs(sc, bd, vpg->num_phys_disks, hsmap, NULL));
+ return (mpii_bio_hs(sc, bd, nvdsk, hsmap, NULL));
}
pd = (struct mpii_cfg_raid_vol_pg0_physdisk *)(vpg + 1) +
@@ -4855,7 +4802,7 @@ mpii_ioctl_disk(struct mpii_softc *sc, struct bioc_disk *bd)
int
mpii_bio_hs(struct mpii_softc *sc, struct bioc_disk *bd, int nvdsk,
- u_int8_t hsmap, int *hscnt)
+ int hsmap, int *hscnt)
{
struct mpii_cfg_raid_config_pg0 *cpg;
struct mpii_raid_config_element *el;
@@ -4906,9 +4853,10 @@ mpii_bio_hs(struct mpii_softc *sc, struct bioc_disk *bd, int nvdsk,
* number, which is good enough for us.
*/
if (bd != NULL && bd->bd_diskid == nhs + nvdsk) {
+ u_int8_t dn = el->phys_disk_num;
+
free(cpg, M_TEMP);
- return (mpii_bio_disk(sc, bd,
- el->phys_disk_num));
+ return (mpii_bio_disk(sc, bd, dn));
}
nhs++;
}
@@ -4987,6 +4935,7 @@ mpii_bio_disk(struct mpii_softc *sc, struct bioc_disk *bd, u_int8_t dn)
bd->bd_status = BIOC_SDUNUSED;
break;
case MPII_CFG_RAID_PHYDISK_0_STATE_NOTCOMPATIBLE:
+ default:
bd->bd_status = BIOC_SDINVALID;
break;
}
@@ -5051,8 +5000,8 @@ mpii_bio_volstate(struct mpii_softc *sc, struct bioc_vol *bv)
if (mpii_cfg_page(sc, MPII_CFG_RAID_VOL_ADDR_HANDLE | volh,
&hdr, 1, vpg, pagelen) != 0) {
- DNPRINTF(MPII_D_MISC, "%s: unable to fetch raid volume page 0\n",
- DEVNAME(sc));
+ DNPRINTF(MPII_D_MISC, "%s: unable to fetch raid volume "
+ "page 0\n", DEVNAME(sc));
free(vpg, M_TEMP);
return (EINVAL);
}
@@ -5076,6 +5025,7 @@ mpii_bio_volstate(struct mpii_softc *sc, struct bioc_vol *bv)
bv->bv_status = BIOC_SVBUILDING;
break;
case MPII_CFG_RAID_VOL_0_STATE_MISSING:
+ default:
bv->bv_status = BIOC_SVINVALID;
break;
}