Module Name: src
Committed By: bouyer
Date: Mon Dec 3 22:34:36 UTC 2018
Modified Files:
src/sys/dev/pci: mfii.c mpii.c mpiireg.h
Log Message:
Update the mpii(4) driver to the latest OpenBSD version.
This adds support for the SAS3xxx LSI controllers, and this also makes the
driver MP-safe.
adjust mfii.c for changes in mpiireg.h
Tested with a
mpii0: SMC2008-IR, firmware 9.0.0.0 IR, MPI 2.0
To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 src/sys/dev/pci/mfii.c
cvs rdiff -u -r1.14 -r1.15 src/sys/dev/pci/mpii.c
cvs rdiff -u -r1.1 -r1.2 src/sys/dev/pci/mpiireg.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/pci/mfii.c
diff -u src/sys/dev/pci/mfii.c:1.2 src/sys/dev/pci/mfii.c:1.3
--- src/sys/dev/pci/mfii.c:1.2 Sat Nov 24 18:37:16 2018
+++ src/sys/dev/pci/mfii.c Mon Dec 3 22:34:36 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: mfii.c,v 1.2 2018/11/24 18:37:16 bouyer Exp $ */
+/* $NetBSD: mfii.c,v 1.3 2018/12/03 22:34:36 bouyer Exp $ */
/* $OpenBSD: mfii.c,v 1.58 2018/08/14 05:22:21 jmatthew Exp $ */
/*
@@ -19,7 +19,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mfii.c,v 1.2 2018/11/24 18:37:16 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mfii.c,v 1.3 2018/12/03 22:34:36 bouyer Exp $");
#include "bio.h"
@@ -1935,11 +1935,15 @@ mfii_initialise_firmware(struct mfii_sof
iiq->sense_buffer_address_high = htole32(
MFII_DMA_DVA(sc->sc_sense) >> 32);
- iiq->reply_descriptor_post_queue_address = htole64(
- MFII_DMA_DVA(sc->sc_reply_postq));
-
- iiq->system_request_frame_base_address =
- htole64(MFII_DMA_DVA(sc->sc_requests));
+ iiq->reply_descriptor_post_queue_address_lo =
+ htole32(MFII_DMA_DVA(sc->sc_reply_postq));
+ iiq->reply_descriptor_post_queue_address_hi =
+ htole32(MFII_DMA_DVA(sc->sc_reply_postq) >> 32);
+
+ iiq->system_request_frame_base_address_lo =
+ htole32(MFII_DMA_DVA(sc->sc_requests));
+ iiq->system_request_frame_base_address_hi =
+ htole32(MFII_DMA_DVA(sc->sc_requests) >> 32);
iiq->timestamp = htole64(time_uptime);
Index: src/sys/dev/pci/mpii.c
diff -u src/sys/dev/pci/mpii.c:1.14 src/sys/dev/pci/mpii.c:1.15
--- src/sys/dev/pci/mpii.c:1.14 Sun Dec 2 13:22:28 2018
+++ src/sys/dev/pci/mpii.c Mon Dec 3 22:34:36 2018
@@ -1,7 +1,7 @@
-/* $NetBSD: mpii.c,v 1.14 2018/12/02 13:22:28 jdolecek Exp $ */
-/* OpenBSD: mpii.c,v 1.51 2012/04/11 13:29:14 naddy Exp */
+/* $NetBSD: mpii.c,v 1.15 2018/12/03 22:34:36 bouyer Exp $ */
+/* $OpenBSD: mpii.c,v 1.115 2018/08/14 05:22:21 jmatthew Exp $ */
/*
- * Copyright (c) 2010 Mike Belopuhov <[email protected]>
+ * Copyright (c) 2010, 2012 Mike Belopuhov
* Copyright (c) 2009 James Giannoules
* Copyright (c) 2005 - 2010 David Gwynne <[email protected]>
* Copyright (c) 2005 - 2010 Marco Peereboom <[email protected]>
@@ -20,7 +20,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mpii.c,v 1.14 2018/12/02 13:22:28 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mpii.c,v 1.15 2018/12/03 22:34:36 bouyer Exp $");
#include "bio.h"
@@ -44,15 +44,15 @@ __KERNEL_RCSID(0, "$NetBSD: mpii.c,v 1.1
#include <dev/scsipi/scsi_all.h>
#include <dev/scsipi/scsiconf.h>
-#include <dev/pci/mpiireg.h>
-
#if NBIO > 0
#include <dev/biovar.h>
-#include <dev/sysmon/sysmonvar.h>
+#include <dev/sysmon/sysmonvar.h>
#include <sys/envsys.h>
#endif
-/* #define MPII_DEBUG */
+#include <dev/pci/mpiireg.h>
+
+// #define MPII_DEBUG
#ifdef MPII_DEBUG
#define DPRINTF(x...) do { if (mpii_debug) printf(x); } while(0)
#define DNPRINTF(n,x...) do { if (mpii_debug & (n)) printf(x); } while(0)
@@ -69,42 +69,29 @@ __KERNEL_RCSID(0, "$NetBSD: mpii.c,v 1.1
#define MPII_D_EVT (0x0400)
#define MPII_D_CFG (0x0800)
#define MPII_D_MAP (0x1000)
-#if 0
+
u_int32_t mpii_debug = 0
- | MPII_D_CMD
- | MPII_D_INTR
- | MPII_D_MISC
- | MPII_D_DMA
- | MPII_D_IOCTL
- | MPII_D_RW
- | MPII_D_MEM
- | MPII_D_CCB
- | MPII_D_PPR
- | MPII_D_RAID
- | MPII_D_EVT
- | MPII_D_CFG
- | MPII_D_MAP
+// | MPII_D_CMD
+// | MPII_D_INTR
+// | MPII_D_MISC
+// | MPII_D_DMA
+// | MPII_D_IOCTL
+// | MPII_D_RW
+// | MPII_D_MEM
+// | MPII_D_CCB
+// | MPII_D_PPR
+// | MPII_D_RAID
+// | MPII_D_EVT
+// | MPII_D_CFG
+// | MPII_D_MAP
;
-#endif
-u_int32_t mpii_debug = MPII_D_MISC;
#else
#define DPRINTF(x...)
#define DNPRINTF(n,x...)
#endif
-#define MPII_REQUEST_SIZE (512)
-#define MPII_REPLY_SIZE (128)
-#define MPII_REPLY_COUNT PAGE_SIZE / MPII_REPLY_SIZE
-
-/*
- * this is the max number of sge's we can stuff in a request frame:
- * sizeof(scsi_io) + sizeof(sense) + sizeof(sge) * 32 = MPII_REQUEST_SIZE
- */
-#define MPII_MAX_SGL (32)
-
-#define MPII_MAX_REQUEST_CREDIT (128)
-
-#define MPII_MAXFER MAXPHYS /* XXX bogus */
+#define MPII_REQUEST_SIZE (512)
+#define MPII_REQUEST_CREDIT (128)
struct mpii_dmamem {
bus_dmamap_t mdm_map;
@@ -112,23 +99,14 @@ struct mpii_dmamem {
size_t mdm_size;
void *mdm_kva;
};
-#define MPII_DMA_MAP(_mdm) (_mdm)->mdm_map
-#define MPII_DMA_DVA(_mdm) (_mdm)->mdm_map->dm_segs[0].ds_addr
-#define MPII_DMA_KVA(_mdm) (void *)(_mdm)->mdm_kva
-
-struct mpii_ccb_bundle {
- struct mpii_msg_scsi_io mcb_io; /* sgl must follow */
- struct mpii_sge mcb_sgl[MPII_MAX_SGL];
- struct scsi_sense_data mcb_sense;
-} __packed;
+#define MPII_DMA_MAP(_mdm) ((_mdm)->mdm_map)
+#define MPII_DMA_DVA(_mdm) ((uint64_t)(_mdm)->mdm_map->dm_segs[0].ds_addr)
+#define MPII_DMA_KVA(_mdm) ((_mdm)->mdm_kva)
struct mpii_softc;
struct mpii_rcb {
- union {
- struct work rcb_wk; /* has to be first in struct */
- SIMPLEQ_ENTRY(mpii_rcb) rcb_link;
- } u;
+ SIMPLEQ_ENTRY(mpii_rcb) rcb_link;
void *rcb_reply;
u_int32_t rcb_reply_dva;
};
@@ -154,20 +132,19 @@ struct mpii_device {
};
struct mpii_ccb {
- union {
- struct work ccb_wk; /* has to be first in struct */
- SIMPLEQ_ENTRY(mpii_ccb) ccb_link;
- } u;
struct mpii_softc *ccb_sc;
- int ccb_smid;
void * ccb_cookie;
+ kmutex_t ccb_mtx;
+ kcondvar_t ccb_cv;
+
bus_dmamap_t ccb_dmamap;
bus_addr_t ccb_offset;
void *ccb_cmd;
bus_addr_t ccb_cmd_dva;
u_int16_t ccb_dev_handle;
+ u_int16_t ccb_smid;
volatile enum {
MPII_CCB_FREE,
@@ -179,11 +156,7 @@ struct mpii_ccb {
void (*ccb_done)(struct mpii_ccb *);
struct mpii_rcb *ccb_rcb;
-};
-
-struct mpii_ccb_wait {
- kmutex_t mpii_ccbw_mtx;
- kcondvar_t mpii_ccbw_cv;
+ SIMPLEQ_ENTRY(mpii_ccb) ccb_link;
};
SIMPLEQ_HEAD(mpii_ccb_list, mpii_ccb);
@@ -195,15 +168,18 @@ struct mpii_softc {
pcitag_t sc_tag;
void *sc_ih;
-
- int sc_flags;
-#define MPII_F_RAID (1<<1)
+ pci_intr_handle_t *sc_pihp;
struct scsipi_adapter sc_adapt;
struct scsipi_channel sc_chan;
device_t sc_child; /* our scsibus */
+ int sc_flags;
+#define MPII_F_RAID (1<<1)
+#define MPII_F_SAS3 (1<<2)
+
struct mpii_device **sc_devs;
+ kmutex_t sc_devs_mtx;
bus_space_tag_t sc_iot;
bus_space_handle_t sc_ioh;
@@ -213,42 +189,37 @@ struct mpii_softc {
kmutex_t sc_req_mtx;
kmutex_t sc_rep_mtx;
- u_int8_t sc_porttype;
- int sc_request_depth;
- int sc_num_reply_frames;
- int sc_reply_free_qdepth;
- int sc_reply_post_qdepth;
- int sc_maxchdepth;
- int sc_first_sgl_len;
- int sc_chain_len;
- int sc_max_sgl_len;
+ ushort sc_reply_size;
+ ushort sc_request_size;
+
+ ushort sc_max_cmds;
+ ushort sc_num_reply_frames;
+ u_int sc_reply_free_qdepth;
+ u_int sc_reply_post_qdepth;
+
+ ushort sc_chain_sge;
+ ushort sc_max_sgl;
u_int8_t sc_ioc_event_replay;
- u_int16_t sc_max_enclosures;
- u_int16_t sc_max_expanders;
+
+ u_int8_t sc_porttype;
u_int8_t sc_max_volumes;
u_int16_t sc_max_devices;
- u_int16_t sc_max_dpm_entries;
u_int16_t sc_vd_count;
u_int16_t sc_vd_id_low;
u_int16_t sc_pd_id_start;
- u_int8_t sc_num_channels;
int sc_ioc_number;
u_int8_t sc_vf_id;
- u_int8_t sc_num_ports;
struct mpii_ccb *sc_ccbs;
struct mpii_ccb_list sc_ccb_free;
kmutex_t sc_ccb_free_mtx;
kcondvar_t sc_ccb_free_cv;
- kmutex_t sc_ccb_mtx;
- /*
- * this protects the ccb state and list entry
- * between mpii_scsi_cmd and scsidone.
- */
-
+ struct mpii_ccb_list sc_ccb_tmos;
+ kmutex_t sc_ssb_tmomtx;
struct workqueue *sc_ssb_tmowk;
+ struct work sc_ssb_tmowork;
struct mpii_dmamem *sc_requests;
@@ -257,139 +228,149 @@ struct mpii_softc {
struct mpii_dmamem *sc_reply_postq;
struct mpii_reply_descr *sc_reply_postq_kva;
- int sc_reply_post_host_index;
+ u_int sc_reply_post_host_index;
struct mpii_dmamem *sc_reply_freeq;
- int sc_reply_free_host_index;
+ u_int sc_reply_free_host_index;
+ kmutex_t sc_reply_free_mtx;
- struct workqueue *sc_ssb_evt_ackwk;
+ struct mpii_rcb_list sc_evt_sas_queue;
+ kmutex_t sc_evt_sas_mtx;
+ struct workqueue *sc_evt_sas_wq;
+ struct work sc_evt_sas_work;
+
+ struct mpii_rcb_list sc_evt_ack_queue;
+ kmutex_t sc_evt_ack_mtx;
+ struct workqueue *sc_evt_ack_wq;
+ struct work sc_evt_ack_work;
struct sysmon_envsys *sc_sme;
envsys_data_t *sc_sensors;
};
-static int mpii_match(device_t, cfdata_t, void *);
-static void mpii_attach(device_t, device_t, void *);
-static int mpii_detach(device_t, int);
-static void mpii_childdetached(device_t, device_t);
-static int mpii_rescan(device_t, const char *, const int *);
+int mpii_match(device_t, cfdata_t, void *);
+void mpii_attach(device_t, device_t, void *);
+int mpii_detach(device_t, int);
+void mpii_childdetached(device_t, device_t);
+int mpii_rescan(device_t, const char *, const int *);
-static int mpii_intr(void *);
+int mpii_intr(void *);
CFATTACH_DECL3_NEW(mpii, sizeof(struct mpii_softc),
mpii_match, mpii_attach, mpii_detach, NULL, mpii_rescan,
mpii_childdetached, DVF_DETACH_SHUTDOWN);
-#define PREAD(s, r) pci_conf_read((s)->sc_pc, (s)->sc_tag, (r))
-#define PWRITE(s, r, v) pci_conf_write((s)->sc_pc, (s)->sc_tag, (r), (v))
-
-static void mpii_scsipi_request(struct scsipi_channel *,
- scsipi_adapter_req_t, void *);
-static void mpii_scsi_cmd_done(struct mpii_ccb *);
-static void mpii_minphys(struct buf *bp);
-
-static struct mpii_dmamem *mpii_dmamem_alloc(struct mpii_softc *, size_t);
-static void mpii_dmamem_free(struct mpii_softc *, struct mpii_dmamem *);
-static int mpii_alloc_ccbs(struct mpii_softc *);
-static struct mpii_ccb *mpii_get_ccb(struct mpii_softc *, int);
-#define MPII_NOSLEEP 0x0001
-static void mpii_put_ccb(struct mpii_softc *, struct mpii_ccb *);
-static int mpii_alloc_replies(struct mpii_softc *);
-static int mpii_alloc_queues(struct mpii_softc *);
-static void mpii_push_reply(struct mpii_softc *, struct mpii_rcb *);
-static void mpii_push_replies(struct mpii_softc *);
-
-static void mpii_scsi_cmd_tmo(void *);
-static void mpii_scsi_cmd_tmo_handler(struct work *, void *);
-static void mpii_scsi_cmd_tmo_done(struct mpii_ccb *);
-
-static int mpii_alloc_dev(struct mpii_softc *);
-static int mpii_insert_dev(struct mpii_softc *, struct mpii_device *);
-static int mpii_remove_dev(struct mpii_softc *, struct mpii_device *);
-static struct mpii_device *mpii_find_dev(struct mpii_softc *, u_int16_t);
-
-static void mpii_start(struct mpii_softc *, struct mpii_ccb *);
-static int mpii_poll(struct mpii_softc *, struct mpii_ccb *);
-static void mpii_poll_done(struct mpii_ccb *);
-static struct mpii_rcb *mpii_reply(struct mpii_softc *,
- struct mpii_reply_descr *);
-
-static void mpii_wait(struct mpii_softc *, struct mpii_ccb *);
-static void mpii_wait_done(struct mpii_ccb *);
-
-static void mpii_init_queues(struct mpii_softc *);
-
-static int mpii_load_xs(struct mpii_ccb *);
-
-static u_int32_t mpii_read(struct mpii_softc *, bus_size_t);
-static void mpii_write(struct mpii_softc *, bus_size_t, u_int32_t);
-static int mpii_wait_eq(struct mpii_softc *, bus_size_t, u_int32_t,
+void mpii_scsipi_request(struct scsipi_channel *,
+ scsipi_adapter_req_t, void *);
+void mpii_scsi_cmd_done(struct mpii_ccb *);
+
+struct mpii_dmamem *
+ mpii_dmamem_alloc(struct mpii_softc *, size_t);
+void mpii_dmamem_free(struct mpii_softc *,
+ struct mpii_dmamem *);
+int mpii_alloc_ccbs(struct mpii_softc *);
+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 *, struct mpii_rcb *);
+void mpii_push_replies(struct mpii_softc *);
+
+void mpii_scsi_cmd_tmo(void *);
+void mpii_scsi_cmd_tmo_handler(struct work *, void *);
+void mpii_scsi_cmd_tmo_done(struct mpii_ccb *);
+
+int mpii_insert_dev(struct mpii_softc *, struct mpii_device *);
+int mpii_remove_dev(struct mpii_softc *, struct mpii_device *);
+struct mpii_device *
+ mpii_find_dev(struct mpii_softc *, u_int16_t);
+
+void mpii_start(struct mpii_softc *, struct mpii_ccb *);
+int mpii_poll(struct mpii_softc *, struct mpii_ccb *);
+void mpii_poll_done(struct mpii_ccb *);
+struct mpii_rcb *
+ mpii_reply(struct mpii_softc *, struct mpii_reply_descr *);
+
+void mpii_wait(struct mpii_softc *, struct mpii_ccb *);
+void mpii_wait_done(struct mpii_ccb *);
+
+void mpii_init_queues(struct mpii_softc *);
+
+int mpii_load_xs(struct mpii_ccb *);
+int mpii_load_xs_sas3(struct mpii_ccb *);
+
+u_int32_t mpii_read(struct mpii_softc *, bus_size_t);
+void mpii_write(struct mpii_softc *, bus_size_t, u_int32_t);
+int mpii_wait_eq(struct mpii_softc *, bus_size_t, u_int32_t,
u_int32_t);
-static int mpii_wait_ne(struct mpii_softc *, bus_size_t, u_int32_t,
+int mpii_wait_ne(struct mpii_softc *, bus_size_t, u_int32_t,
u_int32_t);
-static int mpii_init(struct mpii_softc *);
-static int mpii_reset_soft(struct mpii_softc *);
-static int mpii_reset_hard(struct mpii_softc *);
+int mpii_init(struct mpii_softc *);
+int mpii_reset_soft(struct mpii_softc *);
+int mpii_reset_hard(struct mpii_softc *);
-static int mpii_handshake_send(struct mpii_softc *, void *, size_t);
-static int mpii_handshake_recv_dword(struct mpii_softc *,
+int mpii_handshake_send(struct mpii_softc *, void *, size_t);
+int mpii_handshake_recv_dword(struct mpii_softc *,
u_int32_t *);
-static int mpii_handshake_recv(struct mpii_softc *, void *, size_t);
+int mpii_handshake_recv(struct mpii_softc *, void *, size_t);
-static void mpii_empty_done(struct mpii_ccb *);
+void mpii_empty_done(struct mpii_ccb *);
-static int mpii_iocinit(struct mpii_softc *);
-static int mpii_iocfacts(struct mpii_softc *);
-static int mpii_portfacts(struct mpii_softc *);
-static int mpii_portenable(struct mpii_softc *);
-static int mpii_cfg_coalescing(struct mpii_softc *);
-
-static int mpii_eventnotify(struct mpii_softc *);
-static void mpii_eventnotify_done(struct mpii_ccb *);
-static void mpii_eventack(struct work *, void *);
-static void mpii_eventack_done(struct mpii_ccb *);
-static void mpii_event_process(struct mpii_softc *, struct mpii_rcb *);
-static void mpii_event_sas(struct mpii_softc *,
+int mpii_iocinit(struct mpii_softc *);
+int mpii_iocfacts(struct mpii_softc *);
+int mpii_portfacts(struct mpii_softc *);
+int mpii_portenable(struct mpii_softc *);
+int mpii_cfg_coalescing(struct mpii_softc *);
+int mpii_board_info(struct mpii_softc *);
+int mpii_target_map(struct mpii_softc *);
+
+int mpii_eventnotify(struct mpii_softc *);
+void mpii_eventnotify_done(struct mpii_ccb *);
+void mpii_eventack(struct work *, void *);
+void mpii_eventack_done(struct mpii_ccb *);
+void mpii_event_process(struct mpii_softc *, struct mpii_rcb *);
+void mpii_event_done(struct mpii_softc *, struct mpii_rcb *);
+void mpii_event_sas(struct mpii_softc *, struct mpii_rcb *);
+void mpii_event_sas_work(struct work *, void *);
+void mpii_event_raid(struct mpii_softc *,
struct mpii_msg_event_reply *);
-static void mpii_event_raid(struct mpii_softc *,
+void mpii_event_discovery(struct mpii_softc *,
struct mpii_msg_event_reply *);
-static void mpii_event_defer(void *, void *);
-static void mpii_sas_remove_device(struct mpii_softc *, u_int16_t);
+void mpii_sas_remove_device(struct mpii_softc *, u_int16_t);
-static int mpii_req_cfg_header(struct mpii_softc *, u_int8_t,
+int mpii_req_cfg_header(struct mpii_softc *, u_int8_t,
u_int8_t, u_int32_t, int, void *);
-static int mpii_req_cfg_page(struct mpii_softc *, u_int32_t, int,
+int mpii_req_cfg_page(struct mpii_softc *, u_int32_t, int,
void *, int, void *, size_t);
-static int mpii_get_ioc_pg8(struct mpii_softc *);
-
#if 0
-static int mpii_ioctl_cache(struct scsi_link *, u_long, struct dk_cache *);
+int mpii_ioctl_cache(struct scsi_link *, u_long, struct dk_cache *);
#endif
-static int mpii_cache_enable(struct mpii_softc *, struct mpii_device *);
#if NBIO > 0
-static int mpii_ioctl(device_t, u_long, void *);
-static int mpii_ioctl_inq(struct mpii_softc *, struct bioc_inq *);
-static int mpii_ioctl_vol(struct mpii_softc *, struct bioc_vol *);
-static int mpii_ioctl_disk(struct mpii_softc *, struct bioc_disk *);
-static int mpii_bio_hs(struct mpii_softc *, struct bioc_disk *, int,
+int mpii_ioctl(device_t, u_long, void *);
+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,
int, int *);
-static int mpii_bio_disk(struct mpii_softc *, struct bioc_disk *,
+int mpii_bio_disk(struct mpii_softc *, struct bioc_disk *,
u_int8_t);
-static struct mpii_device *mpii_find_vol(struct mpii_softc *, int);
-static int mpii_bio_volstate(struct mpii_softc *, struct bioc_vol *);
-static int mpii_create_sensors(struct mpii_softc *);
-static int mpii_destroy_sensors(struct mpii_softc *);
-static void mpii_refresh_sensors(struct sysmon_envsys *, envsys_data_t *);
+struct mpii_device *
+ mpii_find_vol(struct mpii_softc *, int);
+#ifndef SMALL_KERNEL
+ int mpii_bio_volstate(struct mpii_softc *, struct bioc_vol *);
+int mpii_create_sensors(struct mpii_softc *);
+void mpii_refresh_sensors(struct sysmon_envsys *, envsys_data_t *);
+int mpii_destroy_sensors(struct mpii_softc *);
+#endif /* SMALL_KERNEL */
#endif /* NBIO > 0 */
-#define DEVNAME(_s) (device_xname((_s)->sc_dev))
+#define DEVNAME(s) (device_xname((s)->sc_dev))
#define dwordsof(s) (sizeof(s) / sizeof(u_int32_t))
-#define dwordn(p, n) (((u_int32_t *)(p))[(n)])
#define mpii_read_db(s) mpii_read((s), MPII_DOORBELL)
#define mpii_write_db(s, v) mpii_write((s), MPII_DOORBELL, (v))
@@ -398,39 +379,29 @@ static void mpii_refresh_sensors(struct
#define mpii_reply_waiting(s) ((mpii_read_intr((s)) & MPII_INTR_STATUS_REPLY)\
== MPII_INTR_STATUS_REPLY)
-#define mpii_read_reply_free(s) mpii_read((s), \
- MPII_REPLY_FREE_HOST_INDEX)
-#define mpii_write_reply_free(s, v) mpii_write((s), \
- MPII_REPLY_FREE_HOST_INDEX, (v))
-#define mpii_read_reply_post(s) mpii_read((s), \
- MPII_REPLY_POST_HOST_INDEX)
-#define mpii_write_reply_post(s, v) mpii_write((s), \
- MPII_REPLY_POST_HOST_INDEX, (v))
+#define mpii_write_reply_free(s, v) \
+ bus_space_write_4((s)->sc_iot, (s)->sc_ioh, \
+ MPII_REPLY_FREE_HOST_INDEX, (v))
+#define mpii_write_reply_post(s, v) \
+ bus_space_write_4((s)->sc_iot, (s)->sc_ioh, \
+ MPII_REPLY_POST_HOST_INDEX, (v))
#define mpii_wait_db_int(s) mpii_wait_ne((s), MPII_INTR_STATUS, \
MPII_INTR_STATUS_IOC2SYSDB, 0)
#define mpii_wait_db_ack(s) mpii_wait_eq((s), MPII_INTR_STATUS, \
MPII_INTR_STATUS_SYS2IOCDB, 0)
+static inline void
+mpii_dvatosge(struct mpii_sge *sge, u_int64_t dva)
+{
+ sge->sg_addr_lo = htole32(dva);
+ sge->sg_addr_hi = htole32(dva >> 32);
+}
+
#define MPII_PG_EXTENDED (1<<0)
#define MPII_PG_POLL (1<<1)
#define MPII_PG_FMT "\020" "\002POLL" "\001EXTENDED"
-#define mpii_cfg_header(_s, _t, _n, _a, _h) \
- mpii_req_cfg_header((_s), (_t), (_n), (_a), \
- MPII_PG_POLL, (_h))
-#define mpii_ecfg_header(_s, _t, _n, _a, _h) \
- mpii_req_cfg_header((_s), (_t), (_n), (_a), \
- MPII_PG_POLL|MPII_PG_EXTENDED, (_h))
-
-#define mpii_cfg_page(_s, _a, _h, _r, _p, _l) \
- mpii_req_cfg_page((_s), (_a), MPII_PG_POLL, \
- (_h), (_r), (_p), (_l))
-#define mpii_ecfg_page(_s, _a, _h, _r, _p, _l) \
- mpii_req_cfg_page((_s), (_a), MPII_PG_POLL|MPII_PG_EXTENDED, \
- (_h), (_r), (_p), (_l))
-
-
static const struct mpii_pci_product {
pci_vendor_id_t mpii_vendor;
pci_product_id_t mpii_product;
@@ -451,37 +422,46 @@ static const struct mpii_pci_product {
{ PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_SAS2308_1 },
{ PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_SAS2308_2 },
{ PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_SAS2308_3 },
- { 0, 0 }
+ { PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_SAS3004 },
+ { PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_SAS3008 },
+ { PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_SAS3108_1 },
+ { PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_SAS3108_2 },
+ { PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_SAS3108_3 },
+ { PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_SAS3108_4 },
+ { PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_SAS3408 },
+ { PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_SAS3416 },
+ { PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_SAS3508 },
+ { PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_SAS3508_1 },
+ { PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_SAS3516 },
+ { PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_SAS3516_1 }
};
-static int
+int
mpii_match(device_t parent, cfdata_t match, void *aux)
{
struct pci_attach_args *pa = aux;
const struct mpii_pci_product *mpii;
- for (mpii = mpii_devices; mpii->mpii_vendor != 0; mpii++) {
- if (PCI_VENDOR(pa->pa_id) == mpii->mpii_vendor &&
- PCI_PRODUCT(pa->pa_id) == mpii->mpii_product)
- return (1);
+ for (mpii = mpii_devices; mpii->mpii_vendor != 0; mpii++) {
+ if (PCI_VENDOR(pa->pa_id) == mpii->mpii_vendor &&
+ PCI_PRODUCT(pa->pa_id) == mpii->mpii_product)
+ return (1);
}
return (0);
}
-static void
+void
mpii_attach(device_t parent, device_t self, void *aux)
{
struct mpii_softc *sc = device_private(self);
struct pci_attach_args *pa = aux;
pcireg_t memtype;
int r;
- pci_intr_handle_t ih;
- const char *intrstr;
struct mpii_ccb *ccb;
struct scsipi_adapter *adapt = &sc->sc_adapt;
struct scsipi_channel *chan = &sc->sc_chan;
- char wkname[15];
char intrbuf[PCI_INTRSTR_LEN];
+ const char *intrstr;
pci_aprint_devinfo(pa, NULL);
@@ -489,26 +469,9 @@ mpii_attach(device_t parent, device_t se
sc->sc_tag = pa->pa_tag;
sc->sc_dmat = pa->pa_dmat;
sc->sc_dev = self;
-
+
mutex_init(&sc->sc_req_mtx, MUTEX_DEFAULT, IPL_BIO);
mutex_init(&sc->sc_rep_mtx, MUTEX_DEFAULT, IPL_BIO);
- mutex_init(&sc->sc_ccb_free_mtx, MUTEX_DEFAULT, IPL_BIO);
- cv_init(&sc->sc_ccb_free_cv, "mpii_ccbs");
- mutex_init(&sc->sc_ccb_mtx, MUTEX_DEFAULT, IPL_BIO);
-
- snprintf(wkname, sizeof(wkname), "%s_tmo", DEVNAME(sc));
- if (workqueue_create(&sc->sc_ssb_tmowk, wkname,
- mpii_scsi_cmd_tmo_handler, sc, PRI_NONE, IPL_BIO, WQ_MPSAFE) != 0) {
- aprint_error_dev(self, "can't create %s workqueue\n", wkname);
- return;
- }
-
- snprintf(wkname, sizeof(wkname), "%s_evt", DEVNAME(sc));
- if (workqueue_create(&sc->sc_ssb_evt_ackwk, wkname,
- mpii_eventack, sc, PRI_NONE, IPL_BIO, WQ_MPSAFE) != 0) {
- aprint_error_dev(self, "can't create %s workqueue\n", wkname);
- return;
- }
/* find the appropriate memory base */
for (r = PCI_MAPREG_START; r < PCI_MAPREG_END; r += sizeof(memtype)) {
@@ -530,8 +493,9 @@ mpii_attach(device_t parent, device_t se
}
/* disable the expansion rom */
- PWRITE(sc, PCI_MAPREG_ROM,
- PREAD(sc, PCI_MAPREG_ROM) & ~PCI_MAPREG_ROM_ENABLE);
+ pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_MAPREG_ROM,
+ pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_MAPREG_ROM) &
+ ~PCI_MAPREG_ROM_ENABLE);
/* disable interrupts */
mpii_write(sc, MPII_INTR_MASK,
@@ -539,19 +503,32 @@ mpii_attach(device_t parent, device_t se
MPII_INTR_MASK_DOORBELL);
/* hook up the interrupt */
- if (pci_intr_map(pa, &ih) != 0) {
+ if (pci_intr_alloc(pa, &sc->sc_pihp, NULL, 0)) {
aprint_error_dev(self, "unable to map interrupt\n");
goto unmap;
}
- intrstr = pci_intr_string(pa->pa_pc, ih, intrbuf, sizeof(intrbuf));
+ intrstr = pci_intr_string(pa->pa_pc, sc->sc_pihp[0],
+ intrbuf, sizeof(intrbuf));
+ pci_intr_setattr(pa->pa_pc, &sc->sc_pihp[0], PCI_INTR_MPSAFE, true);
+ sc->sc_ih = pci_intr_establish_xname(pa->pa_pc, sc->sc_pihp[0], IPL_BIO,
+ mpii_intr, sc, device_xname(self));
+ if (sc->sc_ih == NULL) {
+ aprint_error_dev(self, "couldn't establish interrupt");
+ if (intrstr != NULL)
+ aprint_error(" at %s", intrstr);
+ aprint_error("\n");
+ return;
+ }
+ aprint_normal_dev(self, "interrupting at %s\n", intrstr);
+ aprint_naive("\n");
- if (mpii_init(sc) != 0) {
- aprint_error_dev(self, "unable to initialize ioc\n");
+ if (mpii_iocfacts(sc) != 0) {
+ aprint_error_dev(self, "unable to get iocfacts\n");
goto unmap;
}
- if (mpii_iocfacts(sc) != 0) {
- aprint_error_dev(self, "unable to get iocfacts\n");
+ if (mpii_init(sc) != 0) {
+ aprint_error_dev(self, "unable to initialize ioc\n");
goto unmap;
}
@@ -586,13 +563,18 @@ mpii_attach(device_t parent, device_t se
mpii_push_replies(sc);
mpii_init_queues(sc);
+ if (mpii_board_info(sc) != 0) {
+ aprint_error_dev(self, "unable to get manufacturing page 0\n");
+ goto free_queues;
+ }
+
if (mpii_portfacts(sc) != 0) {
aprint_error_dev(self, "unable to get portfacts\n");
goto free_queues;
}
- if (mpii_get_ioc_pg8(sc) != 0) {
- aprint_error_dev(self, "unable to get ioc page 8\n");
+ if (mpii_target_map(sc) != 0) {
+ aprint_error_dev(self, "unable to setup target mappings\n");
goto free_queues;
}
@@ -603,14 +585,18 @@ mpii_attach(device_t parent, device_t se
/* 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) ||
+ (sc->sc_porttype == MPII_PORTFACTS_PORTTYPE_TRI_MODE)) {
if (mpii_eventnotify(sc) != 0) {
aprint_error_dev(self, "unable to enable events\n");
goto free_queues;
}
}
- if (mpii_alloc_dev(sc) != 0) {
+ mutex_init(&sc->sc_devs_mtx, MUTEX_DEFAULT, IPL_BIO);
+ sc->sc_devs = malloc(sc->sc_max_devices * sizeof(struct mpii_device *),
+ M_DEVBUF, M_NOWAIT | M_ZERO);
+ if (sc->sc_devs == NULL) {
aprint_error_dev(self,
"unable to allocate memory for mpii_device\n");
goto free_queues;
@@ -618,31 +604,22 @@ mpii_attach(device_t parent, device_t se
if (mpii_portenable(sc) != 0) {
aprint_error_dev(self, "unable to enable port\n");
- goto free_dev;
- }
-
- sc->sc_ih = pci_intr_establish_xname(sc->sc_pc, ih, IPL_BIO,
- mpii_intr, sc, DEVNAME(sc));
- if (sc->sc_ih == NULL) {
- aprint_error_dev(self, "can't establish interrupt");
- if (intrstr)
- aprint_error(" at %s", intrstr);
- aprint_error("\n");
- goto free_dev;
+ goto free_devs;
}
+ /* we should be good to go now, attach scsibus */
memset(adapt, 0, sizeof(*adapt));
adapt->adapt_dev = sc->sc_dev;
adapt->adapt_nchannels = 1;
- adapt->adapt_openings = sc->sc_request_depth - 1;
+ adapt->adapt_openings = sc->sc_max_cmds - 4;
adapt->adapt_max_periph = adapt->adapt_openings;
adapt->adapt_request = mpii_scsipi_request;
- adapt->adapt_minphys = mpii_minphys;
+ adapt->adapt_minphys = minphys;
memset(chan, 0, sizeof(*chan));
chan->chan_adapter = adapt;
chan->chan_bustype = &scsi_sas_bustype;
- chan->chan_channel = 0;
+ chan->chan_channel = 0;
chan->chan_flags = 0;
chan->chan_nluns = 8;
chan->chan_ntargets = sc->sc_max_devices;
@@ -659,7 +636,6 @@ mpii_attach(device_t parent, device_t se
if (bio_register(sc->sc_dev, mpii_ioctl) != 0)
panic("%s: controller registration failed",
DEVNAME(sc));
-
if (mpii_create_sensors(sc) != 0)
aprint_error_dev(self, "unable to create sensors\n");
}
@@ -667,13 +643,13 @@ mpii_attach(device_t parent, device_t se
return;
-free_dev:
- if (sc->sc_devs)
- free(sc->sc_devs, M_DEVBUF);
+free_devs:
+ free(sc->sc_devs, M_DEVBUF);
+ sc->sc_devs = NULL;
free_queues:
bus_dmamap_sync(sc->sc_dmat, MPII_DMA_MAP(sc->sc_reply_freeq),
- 0, sc->sc_reply_free_qdepth * 4, BUS_DMASYNC_POSTREAD);
+ 0, sc->sc_reply_free_qdepth * 4, BUS_DMASYNC_POSTREAD);
mpii_dmamem_free(sc, sc->sc_reply_freeq);
bus_dmamap_sync(sc->sc_dmat, MPII_DMA_MAP(sc->sc_reply_postq),
@@ -686,7 +662,7 @@ free_replies:
mpii_dmamem_free(sc, sc->sc_replies);
free_ccbs:
- while ((ccb = mpii_get_ccb(sc, MPII_NOSLEEP)) != NULL)
+ while ((ccb = mpii_get_ccb(sc)) != NULL)
bus_dmamap_destroy(sc->sc_dmat, ccb->ccb_dmamap);
mpii_dmamem_free(sc, sc->sc_requests);
free(sc->sc_ccbs, M_DEVBUF);
@@ -696,10 +672,10 @@ unmap:
sc->sc_ios = 0;
}
-static int
+int
mpii_detach(device_t self, int flags)
{
- struct mpii_softc *sc = device_private(self);
+ struct mpii_softc *sc = device_private(self);
int error;
struct mpii_ccb *ccb;
@@ -712,8 +688,13 @@ mpii_detach(device_t self, int flags)
#endif /* NBIO > 0 */
if (sc->sc_ih != NULL) {
- if (sc->sc_devs)
- free(sc->sc_devs, M_DEVBUF);
+ pci_intr_disestablish(sc->sc_pc, sc->sc_ih);
+ sc->sc_ih = NULL;
+ }
+ if (sc->sc_ios != 0) {
+ bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios);
+ free(sc->sc_devs, M_DEVBUF);
+ sc->sc_devs = NULL;
bus_dmamap_sync(sc->sc_dmat, MPII_DMA_MAP(sc->sc_reply_freeq),
0, sc->sc_reply_free_qdepth * 4, BUS_DMASYNC_POSTREAD);
@@ -727,24 +708,19 @@ mpii_detach(device_t self, int flags)
0, PAGE_SIZE, BUS_DMASYNC_POSTREAD);
mpii_dmamem_free(sc, sc->sc_replies);
- while ((ccb = mpii_get_ccb(sc, MPII_NOSLEEP)) != NULL)
+ while ((ccb = mpii_get_ccb(sc)) != NULL)
bus_dmamap_destroy(sc->sc_dmat, ccb->ccb_dmamap);
mpii_dmamem_free(sc, sc->sc_requests);
free(sc->sc_ccbs, M_DEVBUF);
- pci_intr_disestablish(sc->sc_pc, sc->sc_ih);
- sc->sc_ih = NULL;
- }
- if (sc->sc_ios != 0) {
- bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios);
sc->sc_ios = 0;
}
return (0);
}
-static int
-mpii_rescan(device_t self, const char *ifattr, const int *locators)
+int
+mpii_rescan(device_t self, const char *ifattr, const int *locators)
{
struct mpii_softc *sc = device_private(self);
@@ -757,19 +733,20 @@ mpii_rescan(device_t self, const char *i
return 0;
}
-static void
+void
mpii_childdetached(device_t self, device_t child)
{
- struct mpii_softc *sc = device_private(self);
+ struct mpii_softc *sc = device_private(self);
- KASSERT(self == sc->sc_dev);
- KASSERT(child == sc->sc_child);
+ KASSERT(self == sc->sc_dev);
+ KASSERT(child == sc->sc_child);
- if (child == sc->sc_child)
- sc->sc_child = NULL;
+ if (child == sc->sc_child)
+ sc->sc_child = NULL;
}
-static int
+
+int
mpii_intr(void *arg)
{
struct mpii_rcb_list evts = SIMPLEQ_HEAD_INITIALIZER(evts);
@@ -779,16 +756,18 @@ mpii_intr(void *arg)
struct mpii_ccb *ccb;
struct mpii_rcb *rcb;
int smid;
+ u_int idx;
int rv = 0;
mutex_enter(&sc->sc_rep_mtx);
bus_dmamap_sync(sc->sc_dmat,
MPII_DMA_MAP(sc->sc_reply_postq),
- 0, 8 * sc->sc_reply_post_qdepth,
+ 0, sc->sc_reply_post_qdepth * sizeof(*rdp),
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
+ idx = sc->sc_reply_post_host_index;
for (;;) {
- rdp = &postq[sc->sc_reply_post_host_index];
+ rdp = &postq[idx];
if ((rdp->reply_flags & MPII_REPLY_DESCR_TYPE_MASK) ==
MPII_REPLY_DESCR_UNUSED)
break;
@@ -807,22 +786,23 @@ mpii_intr(void *arg)
ccb = &sc->sc_ccbs[smid - 1];
ccb->ccb_state = MPII_CCB_READY;
ccb->ccb_rcb = rcb;
- SIMPLEQ_INSERT_TAIL(&ccbs, ccb, u.ccb_link);
+ SIMPLEQ_INSERT_TAIL(&ccbs, ccb, ccb_link);
} else
- SIMPLEQ_INSERT_TAIL(&evts, rcb, u.rcb_link);
+ SIMPLEQ_INSERT_TAIL(&evts, rcb, rcb_link);
+
+ if (++idx >= sc->sc_reply_post_qdepth)
+ idx = 0;
- sc->sc_reply_post_host_index++;
- sc->sc_reply_post_host_index %= sc->sc_reply_post_qdepth;
rv = 1;
}
bus_dmamap_sync(sc->sc_dmat,
MPII_DMA_MAP(sc->sc_reply_postq),
- 0, 8 * sc->sc_reply_post_qdepth,
+ 0, sc->sc_reply_post_qdepth * sizeof(*rdp),
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
if (rv)
- mpii_write_reply_post(sc, sc->sc_reply_post_host_index);
+ mpii_write_reply_post(sc, sc->sc_reply_post_host_index = idx);
mutex_exit(&sc->sc_rep_mtx);
@@ -830,114 +810,128 @@ mpii_intr(void *arg)
return (0);
while ((ccb = SIMPLEQ_FIRST(&ccbs)) != NULL) {
- SIMPLEQ_REMOVE_HEAD(&ccbs, u.ccb_link);
+ SIMPLEQ_REMOVE_HEAD(&ccbs, ccb_link);
ccb->ccb_done(ccb);
}
while ((rcb = SIMPLEQ_FIRST(&evts)) != NULL) {
- SIMPLEQ_REMOVE_HEAD(&evts, u.rcb_link);
+ SIMPLEQ_REMOVE_HEAD(&evts, rcb_link);
mpii_event_process(sc, rcb);
}
return (1);
}
-static int
-mpii_load_xs(struct mpii_ccb *ccb)
+int
+mpii_load_xs_sas3(struct mpii_ccb *ccb)
{
struct mpii_softc *sc = ccb->ccb_sc;
struct scsipi_xfer *xs = ccb->ccb_cookie;
- struct mpii_ccb_bundle *mcb = ccb->ccb_cmd;
- struct mpii_msg_scsi_io *io = &mcb->mcb_io;
- struct mpii_sge *sge = NULL, *nsge = &mcb->mcb_sgl[0];
- struct mpii_sge *ce = NULL, *nce = NULL;
- u_int64_t ce_dva;
+ struct mpii_msg_scsi_io *io = ccb->ccb_cmd;
+ struct mpii_ieee_sge *csge, *nsge, *sge;
bus_dmamap_t dmap = ccb->ccb_dmamap;
- u_int32_t addr, flags;
int i, error;
+ /* Request frame structure is described in the mpii_iocfacts */
+ nsge = (struct mpii_ieee_sge *)(io + 1);
+ csge = nsge + sc->sc_chain_sge;
+
/* zero length transfer still requires an SGE */
if (xs->datalen == 0) {
- nsge->sg_hdr = htole32(MPII_SGE_FL_TYPE_SIMPLE |
- MPII_SGE_FL_LAST | MPII_SGE_FL_EOB | MPII_SGE_FL_EOL);
+ nsge->sg_flags = MPII_IEEE_SGE_END_OF_LIST;
return (0);
}
- error = bus_dmamap_load(sc->sc_dmat, dmap,
- xs->data, xs->datalen, NULL, (xs->xs_control & XS_CTL_NOSLEEP) ?
- BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
+ error = bus_dmamap_load(sc->sc_dmat, dmap, xs->data, xs->datalen, NULL,
+ (xs->xs_control & XS_CTL_NOSLEEP) ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
if (error) {
- aprint_error_dev(sc->sc_dev, "error %d loading dmamap\n",
- error);
+ printf("%s: error %d loading dmamap\n", DEVNAME(sc), error);
return (1);
}
- /* safe default staring flags */
- flags = MPII_SGE_FL_TYPE_SIMPLE | MPII_SGE_FL_SIZE_64;
- /* if data out */
- if (xs->xs_control & XS_CTL_DATA_OUT)
- flags |= MPII_SGE_FL_DIR_OUT;
+ sge = nsge;
+ for (i = 0; i < dmap->dm_nsegs; i++, nsge++) {
+ if (nsge == csge) {
+ nsge++;
+ /* offset to the chain sge from the beginning */
+ io->chain_offset = ((uintptr_t)csge - (uintptr_t)io) / 4;
+ csge->sg_flags = MPII_IEEE_SGE_CHAIN_ELEMENT |
+ MPII_IEEE_SGE_ADDR_SYSTEM;
+ /* address of the next sge */
+ csge->sg_addr = htole64(ccb->ccb_cmd_dva +
+ ((uintptr_t)nsge - (uintptr_t)io));
+ csge->sg_len = htole32((dmap->dm_nsegs - i) *
+ sizeof(*sge));
+ }
- /* we will have to exceed the SGEs we can cram into the request frame */
- if (dmap->dm_nsegs > sc->sc_first_sgl_len) {
- ce = &mcb->mcb_sgl[sc->sc_first_sgl_len - 1];
- io->chain_offset = ((u_int8_t *)ce - (u_int8_t *)io) / 4;
+ sge = nsge;
+ sge->sg_flags = MPII_IEEE_SGE_ADDR_SYSTEM;
+ sge->sg_len = htole32(dmap->dm_segs[i].ds_len);
+ sge->sg_addr = htole64(dmap->dm_segs[i].ds_addr);
}
- for (i = 0; i < dmap->dm_nsegs; i++) {
- if (nsge == ce) {
- nsge++;
- sge->sg_hdr |= htole32(MPII_SGE_FL_LAST);
+ /* terminate list */
+ sge->sg_flags |= MPII_IEEE_SGE_END_OF_LIST;
- DNPRINTF(MPII_D_DMA, "%s: - 0x%08x 0x%08x 0x%08x\n",
- DEVNAME(sc), sge->sg_hdr,
- sge->sg_hi_addr, sge->sg_lo_addr);
-
- if ((dmap->dm_nsegs - i) > sc->sc_chain_len) {
- nce = &nsge[sc->sc_chain_len - 1];
- addr = ((u_int8_t *)nce - (u_int8_t *)nsge) / 4;
- addr = addr << 16 |
- sizeof(struct mpii_sge) * sc->sc_chain_len;
- } else {
- nce = NULL;
- addr = sizeof(struct mpii_sge) *
- (dmap->dm_nsegs - i);
- }
+ bus_dmamap_sync(sc->sc_dmat, dmap, 0, dmap->dm_mapsize,
+ (xs->xs_control & XS_CTL_DATA_IN) ? BUS_DMASYNC_PREREAD :
+ BUS_DMASYNC_PREWRITE);
- ce->sg_hdr = htole32(MPII_SGE_FL_TYPE_CHAIN |
- MPII_SGE_FL_SIZE_64 | addr);
+ return (0);
+}
- ce_dva = ccb->ccb_cmd_dva +
- ((u_int8_t *)nsge - (u_int8_t *)mcb);
+int
+mpii_load_xs(struct mpii_ccb *ccb)
+{
+ struct mpii_softc *sc = ccb->ccb_sc;
+ struct scsipi_xfer *xs = ccb->ccb_cookie;
+ struct mpii_msg_scsi_io *io = ccb->ccb_cmd;
+ struct mpii_sge *csge, *nsge, *sge;
+ bus_dmamap_t dmap = ccb->ccb_dmamap;
+ u_int32_t flags;
+ u_int16_t len;
+ int i, error;
- addr = (u_int32_t)(ce_dva >> 32);
- ce->sg_hi_addr = htole32(addr);
- addr = (u_int32_t)ce_dva;
- ce->sg_lo_addr = htole32(addr);
+ /* Request frame structure is described in the mpii_iocfacts */
+ nsge = (struct mpii_sge *)(io + 1);
+ csge = nsge + sc->sc_chain_sge;
- DNPRINTF(MPII_D_DMA, "%s: ce: 0x%08x 0x%08x 0x%08x\n",
- DEVNAME(sc), ce->sg_hdr, ce->sg_hi_addr,
- ce->sg_lo_addr);
+ /* zero length transfer still requires an SGE */
+ if (xs->datalen == 0) {
+ nsge->sg_hdr = htole32(MPII_SGE_FL_TYPE_SIMPLE |
+ MPII_SGE_FL_LAST | MPII_SGE_FL_EOB | MPII_SGE_FL_EOL);
+ return (0);
+ }
- ce = nce;
- }
+ error = bus_dmamap_load(sc->sc_dmat, dmap, xs->data, xs->datalen, NULL,
+ (xs->xs_control & XS_CTL_NOSLEEP) ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
+ if (error) {
+ printf("%s: error %d loading dmamap\n", DEVNAME(sc), error);
+ return (1);
+ }
- DNPRINTF(MPII_D_DMA, "%s: %d: %" PRId64 " 0x%016" PRIx64 "\n",
- DEVNAME(sc), i, (int64_t)dmap->dm_segs[i].ds_len,
- (u_int64_t)dmap->dm_segs[i].ds_addr);
+ /* safe default starting flags */
+ flags = MPII_SGE_FL_TYPE_SIMPLE | MPII_SGE_FL_SIZE_64;
+ if (xs->xs_control & XS_CTL_DATA_OUT)
+ flags |= MPII_SGE_FL_DIR_OUT;
- sge = nsge;
+ sge = nsge;
+ for (i = 0; i < dmap->dm_nsegs; i++, nsge++) {
+ if (nsge == csge) {
+ nsge++;
+ /* offset to the chain sge from the beginning */
+ io->chain_offset = ((uintptr_t)csge - (uintptr_t)io) / 4;
+ /* length of the sgl segment we're pointing to */
+ len = (dmap->dm_nsegs - i) * sizeof(*sge);
+ csge->sg_hdr = htole32(MPII_SGE_FL_TYPE_CHAIN |
+ MPII_SGE_FL_SIZE_64 | len);
+ /* address of the next sge */
+ mpii_dvatosge(csge, ccb->ccb_cmd_dva +
+ ((uintptr_t)nsge - (uintptr_t)io));
+ }
+ sge = nsge;
sge->sg_hdr = htole32(flags | dmap->dm_segs[i].ds_len);
- addr = (u_int32_t)((u_int64_t)dmap->dm_segs[i].ds_addr >> 32);
- sge->sg_hi_addr = htole32(addr);
- addr = (u_int32_t)dmap->dm_segs[i].ds_addr;
- sge->sg_lo_addr = htole32(addr);
-
- DNPRINTF(MPII_D_DMA, "%s: %d: 0x%08x 0x%08x 0x%08x\n",
- DEVNAME(sc), i, sge->sg_hdr, sge->sg_hi_addr,
- sge->sg_lo_addr);
-
- nsge = sge + 1;
+ mpii_dvatosge(sge, dmap->dm_segs[i].ds_addr);
}
/* terminate list */
@@ -951,7 +945,7 @@ mpii_load_xs(struct mpii_ccb *ccb)
return (0);
}
-static u_int32_t
+u_int32_t
mpii_read(struct mpii_softc *sc, bus_size_t r)
{
u_int32_t rv;
@@ -960,17 +954,15 @@ mpii_read(struct mpii_softc *sc, bus_siz
BUS_SPACE_BARRIER_READ);
rv = bus_space_read_4(sc->sc_iot, sc->sc_ioh, r);
- DNPRINTF(MPII_D_RW, "%s: mpii_read %#" PRIx64 " %#x\n", DEVNAME(sc),
- (uint64_t)r, rv);
+ DNPRINTF(MPII_D_RW, "%s: mpii_read %#lx %#x\n", DEVNAME(sc), r, rv);
return (rv);
}
-static void
+void
mpii_write(struct mpii_softc *sc, bus_size_t r, u_int32_t v)
{
- DNPRINTF(MPII_D_RW, "%s: mpii_write %#" PRIx64 " %#x\n", DEVNAME(sc),
- (uint64_t)r, v);
+ DNPRINTF(MPII_D_RW, "%s: mpii_write %#lx %#x\n", DEVNAME(sc), r, v);
bus_space_write_4(sc->sc_iot, sc->sc_ioh, r, v);
bus_space_barrier(sc->sc_iot, sc->sc_ioh, r, 4,
@@ -978,14 +970,14 @@ mpii_write(struct mpii_softc *sc, bus_si
}
-static int
+int
mpii_wait_eq(struct mpii_softc *sc, bus_size_t r, u_int32_t mask,
u_int32_t target)
{
int i;
- DNPRINTF(MPII_D_RW, "%s: mpii_wait_eq %#" PRIx64 " %#x %#x\n",
- DEVNAME(sc), (uint64_t)r, mask, target);
+ DNPRINTF(MPII_D_RW, "%s: mpii_wait_eq %#lx %#x %#x\n", DEVNAME(sc), r,
+ mask, target);
for (i = 0; i < 15000; i++) {
if ((mpii_read(sc, r) & mask) == target)
@@ -996,14 +988,14 @@ mpii_wait_eq(struct mpii_softc *sc, bus_
return (1);
}
-static int
+int
mpii_wait_ne(struct mpii_softc *sc, bus_size_t r, u_int32_t mask,
u_int32_t target)
{
int i;
- DNPRINTF(MPII_D_RW, "%s: mpii_wait_ne %#" PRIx64 " %#x %#x\n",
- DEVNAME(sc), (uint64_t)r, mask, target);
+ DNPRINTF(MPII_D_RW, "%s: mpii_wait_ne %#lx %#x %#x\n", DEVNAME(sc), r,
+ mask, target);
for (i = 0; i < 15000; i++) {
if ((mpii_read(sc, r) & mask) != target)
@@ -1014,8 +1006,7 @@ mpii_wait_ne(struct mpii_softc *sc, bus_
return (1);
}
-
-static int
+int
mpii_init(struct mpii_softc *sc)
{
u_int32_t db;
@@ -1073,7 +1064,7 @@ mpii_init(struct mpii_softc *sc)
return (1);
}
-static int
+int
mpii_reset_soft(struct mpii_softc *sc)
{
DNPRINTF(MPII_D_MISC, "%s: mpii_reset_soft\n", DEVNAME(sc));
@@ -1084,7 +1075,7 @@ mpii_reset_soft(struct mpii_softc *sc)
mpii_write_db(sc,
MPII_DOORBELL_FUNCTION(MPII_FUNCTION_IOC_MESSAGE_UNIT_RESET));
-
+
/* XXX LSI waits 15 sec */
if (mpii_wait_db_ack(sc) != 0)
return (1);
@@ -1099,7 +1090,7 @@ mpii_reset_soft(struct mpii_softc *sc)
return (0);
}
-static int
+int
mpii_reset_hard(struct mpii_softc *sc)
{
u_int16_t i;
@@ -1133,7 +1124,7 @@ mpii_reset_hard(struct mpii_softc *sc)
/* XXX this whole function should be more robust */
-
+
/* XXX read the host diagnostic reg until reset adapter bit clears ? */
for (i = 0; i < 30000; i++) {
if ((mpii_read(sc, MPII_HOSTDIAG) &
@@ -1152,7 +1143,7 @@ mpii_reset_hard(struct mpii_softc *sc)
return(0);
}
-static int
+int
mpii_handshake_send(struct mpii_softc *sc, void *buf, size_t dwords)
{
u_int32_t *query = buf;
@@ -1195,7 +1186,7 @@ mpii_handshake_send(struct mpii_softc *s
return (0);
}
-static int
+int
mpii_handshake_recv_dword(struct mpii_softc *sc, u_int32_t *dword)
{
u_int16_t *words = (u_int16_t *)dword;
@@ -1211,7 +1202,7 @@ mpii_handshake_recv_dword(struct mpii_so
return (0);
}
-static int
+int
mpii_handshake_recv(struct mpii_softc *sc, void *buf, size_t dwords)
{
struct mpii_msg_reply *reply = buf;
@@ -1222,7 +1213,7 @@ mpii_handshake_recv(struct mpii_softc *s
if (mpii_handshake_recv_dword(sc, &dbuf[0]) != 0)
return (1);
- DNPRINTF(MPII_D_CMD, "%s: mpii_handshake_recv dwords: %zd reply: %d\n",
+ DNPRINTF(MPII_D_CMD, "%s: mpii_handshake_recv dwords: %lu reply: %d\n",
DEVNAME(sc), dwords, reply->msg_length);
/*
@@ -1245,31 +1236,34 @@ mpii_handshake_recv(struct mpii_softc *s
/* wait for the doorbell used bit to be reset and clear the intr */
if (mpii_wait_db_int(sc) != 0)
return (1);
-
+
if (mpii_wait_eq(sc, MPII_DOORBELL, MPII_DOORBELL_INUSE, 0) != 0)
return (1);
-
+
mpii_write_intr(sc, 0);
return (0);
}
-static void
+void
mpii_empty_done(struct mpii_ccb *ccb)
{
/* nothing to do */
}
-static int
+int
mpii_iocfacts(struct mpii_softc *sc)
{
struct mpii_msg_iocfacts_request ifq;
struct mpii_msg_iocfacts_reply ifp;
+ int irs;
+ int sge_size;
+ u_int qdepth;
DNPRINTF(MPII_D_MISC, "%s: mpii_iocfacts\n", DEVNAME(sc));
- bzero(&ifq, sizeof(ifq));
- bzero(&ifp, sizeof(ifp));
+ memset(&ifq, 0, sizeof(ifq));
+ memset(&ifp, 0, sizeof(ifp));
ifq.function = MPII_FUNCTION_IOC_FACTS;
@@ -1285,136 +1279,129 @@ mpii_iocfacts(struct mpii_softc *sc)
return (1);
}
- DNPRINTF(MPII_D_MISC, "%s: func: 0x%02x length: %d msgver: %d.%d\n",
- DEVNAME(sc), ifp.function, ifp.msg_length,
- ifp.msg_version_maj, ifp.msg_version_min);
- DNPRINTF(MPII_D_MISC, "%s: msgflags: 0x%02x iocnumber: 0x%02x "
- "headerver: %d.%d\n", DEVNAME(sc), ifp.msg_flags,
- ifp.ioc_number, ifp.header_version_unit,
- ifp.header_version_dev);
- DNPRINTF(MPII_D_MISC, "%s: vp_id: 0x%02x vf_id: 0x%02x\n", DEVNAME(sc),
- ifp.vp_id, ifp.vf_id);
- DNPRINTF(MPII_D_MISC, "%s: iocstatus: 0x%04x ioexceptions: 0x%04x\n",
- DEVNAME(sc), le16toh(ifp.ioc_status),
- le16toh(ifp.ioc_exceptions));
- DNPRINTF(MPII_D_MISC, "%s: iocloginfo: 0x%08x\n", DEVNAME(sc),
- le32toh(ifp.ioc_loginfo));
- DNPRINTF(MPII_D_MISC, "%s: numberofports: 0x%02x whoinit: 0x%02x "
- "maxchaindepth: %d\n", DEVNAME(sc), ifp.number_of_ports,
- ifp.whoinit, ifp.max_chain_depth);
- DNPRINTF(MPII_D_MISC, "%s: productid: 0x%04x requestcredit: 0x%04x\n",
- DEVNAME(sc), le16toh(ifp.product_id), le16toh(ifp.request_credit));
- DNPRINTF(MPII_D_MISC, "%s: ioc_capabilities: 0x%08x\n", DEVNAME(sc),
- le32toh(ifp.ioc_capabilities));
- DNPRINTF(MPII_D_MISC, "%s: fw_version: %d.%d fw_version_unit: 0x%02x "
- "fw_version_dev: 0x%02x\n", DEVNAME(sc),
- ifp.fw_version_maj, ifp.fw_version_min,
- ifp.fw_version_unit, ifp.fw_version_dev);
- DNPRINTF(MPII_D_MISC, "%s: iocrequestframesize: 0x%04x\n",
- DEVNAME(sc), le16toh(ifp.ioc_request_frame_size));
- DNPRINTF(MPII_D_MISC, "%s: maxtargets: 0x%04x "
- "maxinitiators: 0x%04x\n", DEVNAME(sc),
- le16toh(ifp.max_targets), le16toh(ifp.max_initiators));
- DNPRINTF(MPII_D_MISC, "%s: maxenclosures: 0x%04x "
- "maxsasexpanders: 0x%04x\n", DEVNAME(sc),
- le16toh(ifp.max_enclosures), le16toh(ifp.max_sas_expanders));
- DNPRINTF(MPII_D_MISC, "%s: highprioritycredit: 0x%04x "
- "protocolflags: 0x%02x\n", DEVNAME(sc),
- le16toh(ifp.high_priority_credit), le16toh(ifp.protocol_flags));
- DNPRINTF(MPII_D_MISC, "%s: maxvolumes: 0x%02x replyframesize: 0x%02x "
- "mrdpqd: 0x%04x\n", DEVNAME(sc), ifp.max_volumes,
- ifp.reply_frame_size,
- le16toh(ifp.max_reply_descriptor_post_queue_depth));
- DNPRINTF(MPII_D_MISC, "%s: maxpersistententries: 0x%04x "
- "maxdevhandle: 0x%02x\n", DEVNAME(sc),
- le16toh(ifp.max_persistent_entries), le16toh(ifp.max_dev_handle));
-
- sc->sc_maxchdepth = ifp.max_chain_depth;
sc->sc_ioc_number = ifp.ioc_number;
sc->sc_vf_id = ifp.vf_id;
- sc->sc_num_ports = ifp.number_of_ports;
- sc->sc_ioc_event_replay = (le32toh(ifp.ioc_capabilities) &
- MPII_IOCFACTS_CAPABILITY_EVENT_REPLAY) ? 1 : 0;
- sc->sc_max_enclosures = le16toh(ifp.max_enclosures);
- sc->sc_max_expanders = le16toh(ifp.max_sas_expanders);
sc->sc_max_volumes = ifp.max_volumes;
sc->sc_max_devices = ifp.max_volumes + le16toh(ifp.max_targets);
- sc->sc_num_channels = 1;
if (ISSET(le32toh(ifp.ioc_capabilities),
MPII_IOCFACTS_CAPABILITY_INTEGRATED_RAID))
SET(sc->sc_flags, MPII_F_RAID);
+ if (ISSET(le32toh(ifp.ioc_capabilities),
+ MPII_IOCFACTS_CAPABILITY_EVENT_REPLAY))
+ sc->sc_ioc_event_replay = 1;
+
+ sc->sc_max_cmds = MIN(le16toh(ifp.request_credit),
+ MPII_REQUEST_CREDIT);
- sc->sc_request_depth = MIN(le16toh(ifp.request_credit),
- MPII_MAX_REQUEST_CREDIT);
+ /* SAS3 and 3.5 controllers have different sgl layouts */
+ if (ifp.msg_version_maj == 2 && ((ifp.msg_version_min == 5)
+ || (ifp.msg_version_min == 6)))
+ SET(sc->sc_flags, MPII_F_SAS3);
- /* should not be multiple of 16 */
- sc->sc_num_reply_frames = sc->sc_request_depth + 32;
+ /*
+ * The host driver must ensure that there is at least one
+ * unused entry in the Reply Free Queue. One way to ensure
+ * that this requirement is met is to never allocate a number
+ * of reply frames that is a multiple of 16.
+ */
+ sc->sc_num_reply_frames = sc->sc_max_cmds + 32;
if (!(sc->sc_num_reply_frames % 16))
sc->sc_num_reply_frames--;
/* must be multiple of 16 */
+ sc->sc_reply_post_qdepth = sc->sc_max_cmds +
+ sc->sc_num_reply_frames;
+ sc->sc_reply_post_qdepth += 16 - (sc->sc_reply_post_qdepth % 16);
+
+ qdepth = le16toh(ifp.max_reply_descriptor_post_queue_depth);
+ if (sc->sc_reply_post_qdepth > qdepth) {
+ sc->sc_reply_post_qdepth = qdepth;
+ if (sc->sc_reply_post_qdepth < 16) {
+ printf("%s: RDPQ is too shallow\n", DEVNAME(sc));
+ return (1);
+ }
+ sc->sc_max_cmds = sc->sc_reply_post_qdepth / 2 - 4;
+ sc->sc_num_reply_frames = sc->sc_max_cmds + 4;
+ }
+
sc->sc_reply_free_qdepth = sc->sc_num_reply_frames +
- (16 - (sc->sc_num_reply_frames % 16));
- sc->sc_reply_post_qdepth = ((sc->sc_request_depth +
- sc->sc_num_reply_frames + 1 + 15) / 16) * 16;
-
- if (sc->sc_reply_post_qdepth >
- ifp.max_reply_descriptor_post_queue_depth)
- sc->sc_reply_post_qdepth =
- ifp.max_reply_descriptor_post_queue_depth;
-
- DNPRINTF(MPII_D_MISC, "%s: sc_request_depth: %d "
- "sc_num_reply_frames: %d sc_reply_free_qdepth: %d "
- "sc_reply_post_qdepth: %d\n", DEVNAME(sc), sc->sc_request_depth,
- sc->sc_num_reply_frames, sc->sc_reply_free_qdepth,
- sc->sc_reply_post_qdepth);
+ 16 - (sc->sc_num_reply_frames % 16);
/*
- * you can fit sg elements on the end of the io cmd if they fit in the
- * request frame size.
+ * Our request frame for an I/O operation looks like this:
+ *
+ * +-------------------+ -.
+ * | mpii_msg_scsi_io | |
+ * +-------------------| |
+ * | mpii_sge | |
+ * + - - - - - - - - - + |
+ * | ... | > ioc_request_frame_size
+ * + - - - - - - - - - + |
+ * | mpii_sge (tail) | |
+ * + - - - - - - - - - + |
+ * | mpii_sge (csge) | | --.
+ * + - - - - - - - - - + -' | chain sge points to the next sge
+ * | mpii_sge |<-----'
+ * + - - - - - - - - - +
+ * | ... |
+ * + - - - - - - - - - +
+ * | mpii_sge (tail) |
+ * +-------------------+
+ * | |
+ * ~~~~~~~~~~~~~~~~~~~~~
+ * | |
+ * +-------------------+ <- sc_request_size - sizeof(scsi_sense_data)
+ * | scsi_sense_data |
+ * +-------------------+
*/
- sc->sc_first_sgl_len = ((le16toh(ifp.ioc_request_frame_size) * 4) -
- sizeof(struct mpii_msg_scsi_io)) / sizeof(struct mpii_sge);
- DNPRINTF(MPII_D_MISC, "%s: first sgl len: %d\n", DEVNAME(sc),
- sc->sc_first_sgl_len);
-
- sc->sc_chain_len = (le16toh(ifp.ioc_request_frame_size) * 4) /
- sizeof(struct mpii_sge);
- DNPRINTF(MPII_D_MISC, "%s: chain len: %d\n", DEVNAME(sc),
- sc->sc_chain_len);
-
- /* the sgl tailing the io cmd loses an entry to the chain element. */
- sc->sc_max_sgl_len = MPII_MAX_SGL - 1;
- /* the sgl chains lose an entry for each chain element */
- sc->sc_max_sgl_len -= (MPII_MAX_SGL - sc->sc_first_sgl_len) /
- sc->sc_chain_len;
- DNPRINTF(MPII_D_MISC, "%s: max sgl len: %d\n", DEVNAME(sc),
- sc->sc_max_sgl_len);
+ /* both sizes are in 32-bit words */
+ sc->sc_reply_size = ifp.reply_frame_size * 4;
+ irs = le16toh(ifp.ioc_request_frame_size) * 4;
+ sc->sc_request_size = MPII_REQUEST_SIZE;
+ /* make sure we have enough space for scsi sense data */
+ if (irs > sc->sc_request_size) {
+ sc->sc_request_size = irs + sizeof(struct scsi_sense_data);
+ sc->sc_request_size += 16 - (sc->sc_request_size % 16);
+ }
+
+ if (ISSET(sc->sc_flags, MPII_F_SAS3)) {
+ sge_size = sizeof(struct mpii_ieee_sge);
+ } else {
+ sge_size = sizeof(struct mpii_sge);
+ }
- /* XXX we're ignoring the max chain depth */
+ /* offset to the chain sge */
+ sc->sc_chain_sge = (irs - sizeof(struct mpii_msg_scsi_io)) /
+ sge_size - 1;
- return(0);
+ /*
+ * A number of simple scatter-gather elements we can fit into the
+ * request buffer after the I/O command minus the chain element.
+ */
+ sc->sc_max_sgl = (sc->sc_request_size -
+ sizeof(struct mpii_msg_scsi_io) - sizeof(struct scsi_sense_data)) /
+ sge_size - 1;
+ return (0);
}
-static int
+int
mpii_iocinit(struct mpii_softc *sc)
{
struct mpii_msg_iocinit_request iiq;
struct mpii_msg_iocinit_reply iip;
- u_int32_t hi_addr;
DNPRINTF(MPII_D_MISC, "%s: mpii_iocinit\n", DEVNAME(sc));
- bzero(&iiq, sizeof(iiq));
- bzero(&iip, sizeof(iip));
+ memset(&iiq, 0, sizeof(iiq));
+ memset(&iip, 0, sizeof(iip));
iiq.function = MPII_FUNCTION_IOC_INIT;
iiq.whoinit = MPII_WHOINIT_HOST_DRIVER;
-
+
/* XXX JPG do something about vf_id */
iiq.vf_id = 0;
@@ -1425,28 +1412,33 @@ mpii_iocinit(struct mpii_softc *sc)
iiq.hdr_version_unit = 0x00;
iiq.hdr_version_dev = 0x00;
- iiq.system_request_frame_size = htole16(MPII_REQUEST_SIZE / 4);
+ iiq.system_request_frame_size = htole16(sc->sc_request_size / 4);
iiq.reply_descriptor_post_queue_depth =
htole16(sc->sc_reply_post_qdepth);
iiq.reply_free_queue_depth = htole16(sc->sc_reply_free_qdepth);
-
- hi_addr = (u_int32_t)((u_int64_t)MPII_DMA_DVA(sc->sc_requests) >> 32);
- iiq.sense_buffer_address_high = htole32(hi_addr);
- hi_addr = (u_int32_t)
- ((u_int64_t)MPII_DMA_DVA(sc->sc_replies) >> 32);
- iiq.system_reply_address_high = htole32(hi_addr);
+ iiq.sense_buffer_address_high =
+ htole32(MPII_DMA_DVA(sc->sc_requests) >> 32);
- iiq.system_request_frame_base_address =
- (u_int64_t)MPII_DMA_DVA(sc->sc_requests);
+ iiq.system_reply_address_high =
+ htole32(MPII_DMA_DVA(sc->sc_replies) >> 32);
- iiq.reply_descriptor_post_queue_address =
- (u_int64_t)MPII_DMA_DVA(sc->sc_reply_postq);
-
- iiq.reply_free_queue_address =
- (u_int64_t)MPII_DMA_DVA(sc->sc_reply_freeq);
+ iiq.system_request_frame_base_address_lo =
+ htole32(MPII_DMA_DVA(sc->sc_requests));
+ iiq.system_request_frame_base_address_hi =
+ htole32(MPII_DMA_DVA(sc->sc_requests) >> 32);
+
+ iiq.reply_descriptor_post_queue_address_lo =
+ htole32(MPII_DMA_DVA(sc->sc_reply_postq));
+ iiq.reply_descriptor_post_queue_address_hi =
+ htole32(MPII_DMA_DVA(sc->sc_reply_postq) >> 32);
+
+ iiq.reply_free_queue_address_lo =
+ htole32(MPII_DMA_DVA(sc->sc_reply_freeq));
+ iiq.reply_free_queue_address_hi =
+ htole32(MPII_DMA_DVA(sc->sc_reply_freeq) >> 32);
if (mpii_handshake_send(sc, &iiq, dwordsof(iiq)) != 0) {
DNPRINTF(MPII_D_MISC, "%s: mpii_iocinit send failed\n",
@@ -1472,30 +1464,36 @@ mpii_iocinit(struct mpii_softc *sc)
DNPRINTF(MPII_D_MISC, "%s: ioc_loginfo: 0x%08x\n", DEVNAME(sc),
le32toh(iip.ioc_loginfo));
- if ((iip.ioc_status != MPII_IOCSTATUS_SUCCESS) || (iip.ioc_loginfo))
+ if (le16toh(iip.ioc_status) != MPII_IOCSTATUS_SUCCESS ||
+ le32toh(iip.ioc_loginfo))
return (1);
return (0);
}
-static void
+void
mpii_push_reply(struct mpii_softc *sc, struct mpii_rcb *rcb)
{
u_int32_t *rfp;
+ u_int idx;
if (rcb == NULL)
return;
+ mutex_enter(&sc->sc_reply_free_mtx);
+ idx = sc->sc_reply_free_host_index;
+
rfp = MPII_DMA_KVA(sc->sc_reply_freeq);
- rfp[sc->sc_reply_free_host_index] = rcb->rcb_reply_dva;
+ rfp[idx] = htole32(rcb->rcb_reply_dva);
- sc->sc_reply_free_host_index = (sc->sc_reply_free_host_index + 1) %
- sc->sc_reply_free_qdepth;
+ if (++idx >= sc->sc_reply_free_qdepth)
+ idx = 0;
- mpii_write_reply_free(sc, sc->sc_reply_free_host_index);
+ mpii_write_reply_free(sc, sc->sc_reply_free_host_index = idx);
+ mutex_exit(&sc->sc_reply_free_mtx);
}
-static int
+int
mpii_portfacts(struct mpii_softc *sc)
{
struct mpii_msg_portfacts_request *pfq;
@@ -1505,7 +1503,7 @@ mpii_portfacts(struct mpii_softc *sc)
DNPRINTF(MPII_D_MISC, "%s: mpii_portfacts\n", DEVNAME(sc));
- ccb = mpii_get_ccb(sc, 0);
+ ccb = mpii_get_ccb(sc);
if (ccb == NULL) {
DNPRINTF(MPII_D_MISC, "%s: mpii_portfacts mpii_get_ccb fail\n",
DEVNAME(sc));
@@ -1515,7 +1513,7 @@ mpii_portfacts(struct mpii_softc *sc)
ccb->ccb_done = mpii_empty_done;
pfq = ccb->ccb_cmd;
- bzero(pfq, sizeof(*pfq));
+ memset(pfq, 0, sizeof(*pfq));
pfq->function = MPII_FUNCTION_PORT_FACTS;
pfq->chain_offset = 0;
@@ -1537,23 +1535,6 @@ mpii_portfacts(struct mpii_softc *sc)
}
pfp = ccb->ccb_rcb->rcb_reply;
- DNPRINTF(MPII_D_MISC, "%s pfp: %p\n", DEVNAME(sc), pfp);
-
- DNPRINTF(MPII_D_MISC, "%s: function: 0x%02x msg_length: %d\n",
- 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: ioc_status: 0x%04x\n", DEVNAME(sc),
- le16toh(pfp->ioc_status));
- DNPRINTF(MPII_D_MISC, "%s: ioc_loginfo: 0x%08x\n", DEVNAME(sc),
- le32toh(pfp->ioc_loginfo));
- DNPRINTF(MPII_D_MISC, "%s: port_type: 0x%02x\n", DEVNAME(sc),
- pfp->port_type);
- DNPRINTF(MPII_D_MISC, "%s: max_posted_cmd_buffers: %d\n", DEVNAME(sc),
- le16toh(pfp->max_posted_cmd_buffers));
-
sc->sc_porttype = pfp->port_type;
mpii_push_reply(sc, ccb->ccb_rcb);
@@ -1564,34 +1545,42 @@ err:
return (rv);
}
-static void
-mpii_eventack(struct work *wk, void *cookie)
+void
+mpii_eventack(struct work *wk, void * cookie)
{
struct mpii_softc *sc = cookie;
struct mpii_ccb *ccb;
- struct mpii_rcb *rcb = (void *)wk;
+ struct mpii_rcb *rcb, *next;
struct mpii_msg_event_reply *enp;
struct mpii_msg_eventack_request *eaq;
- ccb = mpii_get_ccb(sc, 0);
+ mutex_enter(&sc->sc_evt_ack_mtx);
+ next = SIMPLEQ_FIRST(&sc->sc_evt_ack_queue);
+ SIMPLEQ_INIT(&sc->sc_evt_ack_queue);
+ mutex_exit(&sc->sc_evt_ack_mtx);
- enp = (struct mpii_msg_event_reply *)rcb->rcb_reply;
+ while (next != NULL) {
+ rcb = next;
+ next = SIMPLEQ_NEXT(rcb, rcb_link);
- ccb->ccb_done = mpii_eventack_done;
- eaq = ccb->ccb_cmd;
+ enp = (struct mpii_msg_event_reply *)rcb->rcb_reply;
- eaq->function = MPII_FUNCTION_EVENT_ACK;
+ ccb = mpii_get_ccb(sc);
+ ccb->ccb_done = mpii_eventack_done;
+ eaq = ccb->ccb_cmd;
- eaq->event = enp->event;
- eaq->event_context = enp->event_context;
+ eaq->function = MPII_FUNCTION_EVENT_ACK;
- mpii_push_reply(sc, rcb);
+ eaq->event = enp->event;
+ eaq->event_context = enp->event_context;
- mpii_start(sc, ccb);
+ mpii_push_reply(sc, rcb);
+ mpii_start(sc, ccb);
+ }
}
-static void
+void
mpii_eventack_done(struct mpii_ccb *ccb)
{
struct mpii_softc *sc = ccb->ccb_sc;
@@ -1602,7 +1591,7 @@ mpii_eventack_done(struct mpii_ccb *ccb)
mpii_put_ccb(sc, ccb);
}
-static int
+int
mpii_portenable(struct mpii_softc *sc)
{
struct mpii_msg_portenable_request *peq;
@@ -1610,7 +1599,7 @@ mpii_portenable(struct mpii_softc *sc)
DNPRINTF(MPII_D_MISC, "%s: mpii_portenable\n", DEVNAME(sc));
- ccb = mpii_get_ccb(sc, 0);
+ ccb = mpii_get_ccb(sc);
if (ccb == NULL) {
DNPRINTF(MPII_D_MISC, "%s: mpii_portenable ccb_get\n",
DEVNAME(sc));
@@ -1641,38 +1630,31 @@ mpii_portenable(struct mpii_softc *sc)
return (0);
}
-static int
+int
mpii_cfg_coalescing(struct mpii_softc *sc)
{
- 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));
- return (1);
- }
+ struct mpii_cfg_hdr hdr;
+ struct mpii_cfg_ioc_pg1 ipg;
- if (mpii_cfg_page(sc, 0, &hdr, 1, &pg, sizeof(pg)) != 0) {
+ hdr.page_version = 0;
+ hdr.page_length = sizeof(ipg) / 4;
+ hdr.page_number = 1;
+ hdr.page_type = MPII_CONFIG_REQ_PAGE_TYPE_IOC;
+ memset(&ipg, 0, sizeof(ipg));
+ if (mpii_req_cfg_page(sc, 0, MPII_PG_POLL, &hdr, 1, &ipg,
+ sizeof(ipg)) != 0) {
DNPRINTF(MPII_D_MISC, "%s: unable to fetch IOC page 1\n"
"page 1\n", DEVNAME(sc));
return (1);
}
- DNPRINTF(MPII_D_MISC, "%s: IOC page 1\n", DEVNAME(sc));
- DNPRINTF(MPII_D_MISC, "%s: flags: 0x08%x\n", DEVNAME(sc),
- le32toh(pg.flags));
- DNPRINTF(MPII_D_MISC, "%s: coalescing_timeout: %d\n", DEVNAME(sc),
- le32toh(pg.coalescing_timeout));
- DNPRINTF(MPII_D_MISC, "%s: coalescing_depth: %d pci_slot_num: %d\n",
- DEVNAME(sc), pg.coalescing_timeout, pg.pci_slot_num);
-
- if (!ISSET(le32toh(pg.flags), MPII_CFG_IOC_1_REPLY_COALESCING))
+ if (!ISSET(le32toh(ipg.flags), MPII_CFG_IOC_1_REPLY_COALESCING))
return (0);
- CLR(pg.flags, htole32(MPII_CFG_IOC_1_REPLY_COALESCING));
- if (mpii_cfg_page(sc, 0, &hdr, 0, &pg, sizeof(pg)) != 0) {
+ /* Disable coalescing */
+ CLR(ipg.flags, htole32(MPII_CFG_IOC_1_REPLY_COALESCING));
+ if (mpii_req_cfg_page(sc, 0, MPII_PG_POLL, &hdr, 0, &ipg,
+ sizeof(ipg)) != 0) {
DNPRINTF(MPII_D_MISC, "%s: unable to clear coalescing\n",
DEVNAME(sc));
return (1);
@@ -1693,19 +1675,42 @@ mpii_cfg_coalescing(struct mpii_softc *s
htole32(~(1 << (evt % 32))); \
} while (0)
-static int
+int
mpii_eventnotify(struct mpii_softc *sc)
{
struct mpii_msg_event_request *enq;
struct mpii_ccb *ccb;
+ char wkname[15];
- ccb = mpii_get_ccb(sc, 0);
+ ccb = mpii_get_ccb(sc);
if (ccb == NULL) {
DNPRINTF(MPII_D_MISC, "%s: mpii_eventnotify ccb_get\n",
DEVNAME(sc));
return (1);
}
+ SIMPLEQ_INIT(&sc->sc_evt_sas_queue);
+ mutex_init(&sc->sc_evt_sas_mtx, MUTEX_DEFAULT, IPL_BIO);
+ snprintf(wkname, sizeof(wkname), "%ssas", DEVNAME(sc));
+ if (workqueue_create(&sc->sc_evt_sas_wq, wkname,
+ mpii_event_sas_work, sc, PRI_NONE, IPL_BIO, WQ_MPSAFE) != 0) {
+ mpii_put_ccb(sc, ccb);
+ aprint_error_dev(sc->sc_dev,
+ "can't create %s workqueue\n", wkname);
+ return 1;
+ }
+
+ SIMPLEQ_INIT(&sc->sc_evt_ack_queue);
+ mutex_init(&sc->sc_evt_ack_mtx, MUTEX_DEFAULT, IPL_BIO);
+ snprintf(wkname, sizeof(wkname), "%sevt", DEVNAME(sc));
+ if (workqueue_create(&sc->sc_evt_ack_wq, wkname,
+ mpii_eventack, sc, PRI_NONE, IPL_BIO, WQ_MPSAFE) != 0) {
+ mpii_put_ccb(sc, ccb);
+ aprint_error_dev(sc->sc_dev,
+ "can't create %s workqueue\n", wkname);
+ return 1;
+ }
+
ccb->ccb_done = mpii_eventnotify_done;
enq = ccb->ccb_cmd;
@@ -1739,7 +1744,7 @@ mpii_eventnotify(struct mpii_softc *sc)
return (0);
}
-static void
+void
mpii_eventnotify_done(struct mpii_ccb *ccb)
{
struct mpii_softc *sc = ccb->ccb_sc;
@@ -1751,7 +1756,7 @@ mpii_eventnotify_done(struct mpii_ccb *c
mpii_event_process(sc, rcb);
}
-static void
+void
mpii_event_raid(struct mpii_softc *sc, struct mpii_msg_event_reply *enp)
{
struct mpii_evt_ir_cfg_change_list *ccl;
@@ -1761,12 +1766,13 @@ mpii_event_raid(struct mpii_softc *sc, s
int i;
ccl = (struct mpii_evt_ir_cfg_change_list *)(enp + 1);
-
if (ccl->num_elements == 0)
return;
- if (ISSET(le32toh(ccl->flags), MPII_EVT_IR_CFG_CHANGE_LIST_FOREIGN))
+
+ if (ISSET(le32toh(ccl->flags), MPII_EVT_IR_CFG_CHANGE_LIST_FOREIGN)) {
/* bail on foreign configurations */
return;
+ }
ce = (struct mpii_evt_ir_cfg_element *)(ccl + 1);
@@ -1779,45 +1785,45 @@ mpii_event_raid(struct mpii_softc *sc, s
switch (ce->reason_code) {
case MPII_EVT_IR_CFG_ELEMENT_RC_ADDED:
case MPII_EVT_IR_CFG_ELEMENT_RC_VOLUME_CREATED:
- if (mpii_find_dev(sc,
- le16toh(ce->vol_dev_handle))) {
- aprint_error_dev(sc->sc_dev,
- "device %#x is already "
- "configured\n",
- le16toh(ce->vol_dev_handle));
- break;
- }
dev = malloc(sizeof(*dev), M_DEVBUF,
M_NOWAIT | M_ZERO);
if (!dev) {
- aprint_error_dev(sc->sc_dev,
- "can't allocate device structure\n");
+ printf("%s: failed to allocate a "
+ "device structure\n", DEVNAME(sc));
+ break;
+ }
+ mutex_enter(&sc->sc_devs_mtx);
+ if (mpii_find_dev(sc,
+ le16toh(ce->vol_dev_handle))) {
+ mutex_exit(&sc->sc_devs_mtx);
+ free(dev, M_DEVBUF);
+ printf("%s: device %#x is already "
+ "configured\n", DEVNAME(sc),
+ le16toh(ce->vol_dev_handle));
break;
}
SET(dev->flags, MPII_DF_VOLUME);
dev->slot = sc->sc_vd_id_low;
dev->dev_handle = le16toh(ce->vol_dev_handle);
if (mpii_insert_dev(sc, dev)) {
- aprint_error_dev(sc->sc_dev,
- "can't insert device structure\n");
- free(dev, M_DEVBUF);
- break;
- }
- if (mpii_cache_enable(sc, dev)) {
- aprint_error_dev(sc->sc_dev,
- "can't enable device cache\n");
+ mutex_exit(&sc->sc_devs_mtx);
free(dev, M_DEVBUF);
break;
}
sc->sc_vd_count++;
+ mutex_exit(&sc->sc_devs_mtx);
break;
case MPII_EVT_IR_CFG_ELEMENT_RC_REMOVED:
case MPII_EVT_IR_CFG_ELEMENT_RC_VOLUME_DELETED:
+ mutex_enter(&sc->sc_devs_mtx);
if (!(dev = mpii_find_dev(sc,
- le16toh(ce->vol_dev_handle))))
+ le16toh(ce->vol_dev_handle)))) {
+ mutex_exit(&sc->sc_devs_mtx);
break;
+ }
mpii_remove_dev(sc, dev);
sc->sc_vd_count--;
+ mutex_exit(&sc->sc_devs_mtx);
break;
}
break;
@@ -1827,99 +1833,202 @@ mpii_event_raid(struct mpii_softc *sc, s
ce->reason_code ==
MPII_EVT_IR_CFG_ELEMENT_RC_HIDE) {
/* there should be an underlying sas drive */
+ mutex_enter(&sc->sc_devs_mtx);
if (!(dev = mpii_find_dev(sc,
- le16toh(ce->phys_disk_dev_handle))))
+ le16toh(ce->phys_disk_dev_handle)))) {
+ mutex_exit(&sc->sc_devs_mtx);
break;
+ }
/* promoted from a hot spare? */
CLR(dev->flags, MPII_DF_HOT_SPARE);
SET(dev->flags, MPII_DF_VOLUME_DISK |
MPII_DF_HIDDEN);
+ mutex_exit(&sc->sc_devs_mtx);
}
break;
case MPII_EVT_IR_CFG_ELEMENT_TYPE_HOT_SPARE:
if (ce->reason_code ==
MPII_EVT_IR_CFG_ELEMENT_RC_HIDE) {
/* there should be an underlying sas drive */
+ mutex_enter(&sc->sc_devs_mtx);
if (!(dev = mpii_find_dev(sc,
- le16toh(ce->phys_disk_dev_handle))))
+ le16toh(ce->phys_disk_dev_handle)))) {
+ mutex_exit(&sc->sc_devs_mtx);
break;
+ }
SET(dev->flags, MPII_DF_HOT_SPARE |
MPII_DF_HIDDEN);
+ mutex_exit(&sc->sc_devs_mtx);
}
break;
}
}
}
-static void
-mpii_event_sas(struct mpii_softc *sc, struct mpii_msg_event_reply *enp)
+void
+mpii_event_sas(struct mpii_softc *sc, struct mpii_rcb *rcb)
{
+ struct mpii_msg_event_reply *enp;
struct mpii_evt_sas_tcl *tcl;
struct mpii_evt_phy_entry *pe;
struct mpii_device *dev;
int i;
+ u_int16_t handle;
+ int need_queue = 0;
- tcl = (struct mpii_evt_sas_tcl *)(enp + 1);
-
- if (tcl->num_entries == 0)
- return;
+ enp = (struct mpii_msg_event_reply *)rcb->rcb_reply;
+ DNPRINTF(MPII_D_EVT, "%s: mpii_event_sas 0x%x\n",
+ DEVNAME(sc), le16toh(enp->event));
+ KASSERT(le16toh(enp->event) == MPII_EVENT_SAS_TOPOLOGY_CHANGE_LIST);
+ tcl = (struct mpii_evt_sas_tcl *)(enp + 1);
pe = (struct mpii_evt_phy_entry *)(tcl + 1);
for (i = 0; i < tcl->num_entries; i++, pe++) {
+ DNPRINTF(MPII_D_EVT, "%s: sas change %d stat %d h %d slot %d phy %d enc %d expand %d\n",
+ DEVNAME(sc), i, pe->phy_status,
+ le16toh(pe->dev_handle),
+ sc->sc_pd_id_start + tcl->start_phy_num + i,
+ tcl->start_phy_num + i, le16toh(tcl->enclosure_handle), le16toh(tcl->expander_handle));
+
switch (pe->phy_status & MPII_EVENT_SAS_TOPO_PS_RC_MASK) {
case MPII_EVENT_SAS_TOPO_PS_RC_ADDED:
- if (mpii_find_dev(sc, le16toh(pe->dev_handle))) {
- aprint_error_dev(sc->sc_dev,
- "device %#x is already configured\n",
- le16toh(pe->dev_handle));
- break;
- }
- dev = malloc(sizeof(*dev), M_DEVBUF, M_NOWAIT | M_ZERO);
- if (!dev) {
- aprint_error_dev(sc->sc_dev, "can't allocate "
- "device structure\n");
+ handle = le16toh(pe->dev_handle);
+ DNPRINTF(MPII_D_EVT, "%s: sas add handle %d\n",
+ DEVNAME(sc), handle);
+ dev = malloc(sizeof(*dev), M_DEVBUF, M_WAITOK | M_ZERO);
+ mutex_enter(&sc->sc_devs_mtx);
+ if (mpii_find_dev(sc, handle)) {
+ mutex_exit(&sc->sc_devs_mtx);
+ free(dev, M_DEVBUF);
+ printf("%s: device %#x is already "
+ "configured\n", DEVNAME(sc), handle);
break;
}
+
dev->slot = sc->sc_pd_id_start + tcl->start_phy_num + i;
- dev->dev_handle = le16toh(pe->dev_handle);
+ dev->dev_handle = handle;
dev->phy_num = tcl->start_phy_num + i;
if (tcl->enclosure_handle)
dev->physical_port = tcl->physical_port;
dev->enclosure = le16toh(tcl->enclosure_handle);
dev->expander = le16toh(tcl->expander_handle);
+
if (mpii_insert_dev(sc, dev)) {
- aprint_error_dev(sc->sc_dev, "can't insert "
- "device structure\n");
+ mutex_exit(&sc->sc_devs_mtx);
free(dev, M_DEVBUF);
break;
}
+ printf("%s: physical disk inserted in slot %d\n",
+ DEVNAME(sc), dev->slot);
+ mutex_exit(&sc->sc_devs_mtx);
break;
+
case MPII_EVENT_SAS_TOPO_PS_RC_MISSING:
- if (!(dev = mpii_find_dev(sc,
- le16toh(pe->dev_handle))))
+ /* defer to workqueue thread */
+ need_queue++;
+ break;
+ }
+ }
+
+ if (need_queue) {
+ bool start_wk;
+ mutex_enter(&sc->sc_evt_sas_mtx);
+ start_wk = (SIMPLEQ_FIRST(&sc->sc_evt_sas_queue) == 0);
+ SIMPLEQ_INSERT_TAIL(&sc->sc_evt_sas_queue, rcb, rcb_link);
+ if (start_wk) {
+ workqueue_enqueue(sc->sc_evt_sas_wq,
+ &sc->sc_evt_sas_work, NULL);
+ }
+ mutex_exit(&sc->sc_evt_sas_mtx);
+ } else
+ mpii_event_done(sc, rcb);
+}
+
+void
+mpii_event_sas_work(struct work *wq, void *xsc)
+{
+ struct mpii_softc *sc = xsc;
+ struct mpii_rcb *rcb, *next;
+ struct mpii_msg_event_reply *enp;
+ struct mpii_evt_sas_tcl *tcl;
+ struct mpii_evt_phy_entry *pe;
+ struct mpii_device *dev;
+ int i;
+
+ mutex_enter(&sc->sc_evt_sas_mtx);
+ next = SIMPLEQ_FIRST(&sc->sc_evt_sas_queue);
+ SIMPLEQ_INIT(&sc->sc_evt_sas_queue);
+ mutex_exit(&sc->sc_evt_sas_mtx);
+
+ while (next != NULL) {
+ rcb = next;
+ next = SIMPLEQ_NEXT(rcb, rcb_link);
+
+ enp = (struct mpii_msg_event_reply *)rcb->rcb_reply;
+ DNPRINTF(MPII_D_EVT, "%s: mpii_event_sas_work 0x%x\n",
+ DEVNAME(sc), le16toh(enp->event));
+ KASSERT(le16toh(enp->event) == MPII_EVENT_SAS_TOPOLOGY_CHANGE_LIST);
+ tcl = (struct mpii_evt_sas_tcl *)(enp + 1);
+ pe = (struct mpii_evt_phy_entry *)(tcl + 1);
+
+ for (i = 0; i < tcl->num_entries; i++, pe++) {
+ DNPRINTF(MPII_D_EVT, "%s: sas change %d stat %d h %d slot %d phy %d enc %d expand %d\n",
+ DEVNAME(sc), i, pe->phy_status,
+ le16toh(pe->dev_handle),
+ sc->sc_pd_id_start + tcl->start_phy_num + i,
+ tcl->start_phy_num + i, le16toh(tcl->enclosure_handle), le16toh(tcl->expander_handle));
+
+ switch (pe->phy_status & MPII_EVENT_SAS_TOPO_PS_RC_MASK) {
+ case MPII_EVENT_SAS_TOPO_PS_RC_ADDED:
+ /* already handled */
+ break;
+
+ case MPII_EVENT_SAS_TOPO_PS_RC_MISSING:
+ mutex_enter(&sc->sc_devs_mtx);
+ dev = mpii_find_dev(sc, le16toh(pe->dev_handle));
+ if (dev == NULL) {
+ mutex_exit(&sc->sc_devs_mtx);
+ break;
+ }
+
+ printf(
+ "%s: physical disk removed from slot %d\n",
+ DEVNAME(sc), dev->slot);
+ mpii_remove_dev(sc, dev);
+ mutex_exit(&sc->sc_devs_mtx);
+ mpii_sas_remove_device(sc, dev->dev_handle);
+ if (!ISSET(dev->flags, MPII_DF_HIDDEN)) {
+ scsipi_target_detach(&sc->sc_chan,
+ dev->slot, 0, DETACH_FORCE);
+ sysmon_envsys_sensor_detach(sc->sc_sme,
+ &sc->sc_sensors[dev->slot]);
+ }
+
+ free(dev, M_DEVBUF);
break;
- mpii_remove_dev(sc, dev);
-#if 0
- if (sc->sc_scsibus) {
- SET(dev->flags, MPII_DF_DETACH);
- scsi_activate(sc->sc_scsibus, dev->slot, -1,
- DVACT_DEACTIVATE);
- if (scsi_task(mpii_event_defer, sc,
- dev, 0) != 0)
- aprint_error_dev(sc->sc_dev,
- "unable to run device "
- "detachment routine\n");
}
-#else
- mpii_event_defer(sc, dev);
-#endif /* XXX */
- break;
}
+ mpii_event_done(sc, rcb);
+ }
+}
+
+void
+mpii_event_discovery(struct mpii_softc *sc, struct mpii_msg_event_reply *enp)
+{
+ struct mpii_evt_sas_discovery *esd =
+ (struct mpii_evt_sas_discovery *)(enp + 1);
+
+ if (esd->reason_code == MPII_EVENT_SAS_DISC_REASON_CODE_COMPLETED) {
+ if (esd->discovery_status != 0) {
+ printf("%s: sas discovery completed with status %#x\n",
+ DEVNAME(sc), esd->discovery_status);
+ }
+
}
}
-static void
+void
mpii_event_process(struct mpii_softc *sc, struct mpii_rcb *rcb)
{
struct mpii_msg_event_reply *enp;
@@ -1927,26 +2036,18 @@ mpii_event_process(struct mpii_softc *sc
enp = (struct mpii_msg_event_reply *)rcb->rcb_reply;
DNPRINTF(MPII_D_EVT, "%s: mpii_event_process: %#x\n", DEVNAME(sc),
- le32toh(enp->event));
+ le16toh(enp->event));
- switch (le32toh(enp->event)) {
+ switch (le16toh(enp->event)) {
case MPII_EVENT_EVENT_CHANGE:
/* should be properly ignored */
break;
- case MPII_EVENT_SAS_DISCOVERY: {
- struct mpii_evt_sas_discovery *esd =
- (struct mpii_evt_sas_discovery *)(enp + 1);
-
- if (esd->reason_code ==
- MPII_EVENT_SAS_DISC_REASON_CODE_COMPLETED &&
- esd->discovery_status != 0)
- printf("%s: sas discovery completed with status %#x\n",
- DEVNAME(sc), esd->discovery_status);
- }
+ case MPII_EVENT_SAS_DISCOVERY:
+ mpii_event_discovery(sc, enp);
break;
case MPII_EVENT_SAS_TOPOLOGY_CHANGE_LIST:
- mpii_event_sas(sc, enp);
- break;
+ mpii_event_sas(sc, rcb);
+ return;
case MPII_EVENT_SAS_DEVICE_STATUS_CHANGE:
break;
case MPII_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE:
@@ -1968,8 +2069,12 @@ mpii_event_process(struct mpii_softc *sc
if (cold)
break;
- if (!(dev = mpii_find_dev(sc, le16toh(evd->vol_dev_handle))))
+ mutex_enter(&sc->sc_devs_mtx);
+ dev = mpii_find_dev(sc, le16toh(evd->vol_dev_handle));
+ if (dev == NULL) {
+ mutex_exit(&sc->sc_devs_mtx);
break;
+ }
#if NBIO > 0
if (evd->reason_code == MPII_EVENT_IR_VOL_RC_STATE_CHANGED)
printf("%s: volume %d state changed from %s to %s\n",
@@ -1983,6 +2088,7 @@ mpii_event_process(struct mpii_softc *sc
printf("%s: started resync on a volume %d\n",
DEVNAME(sc), dev->slot - sc->sc_vd_id_low);
}
+ mutex_exit(&sc->sc_devs_mtx);
break;
case MPII_EVENT_IR_PHYSICAL_DISK:
break;
@@ -1994,56 +2100,48 @@ mpii_event_process(struct mpii_softc *sc
(struct mpii_evt_ir_status *)(enp + 1);
struct mpii_device *dev;
- if (!(dev = mpii_find_dev(sc, le16toh(evs->vol_dev_handle))))
- break;
- if (evs->operation == MPII_EVENT_IR_RAIDOP_RESYNC)
+ mutex_enter(&sc->sc_devs_mtx);
+ dev = mpii_find_dev(sc, le16toh(evs->vol_dev_handle));
+ if (dev != NULL &&
+ evs->operation == MPII_EVENT_IR_RAIDOP_RESYNC)
dev->percent = evs->percent;
+ mutex_exit(&sc->sc_devs_mtx);
break;
}
default:
DNPRINTF(MPII_D_EVT, "%s: unhandled event 0x%02x\n",
- DEVNAME(sc), le32toh(enp->event));
+ DEVNAME(sc), le16toh(enp->event));
}
- if (enp->ack_required)
- workqueue_enqueue(sc->sc_ssb_evt_ackwk, &rcb->u.rcb_wk, NULL);
- else
- mpii_push_reply(sc, rcb);
+ mpii_event_done(sc, rcb);
}
-static void
-mpii_event_defer(void *xsc, void *arg)
+void
+mpii_event_done(struct mpii_softc *sc, struct mpii_rcb *rcb)
{
- struct mpii_softc *sc = xsc;
- struct mpii_device *dev = arg;
+ struct mpii_msg_event_reply *enp = rcb->rcb_reply;
+ bool need_start;
- if (ISSET(dev->flags, MPII_DF_DETACH)) {
- mpii_sas_remove_device(sc, dev->dev_handle);
-#if 0
- if (!ISSET(dev->flags, MPII_DF_HIDDEN)) {
- scsi_detach_target(sc->sc_scsibus, dev->slot,
- DETACH_FORCE);
- }
-#endif /* XXX */
- free(dev, M_DEVBUF);
-
- } else if (ISSET(dev->flags, MPII_DF_ATTACH)) {
- CLR(dev->flags, MPII_DF_ATTACH);
-#if 0
- if (!ISSET(dev->flags, MPII_DF_HIDDEN))
- scsi_probe_target(sc->sc_scsibus, dev->slot);
-#endif /* XXX */
- }
+ if (enp->ack_required) {
+ mutex_enter(&sc->sc_evt_ack_mtx);
+ need_start = (SIMPLEQ_FIRST(&sc->sc_evt_ack_queue) == 0);
+ SIMPLEQ_INSERT_TAIL(&sc->sc_evt_ack_queue, rcb, rcb_link);
+ if (need_start)
+ workqueue_enqueue(sc->sc_evt_ack_wq,
+ &sc->sc_evt_ack_work, NULL);
+ mutex_exit(&sc->sc_evt_ack_mtx);
+ } else
+ mpii_push_reply(sc, rcb);
}
-static void
+void
mpii_sas_remove_device(struct mpii_softc *sc, u_int16_t handle)
{
- struct mpii_msg_scsi_task_request *stq;
+ struct mpii_msg_scsi_task_request *stq;
struct mpii_msg_sas_oper_request *soq;
struct mpii_ccb *ccb;
- ccb = mpii_get_ccb(sc, 0);
+ ccb = mpii_get_ccb(sc);
if (ccb == NULL)
return;
@@ -2063,7 +2161,7 @@ mpii_sas_remove_device(struct mpii_softc
ccb->ccb_rcb = NULL;
soq = ccb->ccb_cmd;
- bzero(soq, sizeof(*soq));
+ memset(soq, 0, sizeof(*soq));
soq->function = MPII_FUNCTION_SAS_IO_UNIT_CONTROL;
soq->operation = MPII_SAS_OP_REMOVE_DEVICE;
soq->dev_handle = htole16(handle);
@@ -2072,57 +2170,79 @@ mpii_sas_remove_device(struct mpii_softc
mpii_wait(sc, ccb);
if (ccb->ccb_rcb != NULL)
mpii_push_reply(sc, ccb->ccb_rcb);
+
+ mpii_put_ccb(sc, ccb);
}
-static int
-mpii_get_ioc_pg8(struct mpii_softc *sc)
+int
+mpii_board_info(struct mpii_softc *sc)
{
- struct mpii_cfg_hdr hdr;
- struct mpii_cfg_ioc_pg8 *page;
- size_t pagelen;
- u_int16_t flags;
- int pad = 0, rv = 0;
+ struct mpii_msg_iocfacts_request ifq;
+ struct mpii_msg_iocfacts_reply ifp;
+ struct mpii_cfg_manufacturing_pg0 mpg;
+ struct mpii_cfg_hdr hdr;
+
+ memset(&ifq, 0, sizeof(ifq));
+ memset(&ifp, 0, sizeof(ifp));
- DNPRINTF(MPII_D_RAID, "%s: mpii_get_ioc_pg8\n", DEVNAME(sc));
+ ifq.function = MPII_FUNCTION_IOC_FACTS;
- 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_handshake_send(sc, &ifq, dwordsof(ifq)) != 0) {
+ DNPRINTF(MPII_D_MISC, "%s: failed to request ioc facts\n",
+ DEVNAME(sc));
return (1);
}
- pagelen = hdr.page_length * 4; /* dwords to bytes */
-
- page = malloc(pagelen, M_TEMP, M_NOWAIT);
- if (page == NULL) {
- DNPRINTF(MPII_D_CFG, "%s: mpii_get_ioc_pg8 unable to allocate "
- "space for ioc config page 8\n", DEVNAME(sc));
+ if (mpii_handshake_recv(sc, &ifp, dwordsof(ifp)) != 0) {
+ DNPRINTF(MPII_D_MISC, "%s: failed to receive ioc facts\n",
+ DEVNAME(sc));
return (1);
}
- if (mpii_cfg_page(sc, 0, &hdr, 1, page, pagelen) != 0) {
- DNPRINTF(MPII_D_CFG, "%s: mpii_get_raid unable to fetch IOC "
- "page 8\n", DEVNAME(sc));
- rv = 1;
- goto out;
+ hdr.page_version = 0;
+ hdr.page_length = sizeof(mpg) / 4;
+ hdr.page_number = 0;
+ hdr.page_type = MPII_CONFIG_REQ_PAGE_TYPE_MANUFACTURING;
+ memset(&mpg, 0, sizeof(mpg));
+ if (mpii_req_cfg_page(sc, 0, MPII_PG_POLL, &hdr, 1, &mpg,
+ sizeof(mpg)) != 0) {
+ printf("%s: unable to fetch manufacturing page 0\n",
+ DEVNAME(sc));
+ return (EINVAL);
}
- DNPRINTF(MPII_D_CFG, "%s: numdevsperenclosure: 0x%02x\n", DEVNAME(sc),
- page->num_devs_per_enclosure);
- DNPRINTF(MPII_D_CFG, "%s: maxpersistententries: 0x%04x "
- "maxnumphysicalmappedids: 0x%04x\n", DEVNAME(sc),
- le16toh(page->max_persistent_entries),
- le16toh(page->max_num_physical_mapped_ids));
- DNPRINTF(MPII_D_CFG, "%s: flags: 0x%04x\n", DEVNAME(sc),
- le16toh(page->flags));
- DNPRINTF(MPII_D_CFG, "%s: irvolumemappingflags: 0x%04x\n",
- DEVNAME(sc), le16toh(page->ir_volume_mapping_flags));
+ printf("%s: %s, firmware %u.%u.%u.%u%s, MPI %u.%u\n", DEVNAME(sc),
+ mpg.board_name, ifp.fw_version_maj, ifp.fw_version_min,
+ ifp.fw_version_unit, ifp.fw_version_dev,
+ ISSET(sc->sc_flags, MPII_F_RAID) ? " IR" : "",
+ ifp.msg_version_maj, ifp.msg_version_min);
+
+ return (0);
+}
+
+int
+mpii_target_map(struct mpii_softc *sc)
+{
+ struct mpii_cfg_hdr hdr;
+ struct mpii_cfg_ioc_pg8 ipg;
+ int flags, pad = 0;
- if (page->flags & MPII_IOC_PG8_FLAGS_RESERVED_TARGETID_0)
+ hdr.page_version = 0;
+ hdr.page_length = sizeof(ipg) / 4;
+ hdr.page_number = 8;
+ hdr.page_type = MPII_CONFIG_REQ_PAGE_TYPE_IOC;
+ memset(&ipg, 0, sizeof(ipg));
+ if (mpii_req_cfg_page(sc, 0, MPII_PG_POLL, &hdr, 1, &ipg,
+ sizeof(ipg)) != 0) {
+ printf("%s: unable to fetch ioc page 8\n",
+ DEVNAME(sc));
+ return (EINVAL);
+ }
+
+ if (le16toh(ipg.flags) & MPII_IOC_PG8_FLAGS_RESERVED_TARGETID_0)
pad = 1;
- flags = page->ir_volume_mapping_flags &
+ flags = le16toh(ipg.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) {
@@ -2135,33 +2255,26 @@ mpii_get_ioc_pg8(struct mpii_softc *sc)
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_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);
-
- return(rv);
+ return (0);
}
-static int
+int
mpii_req_cfg_header(struct mpii_softc *sc, u_int8_t type, u_int8_t number,
u_int32_t address, int flags, void *p)
{
struct mpii_msg_config_request *cq;
struct mpii_msg_config_reply *cp;
- struct mpii_cfg_hdr *hdr = p;
- struct mpii_ccb *ccb;
- struct mpii_ecfg_hdr *ehdr = p;
- int etype = 0;
- int rv = 0;
+ struct mpii_ccb *ccb;
+ struct mpii_cfg_hdr *hdr = p;
+ struct mpii_ecfg_hdr *ehdr = p;
+ int etype = 0;
+ int rv = 0;
DNPRINTF(MPII_D_MISC, "%s: mpii_req_cfg_header type: %#x number: %x "
"address: 0x%08x flags: 0x%x\n", DEVNAME(sc), type, number,
address, flags);
- ccb = mpii_get_ccb(sc, ISSET(flags, MPII_PG_POLL) ? MPII_NOSLEEP : 0);
+ ccb = mpii_get_ccb(sc);
if (ccb == NULL) {
DNPRINTF(MPII_D_MISC, "%s: mpii_cfg_header ccb_get\n",
DEVNAME(sc));
@@ -2210,7 +2323,7 @@ mpii_req_cfg_header(struct mpii_softc *s
le16toh(cp->ext_page_length), cp->ext_page_type,
cp->msg_flags);
DNPRINTF(MPII_D_MISC, "%s: vp_id: 0x%02x vf_id: 0x%02x\n", DEVNAME(sc),
- cp->vp_id, cp->vf_id);
+ cp->vp_id, cp->vf_id);
DNPRINTF(MPII_D_MISC, "%s: ioc_status: 0x%04x\n", DEVNAME(sc),
le16toh(cp->ioc_status));
DNPRINTF(MPII_D_MISC, "%s: ioc_loginfo: 0x%08x\n", DEVNAME(sc),
@@ -2225,7 +2338,7 @@ mpii_req_cfg_header(struct mpii_softc *s
if (le16toh(cp->ioc_status) != MPII_IOCSTATUS_SUCCESS)
rv = 1;
else if (ISSET(flags, MPII_PG_EXTENDED)) {
- bzero(ehdr, sizeof(*ehdr));
+ memset(ehdr, 0, sizeof(*ehdr));
ehdr->page_version = cp->config_header.page_version;
ehdr->page_number = cp->config_header.page_number;
ehdr->page_type = cp->config_header.page_type;
@@ -2240,19 +2353,18 @@ mpii_req_cfg_header(struct mpii_softc *s
return (rv);
}
-static int
+int
mpii_req_cfg_page(struct mpii_softc *sc, u_int32_t address, int flags,
void *p, int read, void *page, size_t len)
{
struct mpii_msg_config_request *cq;
struct mpii_msg_config_reply *cp;
- struct mpii_cfg_hdr *hdr = p;
- struct mpii_ccb *ccb;
- struct mpii_ecfg_hdr *ehdr = p;
- u_int64_t dva;
- char *kva;
- int page_length;
- int rv = 0;
+ struct mpii_ccb *ccb;
+ struct mpii_cfg_hdr *hdr = p;
+ struct mpii_ecfg_hdr *ehdr = p;
+ uintptr_t kva;
+ int page_length;
+ int rv = 0;
DNPRINTF(MPII_D_MISC, "%s: mpii_cfg_page address: %d read: %d "
"type: %x\n", DEVNAME(sc), address, read, hdr->page_type);
@@ -2260,12 +2372,10 @@ mpii_req_cfg_page(struct mpii_softc *sc,
page_length = ISSET(flags, MPII_PG_EXTENDED) ?
le16toh(ehdr->ext_page_length) : hdr->page_length;
- if (len > MPII_REQUEST_SIZE - sizeof(struct mpii_msg_config_request) ||
- len < page_length * 4)
+ if (len > sc->sc_request_size - sizeof(*cq) || len < page_length * 4)
return (1);
- ccb = mpii_get_ccb(sc,
- ISSET(flags, MPII_PG_POLL) ? MPII_NOSLEEP : 0);
+ ccb = mpii_get_ccb(sc);
if (ccb == NULL) {
DNPRINTF(MPII_D_MISC, "%s: mpii_cfg_page ccb_get\n",
DEVNAME(sc));
@@ -2295,16 +2405,14 @@ mpii_req_cfg_page(struct mpii_softc *sc,
(read ? MPII_SGE_FL_DIR_IN : MPII_SGE_FL_DIR_OUT));
/* bounce the page via the request space to avoid more bus_dma games */
- dva = ccb->ccb_cmd_dva + sizeof(struct mpii_msg_config_request);
-
- cq->page_buffer.sg_hi_addr = htole32((u_int32_t)(dva >> 32));
- cq->page_buffer.sg_lo_addr = htole32((u_int32_t)dva);
+ mpii_dvatosge(&cq->page_buffer, ccb->ccb_cmd_dva +
+ sizeof(struct mpii_msg_config_request));
- kva = ccb->ccb_cmd;
+ kva = (uintptr_t)ccb->ccb_cmd;
kva += sizeof(struct mpii_msg_config_request);
if (!read)
- bcopy(page, kva, len);
+ memcpy((void *)kva, page, len);
ccb->ccb_done = mpii_empty_done;
if (ISSET(flags, MPII_PG_POLL)) {
@@ -2322,9 +2430,9 @@ mpii_req_cfg_page(struct mpii_softc *sc,
}
cp = ccb->ccb_rcb->rcb_reply;
- DNPRINTF(MPII_D_MISC, "%s: action: 0x%02x "
- "msg_length: %d function: 0x%02x\n", DEVNAME(sc), cp->action,
- cp->msg_length, cp->function);
+ DNPRINTF(MPII_D_MISC, "%s: action: 0x%02x msg_length: %d "
+ "function: 0x%02x\n", DEVNAME(sc), cp->action, cp->msg_length,
+ cp->function);
DNPRINTF(MPII_D_MISC, "%s: ext_page_length: %d ext_page_type: 0x%02x "
"msg_flags: 0x%02x\n", DEVNAME(sc),
le16toh(cp->ext_page_length), cp->ext_page_type,
@@ -2341,11 +2449,11 @@ mpii_req_cfg_page(struct mpii_softc *sc,
cp->config_header.page_length,
cp->config_header.page_number,
cp->config_header.page_type);
-
+
if (le16toh(cp->ioc_status) != MPII_IOCSTATUS_SUCCESS)
rv = 1;
else if (read)
- bcopy(kva, page, len);
+ memcpy(page, (void *)kva, len);
mpii_push_reply(sc, ccb->ccb_rcb);
mpii_put_ccb(sc, ccb);
@@ -2353,22 +2461,24 @@ mpii_req_cfg_page(struct mpii_softc *sc,
return (rv);
}
-static struct mpii_rcb *
+struct mpii_rcb *
mpii_reply(struct mpii_softc *sc, struct mpii_reply_descr *rdp)
{
struct mpii_rcb *rcb = NULL;
u_int32_t rfid;
+ KASSERT(mutex_owned(&sc->sc_rep_mtx));
DNPRINTF(MPII_D_INTR, "%s: mpii_reply\n", DEVNAME(sc));
if ((rdp->reply_flags & MPII_REPLY_DESCR_TYPE_MASK) ==
MPII_REPLY_DESCR_ADDRESS_REPLY) {
rfid = (le32toh(rdp->frame_addr) -
- (u_int32_t)MPII_DMA_DVA(sc->sc_replies)) / MPII_REPLY_SIZE;
+ (u_int32_t)MPII_DMA_DVA(sc->sc_replies)) /
+ sc->sc_reply_size;
bus_dmamap_sync(sc->sc_dmat,
- MPII_DMA_MAP(sc->sc_replies), MPII_REPLY_SIZE * rfid,
- MPII_REPLY_SIZE, BUS_DMASYNC_POSTREAD);
+ MPII_DMA_MAP(sc->sc_replies), sc->sc_reply_size * rfid,
+ sc->sc_reply_size, BUS_DMASYNC_POSTREAD);
rcb = &sc->sc_rcbs[rfid];
}
@@ -2382,7 +2492,7 @@ mpii_reply(struct mpii_softc *sc, struct
return (rcb);
}
-static struct mpii_dmamem *
+struct mpii_dmamem *
mpii_dmamem_alloc(struct mpii_softc *sc, size_t size)
{
struct mpii_dmamem *mdm;
@@ -2399,7 +2509,8 @@ mpii_dmamem_alloc(struct mpii_softc *sc,
goto mdmfree;
if (bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0, &mdm->mdm_seg,
- 1, &nsegs, BUS_DMA_NOWAIT) != 0) goto destroy;
+ 1, &nsegs, BUS_DMA_NOWAIT) != 0)
+ goto destroy;
if (bus_dmamem_map(sc->sc_dmat, &mdm->mdm_seg, nsegs, size,
&mdm->mdm_kva, BUS_DMA_NOWAIT) != 0)
@@ -2409,12 +2520,7 @@ mpii_dmamem_alloc(struct mpii_softc *sc,
NULL, BUS_DMA_NOWAIT) != 0)
goto unmap;
- DNPRINTF(MPII_D_MEM,
- " kva: %p dva: 0x%" PRIx64 " map: %p size: %" PRId64 "\n",
- mdm->mdm_kva, (uint64_t)mdm->mdm_map->dm_segs[0].ds_addr,
- mdm->mdm_map, (uint64_t)size);
-
- bzero(mdm->mdm_kva, size);
+ memset(mdm->mdm_kva, 0, size);
return (mdm);
@@ -2430,7 +2536,7 @@ mdmfree:
return (NULL);
}
-static void
+void
mpii_dmamem_free(struct mpii_softc *sc, struct mpii_dmamem *mdm)
{
DNPRINTF(MPII_D_MEM, "%s: mpii_dmamem_free %p\n", DEVNAME(sc), mdm);
@@ -2442,71 +2548,92 @@ mpii_dmamem_free(struct mpii_softc *sc,
free(mdm, M_DEVBUF);
}
-static int
-mpii_alloc_dev(struct mpii_softc *sc)
-{
- sc->sc_devs = malloc(sc->sc_max_devices *
- sizeof(struct mpii_device *), M_DEVBUF, M_NOWAIT | M_ZERO);
- if (sc->sc_devs == NULL)
- return (1);
- return (0);
-}
-
-static int
+int
mpii_insert_dev(struct mpii_softc *sc, struct mpii_device *dev)
{
+ int slot; /* initial hint */
- if (!dev || dev->slot < 0)
+ KASSERT(mutex_owned(&sc->sc_devs_mtx));
+ DNPRINTF(MPII_D_EVT, "%s: mpii_insert_dev wants slot %d\n",
+ DEVNAME(sc), dev->slot);
+ if (dev == NULL || dev->slot < 0)
return (1);
-
- int slot = dev->slot; /* initial hint */
+ slot = dev->slot;
while (slot < sc->sc_max_devices && sc->sc_devs[slot] != NULL)
slot++;
+
if (slot >= sc->sc_max_devices)
return (1);
+
+ DNPRINTF(MPII_D_EVT, "%s: mpii_insert_dev alloc slot %d\n",
+ DEVNAME(sc), slot);
+
dev->slot = slot;
sc->sc_devs[slot] = dev;
+
return (0);
}
-static int
+int
mpii_remove_dev(struct mpii_softc *sc, struct mpii_device *dev)
{
int i;
- if (!dev)
+ KASSERT(mutex_owned(&sc->sc_devs_mtx));
+ if (dev == NULL)
return (1);
- for (i = 0; i < sc->sc_max_devices; i++)
- if (sc->sc_devs[i] &&
- sc->sc_devs[i]->dev_handle == dev->dev_handle) {
+
+ for (i = 0; i < sc->sc_max_devices; i++) {
+ if (sc->sc_devs[i] == NULL)
+ continue;
+
+ if (sc->sc_devs[i]->dev_handle == dev->dev_handle) {
sc->sc_devs[i] = NULL;
return (0);
}
+ }
+
return (1);
}
-static struct mpii_device *
+struct mpii_device *
mpii_find_dev(struct mpii_softc *sc, u_int16_t handle)
{
int i;
+ KASSERT(mutex_owned(&sc->sc_devs_mtx));
- for (i = 0; i < sc->sc_max_devices; i++)
- if (sc->sc_devs[i] && sc->sc_devs[i]->dev_handle == handle)
+ for (i = 0; i < sc->sc_max_devices; i++) {
+ if (sc->sc_devs[i] == NULL)
+ continue;
+
+ if (sc->sc_devs[i]->dev_handle == handle)
return (sc->sc_devs[i]);
+ }
+
return (NULL);
}
-static int
+int
mpii_alloc_ccbs(struct mpii_softc *sc)
{
struct mpii_ccb *ccb;
u_int8_t *cmd;
int i;
+ char wqname[16];
SIMPLEQ_INIT(&sc->sc_ccb_free);
+ SIMPLEQ_INIT(&sc->sc_ccb_tmos);
+ mutex_init(&sc->sc_ccb_free_mtx, MUTEX_DEFAULT, IPL_BIO);
+ cv_init(&sc->sc_ccb_free_cv, "mpii_ccbs");
+ mutex_init(&sc->sc_ssb_tmomtx, MUTEX_DEFAULT, IPL_BIO);
+ snprintf(wqname, sizeof(wqname) - 1, "%sabrt", DEVNAME(sc));
+ workqueue_create(&sc->sc_ssb_tmowk, wqname, mpii_scsi_cmd_tmo_handler,
+ sc, PRI_BIO, IPL_BIO, WQ_MPSAFE);
+ if (sc->sc_ssb_tmowk == NULL)
+ return 1;
- sc->sc_ccbs = malloc(sizeof(*ccb) * (sc->sc_request_depth-1),
+ sc->sc_ccbs = malloc((sc->sc_max_cmds-1) * sizeof(*ccb),
M_DEVBUF, M_NOWAIT | M_ZERO);
if (sc->sc_ccbs == NULL) {
printf("%s: unable to allocate ccbs\n", DEVNAME(sc));
@@ -2514,43 +2641,44 @@ mpii_alloc_ccbs(struct mpii_softc *sc)
}
sc->sc_requests = mpii_dmamem_alloc(sc,
- MPII_REQUEST_SIZE * sc->sc_request_depth);
+ sc->sc_request_size * sc->sc_max_cmds);
if (sc->sc_requests == NULL) {
printf("%s: unable to allocate ccb dmamem\n", DEVNAME(sc));
goto free_ccbs;
}
cmd = MPII_DMA_KVA(sc->sc_requests);
- bzero(cmd, MPII_REQUEST_SIZE * sc->sc_request_depth);
/*
- * we have sc->sc_request_depth system request message
+ * we have sc->sc_max_cmds system request message
* frames, but smid zero cannot be used. so we then
- * have (sc->sc_request_depth - 1) number of ccbs
+ * have (sc->sc_max_cmds - 1) number of ccbs
*/
- for (i = 1; i < sc->sc_request_depth; i++) {
+ for (i = 1; i < sc->sc_max_cmds; i++) {
ccb = &sc->sc_ccbs[i - 1];
- if (bus_dmamap_create(sc->sc_dmat, MAXPHYS,
- sc->sc_max_sgl_len, MAXPHYS, 0,
- BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
+ if (bus_dmamap_create(sc->sc_dmat, MAXPHYS, sc->sc_max_sgl,
+ MAXPHYS, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
&ccb->ccb_dmamap) != 0) {
printf("%s: unable to create dma map\n", DEVNAME(sc));
goto free_maps;
}
ccb->ccb_sc = sc;
- ccb->ccb_smid = i;
- ccb->ccb_offset = MPII_REQUEST_SIZE * i;
+ mutex_init(&ccb->ccb_mtx, MUTEX_DEFAULT, IPL_BIO);
+ cv_init(&ccb->ccb_cv, "mpiiexec");
+
+ ccb->ccb_smid = htole16(i);
+ ccb->ccb_offset = sc->sc_request_size * i;
ccb->ccb_cmd = &cmd[ccb->ccb_offset];
ccb->ccb_cmd_dva = (u_int32_t)MPII_DMA_DVA(sc->sc_requests) +
ccb->ccb_offset;
DNPRINTF(MPII_D_CCB, "%s: mpii_alloc_ccbs(%d) ccb: %p map: %p "
- "sc: %p smid: %#x offs: %#" PRIx64 " cmd: %#" PRIx64 " dva: %#" PRIx64 "\n",
+ "sc: %p smid: %#x offs: %#lx cmd: %p dva: %#lx\n",
DEVNAME(sc), i, ccb, ccb->ccb_dmamap, ccb->ccb_sc,
- ccb->ccb_smid, (uint64_t)ccb->ccb_offset,
- (uint64_t)ccb->ccb_cmd, (uint64_t)ccb->ccb_cmd_dva);
+ ccb->ccb_smid, ccb->ccb_offset, ccb->ccb_cmd,
+ ccb->ccb_cmd_dva);
mpii_put_ccb(sc, ccb);
}
@@ -2558,7 +2686,7 @@ mpii_alloc_ccbs(struct mpii_softc *sc)
return (0);
free_maps:
- while ((ccb = mpii_get_ccb(sc, MPII_NOSLEEP)) != NULL)
+ while ((ccb = mpii_get_ccb(sc)) != NULL)
bus_dmamap_destroy(sc->sc_dmat, ccb->ccb_dmamap);
mpii_dmamem_free(sc, sc->sc_requests);
@@ -2568,38 +2696,31 @@ free_ccbs:
return (1);
}
-static void
+void
mpii_put_ccb(struct mpii_softc *sc, struct mpii_ccb *ccb)
{
- KASSERT(ccb->ccb_sc == sc);
DNPRINTF(MPII_D_CCB, "%s: mpii_put_ccb %p\n", DEVNAME(sc), ccb);
ccb->ccb_state = MPII_CCB_FREE;
ccb->ccb_cookie = NULL;
ccb->ccb_done = NULL;
ccb->ccb_rcb = NULL;
- bzero(ccb->ccb_cmd, MPII_REQUEST_SIZE);
+ memset(ccb->ccb_cmd, 0, sc->sc_request_size);
mutex_enter(&sc->sc_ccb_free_mtx);
- SIMPLEQ_INSERT_HEAD(&sc->sc_ccb_free, ccb, u.ccb_link);
- cv_signal(&sc->sc_ccb_free_cv);
+ SIMPLEQ_INSERT_HEAD(&sc->sc_ccb_free, ccb, ccb_link);
mutex_exit(&sc->sc_ccb_free_mtx);
}
-static struct mpii_ccb *
-mpii_get_ccb(struct mpii_softc *sc, int flags)
+struct mpii_ccb *
+mpii_get_ccb(struct mpii_softc *sc)
{
struct mpii_ccb *ccb;
mutex_enter(&sc->sc_ccb_free_mtx);
- while ((ccb = SIMPLEQ_FIRST(&sc->sc_ccb_free)) == NULL) {
- if (flags & MPII_NOSLEEP)
- break;
- cv_wait(&sc->sc_ccb_free_cv, &sc->sc_ccb_free_mtx);
- }
-
+ ccb = SIMPLEQ_FIRST(&sc->sc_ccb_free);
if (ccb != NULL) {
- SIMPLEQ_REMOVE_HEAD(&sc->sc_ccb_free, u.ccb_link);
+ SIMPLEQ_REMOVE_HEAD(&sc->sc_ccb_free, ccb_link);
ccb->ccb_state = MPII_CCB_READY;
KASSERT(ccb->ccb_sc == sc);
}
@@ -2610,7 +2731,7 @@ mpii_get_ccb(struct mpii_softc *sc, int
return (ccb);
}
-static int
+int
mpii_alloc_replies(struct mpii_softc *sc)
{
DNPRINTF(MPII_D_MISC, "%s: mpii_alloc_replies\n", DEVNAME(sc));
@@ -2620,7 +2741,7 @@ mpii_alloc_replies(struct mpii_softc *sc
if (sc->sc_rcbs == NULL)
return (1);
- sc->sc_replies = mpii_dmamem_alloc(sc, MPII_REPLY_SIZE *
+ sc->sc_replies = mpii_dmamem_alloc(sc, sc->sc_reply_size *
sc->sc_num_reply_frames);
if (sc->sc_replies == NULL) {
free(sc->sc_rcbs, M_DEVBUF);
@@ -2630,39 +2751,50 @@ mpii_alloc_replies(struct mpii_softc *sc
return (0);
}
-static void
+void
mpii_push_replies(struct mpii_softc *sc)
{
struct mpii_rcb *rcb;
- char *kva = MPII_DMA_KVA(sc->sc_replies);
+ uintptr_t kva = (uintptr_t)MPII_DMA_KVA(sc->sc_replies);
int i;
bus_dmamap_sync(sc->sc_dmat, MPII_DMA_MAP(sc->sc_replies),
- 0, MPII_REPLY_SIZE * sc->sc_num_reply_frames, BUS_DMASYNC_PREREAD);
+ 0, sc->sc_reply_size * sc->sc_num_reply_frames,
+ BUS_DMASYNC_PREREAD);
for (i = 0; i < sc->sc_num_reply_frames; i++) {
rcb = &sc->sc_rcbs[i];
- rcb->rcb_reply = kva + MPII_REPLY_SIZE * i;
+ rcb->rcb_reply = (void *)(kva + sc->sc_reply_size * i);
rcb->rcb_reply_dva = (u_int32_t)MPII_DMA_DVA(sc->sc_replies) +
- MPII_REPLY_SIZE * i;
+ sc->sc_reply_size * i;
mpii_push_reply(sc, rcb);
}
}
-static void
+void
mpii_start(struct mpii_softc *sc, struct mpii_ccb *ccb)
{
struct mpii_request_header *rhp;
struct mpii_request_descr descr;
- u_int32_t *rdp = (u_int32_t *)&descr;
+#if defined(__LP64__) && 0
+ u_long *rdp = (u_long *)&descr;
+#else
+ u_int32_t *rdp = (u_int32_t *)&descr;
+#endif
+
+ DNPRINTF(MPII_D_RW, "%s: mpii_start %#lx\n", DEVNAME(sc),
+ ccb->ccb_cmd_dva);
- DNPRINTF(MPII_D_RW, "%s: mpii_start %#" PRIx64 "\n", DEVNAME(sc),
- (uint64_t)ccb->ccb_cmd_dva);
+ bus_dmamap_sync(sc->sc_dmat, MPII_DMA_MAP(sc->sc_requests),
+ ccb->ccb_offset, sc->sc_request_size,
+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+
+ ccb->ccb_state = MPII_CCB_QUEUED;
rhp = ccb->ccb_cmd;
- bzero(&descr, sizeof(descr));
+ memset(&descr, 0, sizeof(descr));
switch (rhp->function) {
case MPII_FUNCTION_SCSI_IO_REQUEST:
@@ -2677,34 +2809,42 @@ mpii_start(struct mpii_softc *sc, struct
}
descr.vf_id = sc->sc_vf_id;
- descr.smid = htole16(ccb->ccb_smid);
-
- bus_dmamap_sync(sc->sc_dmat, MPII_DMA_MAP(sc->sc_requests),
- ccb->ccb_offset, MPII_REQUEST_SIZE,
- BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
-
- ccb->ccb_state = MPII_CCB_QUEUED;
+ descr.smid = ccb->ccb_smid;
+#if defined(__LP64__) && 0
+ DNPRINTF(MPII_D_RW, "%s: MPII_REQ_DESCR_POST_LOW (0x%08x) write "
+ "0x%08lx\n", DEVNAME(sc), MPII_REQ_DESCR_POST_LOW, *rdp);
+ bus_space_write_raw_8(sc->sc_iot, sc->sc_ioh,
+ MPII_REQ_DESCR_POST_LOW, *rdp);
+#else
DNPRINTF(MPII_D_RW, "%s: MPII_REQ_DESCR_POST_LOW (0x%08x) write "
- "0x%08x\n", DEVNAME(sc), MPII_REQ_DESCR_POST_LOW, *rdp);
+ "0x%04x\n", DEVNAME(sc), MPII_REQ_DESCR_POST_LOW, *rdp);
DNPRINTF(MPII_D_RW, "%s: MPII_REQ_DESCR_POST_HIGH (0x%08x) write "
- "0x%08x\n", DEVNAME(sc), MPII_REQ_DESCR_POST_HIGH, *(rdp+1));
+ "0x%04x\n", DEVNAME(sc), MPII_REQ_DESCR_POST_HIGH, *(rdp+1));
mutex_enter(&sc->sc_req_mtx);
- mpii_write(sc, MPII_REQ_DESCR_POST_LOW, htole32(*rdp));
- mpii_write(sc, MPII_REQ_DESCR_POST_HIGH, htole32(*(rdp+1)));
+ bus_space_write_4(sc->sc_iot, sc->sc_ioh,
+ MPII_REQ_DESCR_POST_LOW, rdp[0]);
+ bus_space_barrier(sc->sc_iot, sc->sc_ioh,
+ MPII_REQ_DESCR_POST_LOW, 8, BUS_SPACE_BARRIER_WRITE);
+
+ bus_space_write_4(sc->sc_iot, sc->sc_ioh,
+ MPII_REQ_DESCR_POST_HIGH, rdp[1]);
+ bus_space_barrier(sc->sc_iot, sc->sc_ioh,
+ MPII_REQ_DESCR_POST_LOW, 8, BUS_SPACE_BARRIER_WRITE);
mutex_exit(&sc->sc_req_mtx);
+#endif
}
-static int
+int
mpii_poll(struct mpii_softc *sc, struct mpii_ccb *ccb)
{
void (*done)(struct mpii_ccb *);
void *cookie;
int rv = 1;
- DNPRINTF(MPII_D_INTR, "%s: mpii_complete\n", DEVNAME(sc));
+ DNPRINTF(MPII_D_INTR, "%s: mpii_poll\n", DEVNAME(sc));
done = ccb->ccb_done;
cookie = ccb->ccb_cookie;
@@ -2728,7 +2868,7 @@ mpii_poll(struct mpii_softc *sc, struct
return (0);
}
-static void
+void
mpii_poll_done(struct mpii_ccb *ccb)
{
int *rv = ccb->ccb_cookie;
@@ -2736,55 +2876,41 @@ mpii_poll_done(struct mpii_ccb *ccb)
*rv = 0;
}
-static int
+int
mpii_alloc_queues(struct mpii_softc *sc)
{
- u_int32_t *kva;
- u_int64_t *kva64;
+ u_int32_t *rfp;
int i;
-
+
DNPRINTF(MPII_D_MISC, "%s: mpii_alloc_queues\n", DEVNAME(sc));
+ mutex_init(&sc->sc_reply_free_mtx, MUTEX_DEFAULT, IPL_BIO);
sc->sc_reply_freeq = mpii_dmamem_alloc(sc,
- sc->sc_reply_free_qdepth * 4);
+ sc->sc_reply_free_qdepth * sizeof(*rfp));
if (sc->sc_reply_freeq == NULL)
return (1);
-
- kva = MPII_DMA_KVA(sc->sc_reply_freeq);
+ rfp = MPII_DMA_KVA(sc->sc_reply_freeq);
for (i = 0; i < sc->sc_num_reply_frames; i++) {
- kva[i] = (u_int32_t)MPII_DMA_DVA(sc->sc_replies) +
- MPII_REPLY_SIZE * i;
-
- DNPRINTF(MPII_D_MISC, "%s: %d: %p = 0x%08x\n",
- DEVNAME(sc), i,
- &kva[i], (u_int)MPII_DMA_DVA(sc->sc_replies) +
- MPII_REPLY_SIZE * i);
+ rfp[i] = (u_int32_t)MPII_DMA_DVA(sc->sc_replies) +
+ sc->sc_reply_size * i;
}
- sc->sc_reply_postq =
- mpii_dmamem_alloc(sc, sc->sc_reply_post_qdepth * 8);
+ sc->sc_reply_postq = mpii_dmamem_alloc(sc,
+ sc->sc_reply_post_qdepth * sizeof(struct mpii_reply_descr));
if (sc->sc_reply_postq == NULL)
goto free_reply_freeq;
sc->sc_reply_postq_kva = MPII_DMA_KVA(sc->sc_reply_postq);
-
- DNPRINTF(MPII_D_MISC, "%s: populating reply post descriptor queue\n",
- DEVNAME(sc));
- kva64 = (u_int64_t *)MPII_DMA_KVA(sc->sc_reply_postq);
- for (i = 0; i < sc->sc_reply_post_qdepth; i++) {
- kva64[i] = 0xffffffffffffffffllu;
- DNPRINTF(MPII_D_MISC, "%s: %d: %p = 0x%" PRIx64 "\n",
- DEVNAME(sc), i, &kva64[i], kva64[i]);
- }
+ memset(sc->sc_reply_postq_kva, 0xff, sc->sc_reply_post_qdepth *
+ sizeof(struct mpii_reply_descr));
return (0);
free_reply_freeq:
-
mpii_dmamem_free(sc, sc->sc_reply_freeq);
return (1);
}
-static void
+void
mpii_init_queues(struct mpii_softc *sc)
{
DNPRINTF(MPII_D_MISC, "%s: mpii_init_queues\n", DEVNAME(sc));
@@ -2795,10 +2921,9 @@ mpii_init_queues(struct mpii_softc *sc)
mpii_write_reply_post(sc, sc->sc_reply_post_host_index);
}
-static void
+void
mpii_wait(struct mpii_softc *sc, struct mpii_ccb *ccb)
{
- struct mpii_ccb_wait mpii_ccb_wait;
void (*done)(struct mpii_ccb *);
void *cookie;
@@ -2806,52 +2931,31 @@ mpii_wait(struct mpii_softc *sc, struct
cookie = ccb->ccb_cookie;
ccb->ccb_done = mpii_wait_done;
- ccb->ccb_cookie = &mpii_ccb_wait;
-
- mutex_init(&mpii_ccb_wait.mpii_ccbw_mtx, MUTEX_DEFAULT, IPL_BIO);
- cv_init(&mpii_ccb_wait.mpii_ccbw_cv, "mpii_wait");
+ ccb->ccb_cookie = ccb;
/* XXX this will wait forever for the ccb to complete */
mpii_start(sc, ccb);
- mutex_enter(&mpii_ccb_wait.mpii_ccbw_mtx);
- while (ccb->ccb_cookie != NULL) {
- cv_wait(&mpii_ccb_wait.mpii_ccbw_cv,
- &mpii_ccb_wait.mpii_ccbw_mtx);
- }
- mutex_exit(&mpii_ccb_wait.mpii_ccbw_mtx);
- mutex_destroy(&mpii_ccb_wait.mpii_ccbw_mtx);
- cv_destroy(&mpii_ccb_wait.mpii_ccbw_cv);
+ mutex_enter(&ccb->ccb_mtx);
+ while (ccb->ccb_cookie != NULL)
+ cv_wait(&ccb->ccb_cv, &ccb->ccb_mtx);
+ mutex_exit(&ccb->ccb_mtx);
ccb->ccb_cookie = cookie;
done(ccb);
}
-static void
+void
mpii_wait_done(struct mpii_ccb *ccb)
{
- struct mpii_ccb_wait *mpii_ccb_waitp = ccb->ccb_cookie;
-
- mutex_enter(&mpii_ccb_waitp->mpii_ccbw_mtx);
+ mutex_enter(&ccb->ccb_mtx);
ccb->ccb_cookie = NULL;
- cv_signal(&mpii_ccb_waitp->mpii_ccbw_cv);
- mutex_exit(&mpii_ccb_waitp->mpii_ccbw_mtx);
-}
-
-static void
-mpii_minphys(struct buf *bp)
-{
- DNPRINTF(MPII_D_MISC, "mpii_minphys: %d\n", bp->b_bcount);
-
- /* XXX currently using MPII_MAXFER = MAXPHYS */
- if (bp->b_bcount > MPII_MAXFER) {
- bp->b_bcount = MPII_MAXFER;
- minphys(bp);
- }
+ cv_signal(&ccb->ccb_cv);
+ mutex_exit(&ccb->ccb_mtx);
}
-static void
+void
mpii_scsipi_request(struct scsipi_channel *chan, scsipi_adapter_req_t req,
void *arg)
{
@@ -2860,27 +2964,27 @@ mpii_scsipi_request(struct scsipi_channe
struct scsipi_adapter *adapt = chan->chan_adapter;
struct mpii_softc *sc = device_private(adapt->adapt_dev);
struct mpii_ccb *ccb;
- struct mpii_ccb_bundle *mcb;
struct mpii_msg_scsi_io *io;
struct mpii_device *dev;
- int target;
- int timeout;
+ int target, timeout, ret;
+ u_int16_t dev_handle;
DNPRINTF(MPII_D_CMD, "%s: mpii_scsipi_request\n", DEVNAME(sc));
+
switch (req) {
case ADAPTER_REQ_GROW_RESOURCES:
- /* Not supported. */
+ /* Not supported. */
return;
case ADAPTER_REQ_SET_XFER_MODE:
{
struct scsipi_xfer_mode *xm = arg;
xm->xm_mode = PERIPH_CAP_TQING;
- xm->xm_period = 0;
- xm->xm_offset = 0;
+ xm->xm_period = 0;
+ xm->xm_offset = 0;
scsipi_async_event(&sc->sc_chan, ASYNC_EVENT_XFER_MODE, xm);
return;
}
- case ADAPTER_REQ_RUN_XFER:
+ case ADAPTER_REQ_RUN_XFER:
break;
}
@@ -2889,9 +2993,9 @@ mpii_scsipi_request(struct scsipi_channe
target = periph->periph_target;
if (xs->cmdlen > MPII_CDB_LEN) {
- DNPRINTF(MPII_D_CMD, "%s: CBD too big %d\n",
+ DNPRINTF(MPII_D_CMD, "%s: CDB too big %d\n",
DEVNAME(sc), xs->cmdlen);
- bzero(&xs->sense, sizeof(xs->sense));
+ memset(&xs->sense, 0, sizeof(xs->sense));
xs->sense.scsi_sense.response_code =
SSD_RCODE_VALID | SSD_RCODE_CURRENT;
xs->sense.scsi_sense.flags = SKEY_ILLEGAL_REQUEST;
@@ -2901,36 +3005,38 @@ mpii_scsipi_request(struct scsipi_channe
return;
}
+ mutex_enter(&sc->sc_devs_mtx);
if ((dev = sc->sc_devs[target]) == NULL) {
+ mutex_exit(&sc->sc_devs_mtx);
/* device no longer exists */
xs->error = XS_SELTIMEOUT;
scsipi_done(xs);
return;
}
+ dev_handle = dev->dev_handle;
+ mutex_exit(&sc->sc_devs_mtx);
- ccb = mpii_get_ccb(sc, MPII_NOSLEEP);
+ ccb = mpii_get_ccb(sc);
if (ccb == NULL) {
xs->error = XS_RESOURCE_SHORTAGE;
scsipi_done(xs);
return;
}
-
DNPRINTF(MPII_D_CMD, "%s: ccb_smid: %d xs->xs_control: 0x%x\n",
DEVNAME(sc), ccb->ccb_smid, xs->xs_control);
ccb->ccb_cookie = xs;
ccb->ccb_done = mpii_scsi_cmd_done;
- ccb->ccb_dev_handle = dev->dev_handle;
-
- mcb = ccb->ccb_cmd;
- io = &mcb->mcb_io;
+ ccb->ccb_dev_handle = dev_handle;
+ io = ccb->ccb_cmd;
+ memset(io, 0, sizeof(*io));
io->function = MPII_FUNCTION_SCSI_IO_REQUEST;
io->sense_buffer_length = sizeof(xs->sense);
- io->sgl_offset0 = 24; /* XXX fix this */
+ io->sgl_offset0 = sizeof(struct mpii_msg_scsi_io) / 4;
io->io_flags = htole16(xs->cmdlen);
io->dev_handle = htole16(ccb->ccb_dev_handle);
- io->lun[0] = htobe16(periph->periph_lun);
+ io->lun[0] = htole16(periph->periph_lun);
switch (xs->xs_control & (XS_CTL_DATA_IN | XS_CTL_DATA_OUT)) {
case XS_CTL_DATA_IN:
@@ -2941,6 +3047,7 @@ mpii_scsipi_request(struct scsipi_channe
break;
default:
io->direction = MPII_SCSIIO_DIR_NONE;
+ break;
}
io->tagging = MPII_SCSIIO_ATTR_SIMPLE_Q;
@@ -2949,95 +3056,94 @@ mpii_scsipi_request(struct scsipi_channe
io->data_length = htole32(xs->datalen);
+ /* sense data is at the end of a request */
io->sense_buffer_low_address = htole32(ccb->ccb_cmd_dva +
- ((u_int8_t *)&mcb->mcb_sense - (u_int8_t *)mcb));
+ sc->sc_request_size - sizeof(struct scsi_sense_data));
+
+ if (ISSET(sc->sc_flags, MPII_F_SAS3))
+ ret = mpii_load_xs_sas3(ccb);
+ else
+ ret = mpii_load_xs(ccb);
- if (mpii_load_xs(ccb) != 0) {
+ if (ret != 0) {
xs->error = XS_DRIVER_STUFFUP;
- mpii_put_ccb(sc, ccb);
- scsipi_done(xs);
- return;
+ goto done;
}
- DNPRINTF(MPII_D_CMD, "%s: sizeof(mpii_msg_scsi_io): %ld "
- "sizeof(mpii_ccb_bundle): %ld sge offset: 0x%02lx\n",
- DEVNAME(sc), sizeof(struct mpii_msg_scsi_io),
- sizeof(struct mpii_ccb_bundle),
- (u_int8_t *)&mcb->mcb_sgl[0] - (u_int8_t *)mcb);
-
- DNPRINTF(MPII_D_CMD, "%s sgl[0]: 0x%04x 0%04x 0x%04x\n",
- DEVNAME(sc), mcb->mcb_sgl[0].sg_hdr, mcb->mcb_sgl[0].sg_lo_addr,
- mcb->mcb_sgl[0].sg_hi_addr);
-
- DNPRINTF(MPII_D_CMD, "%s: Offset0: 0x%02x\n", DEVNAME(sc),
- io->sgl_offset0);
-
if (xs->xs_control & XS_CTL_POLL) {
if (mpii_poll(sc, ccb) != 0) {
xs->error = XS_DRIVER_STUFFUP;
- mpii_put_ccb(sc, ccb);
- scsipi_done(xs);
+ goto done;
}
return;
}
- timeout = mstohz(xs->timeout);
+ timeout = mstohz(xs->timeout);
if (timeout == 0)
timeout = 1;
callout_reset(&xs->xs_callout, timeout, mpii_scsi_cmd_tmo, ccb);
-
- DNPRINTF(MPII_D_CMD, "%s: mpii_scsipi_request(): opcode: %02x "
- "datalen: %d\n", DEVNAME(sc), xs->cmd->opcode, xs->datalen);
-
mpii_start(sc, ccb);
+ return;
+done:
+ mpii_put_ccb(sc, ccb);
+ scsipi_done(xs);
}
-static void
+void
mpii_scsi_cmd_tmo(void *xccb)
{
struct mpii_ccb *ccb = xccb;
struct mpii_softc *sc = ccb->ccb_sc;
+ bool start_work;
printf("%s: mpii_scsi_cmd_tmo\n", DEVNAME(sc));
- mutex_enter(&sc->sc_ccb_mtx);
if (ccb->ccb_state == MPII_CCB_QUEUED) {
+ mutex_enter(&sc->sc_ssb_tmomtx);
+ start_work = (SIMPLEQ_FIRST(&sc->sc_ccb_tmos) == 0);
ccb->ccb_state = MPII_CCB_TIMEOUT;
- workqueue_enqueue(sc->sc_ssb_tmowk, &ccb->u.ccb_wk, NULL);
+ SIMPLEQ_INSERT_HEAD(&sc->sc_ccb_tmos, ccb, ccb_link);
+ if (start_work) {
+ workqueue_enqueue(sc->sc_ssb_tmowk,
+ &sc->sc_ssb_tmowork, NULL);
+ }
+ mutex_exit(&sc->sc_ssb_tmomtx);
}
- mutex_exit(&sc->sc_ccb_mtx);
}
-static void
+void
mpii_scsi_cmd_tmo_handler(struct work *wk, void *cookie)
{
struct mpii_softc *sc = cookie;
- struct mpii_ccb *tccb;
+ struct mpii_ccb *next;
struct mpii_ccb *ccb;
+ struct mpii_ccb *tccb;
struct mpii_msg_scsi_task_request *stq;
- ccb = (void *)wk;
- tccb = mpii_get_ccb(sc, 0);
+ mutex_enter(&sc->sc_ssb_tmomtx);
+ next = SIMPLEQ_FIRST(&sc->sc_ccb_tmos);
+ SIMPLEQ_INIT(&sc->sc_ccb_tmos);
+ mutex_exit(&sc->sc_ssb_tmomtx);
+
+ while (next != NULL) {
+ ccb = next;
+ next = SIMPLEQ_NEXT(ccb, ccb_link);
+ if (ccb->ccb_state != MPII_CCB_TIMEOUT)
+ continue;
+ tccb = mpii_get_ccb(sc);
+ stq = tccb->ccb_cmd;
+ stq->function = MPII_FUNCTION_SCSI_TASK_MGMT;
+ stq->task_type = MPII_SCSI_TASK_TARGET_RESET;
+ stq->dev_handle = htole16(ccb->ccb_dev_handle);
- mutex_enter(&sc->sc_ccb_mtx);
- if (ccb->ccb_state != MPII_CCB_TIMEOUT) {
- mpii_put_ccb(sc, tccb);
+ tccb->ccb_done = mpii_scsi_cmd_tmo_done;
+ mpii_wait(sc, tccb);
}
- /* should remove any other ccbs for the same dev handle */
- mutex_exit(&sc->sc_ccb_mtx);
-
- stq = tccb->ccb_cmd;
- stq->function = MPII_FUNCTION_SCSI_TASK_MGMT;
- stq->task_type = MPII_SCSI_TASK_TARGET_RESET;
- stq->dev_handle = htole16(ccb->ccb_dev_handle);
-
- tccb->ccb_done = mpii_scsi_cmd_tmo_done;
- mpii_start(sc, tccb);
}
-static void
+void
mpii_scsi_cmd_tmo_done(struct mpii_ccb *tccb)
{
- mpii_put_ccb(tccb->ccb_sc, tccb);
+ mpii_put_ccb(tccb->ccb_sc, tccb);
}
static u_int8_t
@@ -3047,40 +3153,40 @@ map_scsi_status(u_int8_t mpii_scsi_statu
switch (mpii_scsi_status)
{
- case MPII_SCSIIO_ERR_STATUS_SUCCESS:
+ case MPII_SCSIIO_STATUS_GOOD:
scsi_status = SCSI_OK;
break;
- case MPII_SCSIIO_ERR_STATUS_CHECK_COND:
+ case MPII_SCSIIO_STATUS_CHECK_COND:
scsi_status = SCSI_CHECK;
break;
- case MPII_SCSIIO_ERR_STATUS_BUSY:
+ case MPII_SCSIIO_STATUS_BUSY:
scsi_status = SCSI_BUSY;
break;
- case MPII_SCSIIO_ERR_STATUS_INTERMEDIATE:
+ case MPII_SCSIIO_STATUS_INTERMEDIATE:
scsi_status = SCSI_INTERM;
break;
- case MPII_SCSIIO_ERR_STATUS_INTERMEDIATE_CONDMET:
+ case MPII_SCSIIO_STATUS_INTERMEDIATE_CONDMET:
scsi_status = SCSI_INTERM;
break;
- case MPII_SCSIIO_ERR_STATUS_RESERVATION_CONFLICT:
+ case MPII_SCSIIO_STATUS_RESERVATION_CONFLICT:
scsi_status = SCSI_RESV_CONFLICT;
break;
- case MPII_SCSIIO_ERR_STATUS_CMD_TERM:
- case MPII_SCSIIO_ERR_STATUS_TASK_ABORTED:
+ case MPII_SCSIIO_STATUS_CMD_TERM:
+ case MPII_SCSIIO_STATUS_TASK_ABORTED:
scsi_status = SCSI_TERMINATED;
break;
- case MPII_SCSIIO_ERR_STATUS_TASK_SET_FULL:
+ case MPII_SCSIIO_STATUS_TASK_SET_FULL:
scsi_status = SCSI_QUEUE_FULL;
break;
- case MPII_SCSIIO_ERR_STATUS_ACA_ACTIVE:
+ case MPII_SCSIIO_STATUS_ACA_ACTIVE:
scsi_status = SCSI_ACA_ACTIVE;
break;
@@ -3093,22 +3199,20 @@ map_scsi_status(u_int8_t mpii_scsi_statu
return scsi_status;
}
-static void
+void
mpii_scsi_cmd_done(struct mpii_ccb *ccb)
{
struct mpii_msg_scsi_io_error *sie;
struct mpii_softc *sc = ccb->ccb_sc;
struct scsipi_xfer *xs = ccb->ccb_cookie;
- struct mpii_ccb_bundle *mcb = ccb->ccb_cmd;
+ struct scsi_sense_data *sense;
bus_dmamap_t dmap = ccb->ccb_dmamap;
- bool timeout = 0;
+ bool timeout = 1;
callout_stop(&xs->xs_callout);
- mutex_enter(&sc->sc_ccb_mtx);
if (ccb->ccb_state == MPII_CCB_TIMEOUT)
timeout = 1;
ccb->ccb_state = MPII_CCB_READY;
- mutex_exit(&sc->sc_ccb_mtx);
if (xs->datalen != 0) {
bus_dmamap_sync(sc->sc_dmat, dmap, 0, dmap->dm_mapsize,
@@ -3124,15 +3228,13 @@ mpii_scsi_cmd_done(struct mpii_ccb *ccb)
if (ccb->ccb_rcb == NULL) {
/* no scsi error, we're ok so drop out early */
xs->status = SCSI_OK;
- mpii_put_ccb(sc, ccb);
- scsipi_done(xs);
- return;
+ goto done;
}
sie = ccb->ccb_rcb->rcb_reply;
DNPRINTF(MPII_D_CMD, "%s: mpii_scsi_cmd_done xs cmd: 0x%02x len: %d "
- "xs_control 0x%x\n", DEVNAME(sc), xs->cmd->opcode, xs->datalen,
+ "flags 0x%x\n", DEVNAME(sc), xs->cmd->opcode, xs->datalen,
xs->xs_control);
DNPRINTF(MPII_D_CMD, "%s: dev_handle: %d msg_length: %d "
"function: 0x%02x\n", DEVNAME(sc), le16toh(sie->dev_handle),
@@ -3159,14 +3261,12 @@ mpii_scsi_cmd_done(struct mpii_ccb *ccb)
switch (le16toh(sie->ioc_status) & MPII_IOCSTATUS_MASK) {
case MPII_IOCSTATUS_SCSI_DATA_UNDERRUN:
- switch (sie->scsi_status) {
- case MPII_SCSIIO_ERR_STATUS_CHECK_COND:
+ switch(sie->scsi_status) {
+ case MPII_SCSIIO_STATUS_CHECK_COND:
xs->error = XS_SENSE;
- /*FALLTHROUGH*/
- case MPII_SCSIIO_ERR_STATUS_SUCCESS:
+ case MPII_SCSIIO_STATUS_GOOD:
xs->resid = xs->datalen - le32toh(sie->transfer_count);
break;
-
default:
xs->error = XS_DRIVER_STUFFUP;
break;
@@ -3176,22 +3276,15 @@ mpii_scsi_cmd_done(struct mpii_ccb *ccb)
case MPII_IOCSTATUS_SUCCESS:
case MPII_IOCSTATUS_SCSI_RECOVERED_ERROR:
switch (sie->scsi_status) {
- case MPII_SCSIIO_ERR_STATUS_SUCCESS:
- /*
- * xs->resid = 0; - already set above
- *
- * XXX: check whether UNDERUN strategy
- * would be appropriate here too.
- * that would allow joining these cases.
- */
+ case MPII_SCSIIO_STATUS_GOOD:
break;
- case MPII_SCSIIO_ERR_STATUS_CHECK_COND:
+ case MPII_SCSIIO_STATUS_CHECK_COND:
xs->error = XS_SENSE;
break;
-
- case MPII_SCSIIO_ERR_STATUS_BUSY:
- case MPII_SCSIIO_ERR_STATUS_TASK_SET_FULL:
+
+ case MPII_SCSIIO_STATUS_BUSY:
+ case MPII_SCSIIO_STATUS_TASK_SET_FULL:
xs->error = XS_BUSY;
break;
@@ -3220,26 +3313,56 @@ mpii_scsi_cmd_done(struct mpii_ccb *ccb)
break;
}
- if (sie->scsi_state & MPII_SCSIIO_ERR_STATE_AUTOSENSE_VALID)
- memcpy(&xs->sense, &mcb->mcb_sense, sizeof(xs->sense));
+ sense = (struct scsi_sense_data *)((uintptr_t)ccb->ccb_cmd +
+ sc->sc_request_size - sizeof(*sense));
+ if (sie->scsi_state & MPII_SCSIIO_STATE_AUTOSENSE_VALID)
+ memcpy(&xs->sense, sense, sizeof(xs->sense));
DNPRINTF(MPII_D_CMD, "%s: xs err: %d status: %#x\n", DEVNAME(sc),
xs->error, xs->status);
mpii_push_reply(sc, ccb->ccb_rcb);
+done:
mpii_put_ccb(sc, ccb);
scsipi_done(xs);
}
#if 0
-static int
+int
+mpii_scsi_ioctl(struct scsi_link *link, u_long cmd, void *addr, int flag)
+{
+ struct mpii_softc *sc = (struct mpii_softc *)link->adapter_softc;
+ struct mpii_device *dev = sc->sc_devs[link->target];
+
+ DNPRINTF(MPII_D_IOCTL, "%s: mpii_scsi_ioctl\n", DEVNAME(sc));
+
+ switch (cmd) {
+ case DIOCGCACHE:
+ case DIOCSCACHE:
+ if (dev != NULL && ISSET(dev->flags, MPII_DF_VOLUME)) {
+ return (mpii_ioctl_cache(link, cmd,
+ (struct dk_cache *)addr));
+ }
+ break;
+
+ default:
+ if (sc->sc_ioctl)
+ return (sc->sc_ioctl(link->adapter_softc, cmd, addr));
+
+ break;
+ }
+
+ return (ENOTTY);
+}
+
+int
mpii_ioctl_cache(struct scsi_link *link, u_long cmd, struct dk_cache *dc)
{
struct mpii_softc *sc = (struct mpii_softc *)link->adapter_softc;
struct mpii_device *dev = sc->sc_devs[link->target];
struct mpii_cfg_raid_vol_pg0 *vpg;
struct mpii_msg_raid_action_request *req;
- struct mpii_msg_raid_action_reply *rep;
+ struct mpii_msg_raid_action_reply *rep;
struct mpii_cfg_hdr hdr;
struct mpii_ccb *ccb;
u_int32_t addr = MPII_CFG_RAID_VOL_ADDR_HANDLE | dev->dev_handle;
@@ -3280,7 +3403,7 @@ mpii_ioctl_cache(struct scsi_link *link,
if (((dc->wrcache) ? 1 : 0) == enabled)
goto done;
- ccb = mpii_get_ccb(sc, MPII_NOSLEEP);
+ ccb = scsi_io_get(&sc->sc_iopool, SCSI_POLL);
if (ccb == NULL) {
rv = ENOMEM;
goto done;
@@ -3289,7 +3412,7 @@ mpii_ioctl_cache(struct scsi_link *link,
ccb->ccb_done = mpii_empty_done;
req = ccb->ccb_cmd;
- bzero(req, sizeof(*req));
+ memset(req, 0, sizeof(*req));
req->function = MPII_FUNCTION_RAID_ACTION;
req->action = MPII_RAID_ACTION_CHANGE_VOL_WRITE_CACHE;
req->vol_dev_handle = htole16(dev->dev_handle);
@@ -3313,106 +3436,22 @@ mpii_ioctl_cache(struct scsi_link *link,
mpii_push_reply(sc, ccb->ccb_rcb);
}
- mpii_put_ccb(sc, ccb);
-
-done:
- free(vpg, M_TEMP);
- return (rv);
-}
-#endif
-static int
-mpii_cache_enable(struct mpii_softc *sc, struct mpii_device *dev)
-{
- struct mpii_cfg_raid_vol_pg0 *vpg;
- struct mpii_msg_raid_action_request *req;
- struct mpii_msg_raid_action_reply *rep;
- struct mpii_cfg_hdr hdr;
- struct mpii_ccb *ccb;
- u_int32_t addr = MPII_CFG_RAID_VOL_ADDR_HANDLE | dev->dev_handle;
- size_t pagelen;
- int rv = 0;
- int enabled;
-
- if (mpii_req_cfg_header(sc, MPII_CONFIG_REQ_PAGE_TYPE_RAID_VOL, 0,
- addr, MPII_PG_POLL, &hdr) != 0)
- return (EINVAL);
-
- pagelen = hdr.page_length * 4;
- vpg = malloc(pagelen, M_TEMP, M_NOWAIT | M_ZERO);
- if (vpg == NULL)
- return (ENOMEM);
-
- if (mpii_req_cfg_page(sc, addr, MPII_PG_POLL, &hdr, 1,
- vpg, pagelen) != 0) {
- rv = EINVAL;
- goto done;
- free(vpg, M_TEMP);
- return (EINVAL);
- }
-
- enabled = ((le16toh(vpg->volume_settings) &
- MPII_CFG_RAID_VOL_0_SETTINGS_CACHE_MASK) ==
- MPII_CFG_RAID_VOL_0_SETTINGS_CACHE_ENABLED) ? 1 : 0;
- aprint_normal_dev(sc->sc_dev, "target %d cache %s", dev->slot,
- enabled ? "enabled" : "disabled, enabling");
- aprint_normal("\n");
-
- if (enabled == 0)
- goto done;
-
- ccb = mpii_get_ccb(sc, MPII_NOSLEEP);
- if (ccb == NULL) {
- rv = ENOMEM;
- goto done;
- }
-
- ccb->ccb_done = mpii_empty_done;
-
- req = ccb->ccb_cmd;
- bzero(req, sizeof(*req));
- req->function = MPII_FUNCTION_RAID_ACTION;
- req->action = MPII_RAID_ACTION_CHANGE_VOL_WRITE_CACHE;
- req->vol_dev_handle = htole16(dev->dev_handle);
- req->action_data = htole32(
- MPII_RAID_VOL_WRITE_CACHE_ENABLE);
-
- if (mpii_poll(sc, ccb) != 0) {
- rv = EIO;
- goto done;
- }
-
- if (ccb->ccb_rcb != NULL) {
- rep = ccb->ccb_rcb->rcb_reply;
- if ((rep->ioc_status != MPII_IOCSTATUS_SUCCESS) ||
- ((rep->action_data[0] &
- MPII_RAID_VOL_WRITE_CACHE_MASK) !=
- MPII_RAID_VOL_WRITE_CACHE_ENABLE))
- rv = EINVAL;
- mpii_push_reply(sc, ccb->ccb_rcb);
- }
-
- mpii_put_ccb(sc, ccb);
+ scsi_io_put(&sc->sc_iopool, ccb);
done:
free(vpg, M_TEMP);
- if (rv) {
- aprint_error_dev(sc->sc_dev,
- "enabling cache on target %d failed (%d)\n",
- dev->slot, rv);
- }
return (rv);
}
+#endif /* 0 */
#if NBIO > 0
-static int
+int
mpii_ioctl(device_t dev, u_long cmd, void *addr)
{
struct mpii_softc *sc = device_private(dev);
- int s, error = 0;
+ int error = 0;
DNPRINTF(MPII_D_IOCTL, "%s: mpii_ioctl ", DEVNAME(sc));
- KERNEL_LOCK(1, curlwp);
- s = splbio();
switch (cmd) {
case BIOCINQ:
@@ -3429,15 +3468,13 @@ mpii_ioctl(device_t dev, u_long cmd, voi
break;
default:
DNPRINTF(MPII_D_IOCTL, " invalid ioctl\n");
- error = EINVAL;
+ error = ENOTTY;
}
- splx(s);
- KERNEL_UNLOCK_ONE(curlwp);
return (error);
}
-static int
+int
mpii_ioctl_inq(struct mpii_softc *sc, struct bioc_inq *bi)
{
int i;
@@ -3445,30 +3482,37 @@ mpii_ioctl_inq(struct mpii_softc *sc, st
DNPRINTF(MPII_D_IOCTL, "%s: mpii_ioctl_inq\n", DEVNAME(sc));
strlcpy(bi->bi_dev, DEVNAME(sc), sizeof(bi->bi_dev));
+ mutex_enter(&sc->sc_devs_mtx);
for (i = 0; i < sc->sc_max_devices; i++)
if (sc->sc_devs[i] &&
ISSET(sc->sc_devs[i]->flags, MPII_DF_VOLUME))
bi->bi_novol++;
+ mutex_exit(&sc->sc_devs_mtx);
return (0);
}
-static int
+int
mpii_ioctl_vol(struct mpii_softc *sc, struct bioc_vol *bv)
{
struct mpii_cfg_raid_vol_pg0 *vpg;
struct mpii_cfg_hdr hdr;
struct mpii_device *dev;
- struct scsipi_periph *periph;
size_t pagelen;
u_int16_t volh;
int rv, hcnt = 0;
+ int percent;
DNPRINTF(MPII_D_IOCTL, "%s: mpii_ioctl_vol %d\n",
DEVNAME(sc), bv->bv_volid);
- if ((dev = mpii_find_vol(sc, bv->bv_volid)) == NULL)
+ mutex_enter(&sc->sc_devs_mtx);
+ if ((dev = mpii_find_vol(sc, bv->bv_volid)) == NULL) {
+ mutex_exit(&sc->sc_devs_mtx);
return (ENODEV);
+ }
volh = dev->dev_handle;
+ percent = dev->percent;
+ mutex_exit(&sc->sc_devs_mtx);
if (mpii_req_cfg_header(sc, MPII_CONFIG_REQ_PAGE_TYPE_RAID_VOL, 0,
MPII_CFG_RAID_VOL_ADDR_HANDLE | volh, 0, &hdr) != 0) {
@@ -3502,7 +3546,7 @@ mpii_ioctl_vol(struct mpii_softc *sc, st
if (ISSET(le32toh(vpg->volume_status),
MPII_CFG_RAID_VOL_0_STATUS_RESYNC)) {
bv->bv_status = BIOC_SVREBUILD;
- bv->bv_percent = dev->percent;
+ bv->bv_percent = percent;
} else
bv->bv_status = BIOC_SVDEGRADED;
break;
@@ -3542,22 +3586,11 @@ mpii_ioctl_vol(struct mpii_softc *sc, st
bv->bv_size = le64toh(vpg->max_lba) * le16toh(vpg->block_size);
- periph = scsipi_lookup_periph(&sc->sc_chan, dev->slot, 0);
- if (periph != NULL) {
- if (periph->periph_dev == NULL) {
- snprintf(bv->bv_dev, sizeof(bv->bv_dev), "%s:%d",
- DEVNAME(sc), dev->slot);
- } else {
- strlcpy(bv->bv_dev, device_xname(periph->periph_dev),
- sizeof(bv->bv_dev));
- }
- }
-
free(vpg, M_TEMP);
return (0);
}
-static int
+int
mpii_ioctl_disk(struct mpii_softc *sc, struct bioc_disk *bd)
{
struct mpii_cfg_raid_vol_pg0 *vpg;
@@ -3571,9 +3604,13 @@ mpii_ioctl_disk(struct mpii_softc *sc, s
DNPRINTF(MPII_D_IOCTL, "%s: mpii_ioctl_disk %d/%d\n",
DEVNAME(sc), bd->bd_volid, bd->bd_diskid);
- if ((dev = mpii_find_vol(sc, bd->bd_volid)) == NULL)
+ mutex_enter(&sc->sc_devs_mtx);
+ if ((dev = mpii_find_vol(sc, bd->bd_volid)) == NULL) {
+ mutex_exit(&sc->sc_devs_mtx);
return (ENODEV);
+ }
volh = dev->dev_handle;
+ mutex_exit(&sc->sc_devs_mtx);
if (mpii_req_cfg_header(sc, MPII_CONFIG_REQ_PAGE_TYPE_RAID_VOL, 0,
MPII_CFG_RAID_VOL_ADDR_HANDLE | volh, 0, &hdr) != 0) {
@@ -3614,7 +3651,7 @@ mpii_ioctl_disk(struct mpii_softc *sc, s
return (mpii_bio_disk(sc, bd, dn));
}
-static int
+int
mpii_bio_hs(struct mpii_softc *sc, struct bioc_disk *bd, int nvdsk,
int hsmap, int *hscnt)
{
@@ -3684,7 +3721,7 @@ mpii_bio_hs(struct mpii_softc *sc, struc
return (0);
}
-static int
+int
mpii_bio_disk(struct mpii_softc *sc, struct bioc_disk *bd, u_int8_t dn)
{
struct mpii_cfg_raid_physdisk_pg0 *ppg;
@@ -3717,11 +3754,14 @@ mpii_bio_disk(struct mpii_softc *sc, str
bd->bd_target = ppg->phys_disk_num;
+ mutex_enter(&sc->sc_devs_mtx);
if ((dev = mpii_find_dev(sc, le16toh(ppg->dev_handle))) == NULL) {
+ mutex_exit(&sc->sc_devs_mtx);
bd->bd_status = BIOC_SDINVALID;
free(ppg, M_TEMP);
return (0);
}
+ mutex_exit(&sc->sc_devs_mtx);
switch (ppg->phys_disk_state) {
case MPII_CFG_RAID_PHYDISK_0_STATE_ONLINE:
@@ -3772,11 +3812,12 @@ mpii_bio_disk(struct mpii_softc *sc, str
return (0);
}
-static struct mpii_device *
+struct mpii_device *
mpii_find_vol(struct mpii_softc *sc, int volid)
{
struct mpii_device *dev = NULL;
+ KASSERT(mutex_owned(&sc->sc_devs_mtx));
if (sc->sc_vd_id_low + volid >= sc->sc_max_devices)
return (NULL);
dev = sc->sc_devs[sc->sc_vd_id_low + volid];
@@ -3788,7 +3829,7 @@ mpii_find_vol(struct mpii_softc *sc, int
/*
* Non-sleeping lightweight version of the mpii_ioctl_vol
*/
-static int
+int
mpii_bio_volstate(struct mpii_softc *sc, struct bioc_vol *bv)
{
struct mpii_cfg_raid_vol_pg0 *vpg;
@@ -3797,12 +3838,16 @@ mpii_bio_volstate(struct mpii_softc *sc,
size_t pagelen;
u_int16_t volh;
- if ((dev = mpii_find_vol(sc, bv->bv_volid)) == NULL)
+ mutex_enter(&sc->sc_devs_mtx);
+ if ((dev = mpii_find_vol(sc, bv->bv_volid)) == NULL) {
+ mutex_exit(&sc->sc_devs_mtx);
return (ENODEV);
+ }
volh = dev->dev_handle;
+ mutex_exit(&sc->sc_devs_mtx);
- if (mpii_cfg_header(sc, MPII_CONFIG_REQ_PAGE_TYPE_RAID_VOL, 0,
- MPII_CFG_RAID_VOL_ADDR_HANDLE | volh, &hdr) != 0) {
+ if (mpii_req_cfg_header(sc, MPII_CONFIG_REQ_PAGE_TYPE_RAID_VOL, 0,
+ MPII_CFG_RAID_VOL_ADDR_HANDLE | volh, MPII_PG_POLL, &hdr) != 0) {
DNPRINTF(MPII_D_MISC, "%s: unable to fetch header for raid "
"volume page 0\n", DEVNAME(sc));
return (EINVAL);
@@ -3816,8 +3861,8 @@ mpii_bio_volstate(struct mpii_softc *sc,
return (ENOMEM);
}
- if (mpii_cfg_page(sc, MPII_CFG_RAID_VOL_ADDR_HANDLE | volh,
- &hdr, 1, vpg, pagelen) != 0) {
+ if (mpii_req_cfg_page(sc, MPII_CFG_RAID_VOL_ADDR_HANDLE | volh,
+ MPII_PG_POLL, &hdr, 1, vpg, pagelen) != 0) {
DNPRINTF(MPII_D_MISC, "%s: unable to fetch raid volume "
"page 0\n", DEVNAME(sc));
free(vpg, M_TEMP);
@@ -3852,47 +3897,46 @@ mpii_bio_volstate(struct mpii_softc *sc,
return (0);
}
-static int
+int
mpii_create_sensors(struct mpii_softc *sc)
{
int i, rv;
+ DNPRINTF(MPII_D_MISC, "%s: mpii_create_sensors(%d)\n",
+ DEVNAME(sc), sc->sc_max_volumes);
sc->sc_sme = sysmon_envsys_create();
- sc->sc_sensors = malloc(sizeof(envsys_data_t) * sc->sc_vd_count,
+ sc->sc_sensors = malloc(sizeof(envsys_data_t) * sc->sc_max_volumes,
M_DEVBUF, M_NOWAIT | M_ZERO);
if (sc->sc_sensors == NULL) {
- aprint_error_dev(sc->sc_dev,
- "can't allocate envsys_data_t\n");
+ aprint_error_dev(sc->sc_dev, "can't allocate envsys_data_t\n");
return (1);
}
- for (i = 0; i < sc->sc_vd_count; i++) {
+ for (i = 0; i < sc->sc_max_volumes; i++) {
sc->sc_sensors[i].units = ENVSYS_DRIVE;
sc->sc_sensors[i].state = ENVSYS_SINVALID;
sc->sc_sensors[i].value_cur = ENVSYS_DRIVE_EMPTY;
- /* Enable monitoring for drive state changes */
sc->sc_sensors[i].flags |= ENVSYS_FMONSTCHANGED;
- /* logical drives */
+ /* logical drives */
snprintf(sc->sc_sensors[i].desc,
sizeof(sc->sc_sensors[i].desc), "%s:%d",
- DEVNAME(sc), i);
- if ((rv = sysmon_envsys_sensor_attach(sc->sc_sme,
+ DEVNAME(sc), i);
+ if ((rv = sysmon_envsys_sensor_attach(sc->sc_sme,
&sc->sc_sensors[i])) != 0) {
aprint_error_dev(sc->sc_dev,
"unable to attach sensor (rv = %d)\n", rv);
- goto out;
- }
+ goto out;
+ }
}
sc->sc_sme->sme_name = DEVNAME(sc);
- sc->sc_sme->sme_cookie = sc;
+ sc->sc_sme->sme_cookie = sc;
sc->sc_sme->sme_refresh = mpii_refresh_sensors;
rv = sysmon_envsys_register(sc->sc_sme);
-
if (rv != 0) {
aprint_error_dev(sc->sc_dev,
- "unable to register with sysmon (rv = %d)\n", rv);
+ "unable to register with sysmon (rv = %d)\n", rv);
goto out;
}
return 0;
@@ -3901,35 +3945,30 @@ out:
free(sc->sc_sensors, M_DEVBUF);
sysmon_envsys_destroy(sc->sc_sme);
sc->sc_sme = NULL;
- return EINVAL;
+ return 1;
}
-static int
+int
mpii_destroy_sensors(struct mpii_softc *sc)
{
- if (sc->sc_sme == NULL)
+ if (sc->sc_sme == NULL)
return 0;
sysmon_envsys_unregister(sc->sc_sme);
sc->sc_sme = NULL;
free(sc->sc_sensors, M_DEVBUF);
return 0;
+
}
-static void
+void
mpii_refresh_sensors(struct sysmon_envsys *sme, envsys_data_t *edata)
{
- struct mpii_softc *sc = sc = sme->sme_cookie;
+ struct mpii_softc *sc = sme->sme_cookie;
struct bioc_vol bv;
- int s, error;
- bzero(&bv, sizeof(bv));
+ memset(&bv, 0, sizeof(bv));
bv.bv_volid = edata->sensor;
- KERNEL_LOCK(1, curlwp);
- s = splbio();
- error = mpii_bio_volstate(sc, &bv);
- splx(s);
- KERNEL_UNLOCK_ONE(curlwp);
- if (error)
+ if (mpii_bio_volstate(sc, &bv))
bv.bv_status = BIOC_SVINVALID;
bio_vol_to_envsys(edata, &bv);
}
Index: src/sys/dev/pci/mpiireg.h
diff -u src/sys/dev/pci/mpiireg.h:1.1 src/sys/dev/pci/mpiireg.h:1.2
--- src/sys/dev/pci/mpiireg.h:1.1 Sat Nov 24 18:11:22 2018
+++ src/sys/dev/pci/mpiireg.h Mon Dec 3 22:34:36 2018
@@ -1,7 +1,7 @@
-/* $NetBSD: mpiireg.h,v 1.1 2018/11/24 18:11:22 bouyer Exp $ */
-/* OpenBSD: mpii.c,v 1.51 2012/04/11 13:29:14 naddy Exp */
+/* $NetBSD: mpiireg.h,v 1.2 2018/12/03 22:34:36 bouyer Exp $ */
+/* $OpenBSD: mpiireg.h,v 1.13 2018/06/19 10:32:41 jmatthew Exp $ */
/*
- * Copyright (c) 2010 Mike Belopuhov <[email protected]>
+ * Copyright (c) 2010 Mike Belopuhov
* Copyright (c) 2009 James Giannoules
* Copyright (c) 2005 - 2010 David Gwynne <[email protected]>
* Copyright (c) 2005 - 2010 Marco Peereboom <[email protected]>
@@ -58,18 +58,18 @@
#define MPII_HOSTDIAG (0x08)
#define MPII_HOSTDIAG_BDS_MASK (0x00001800) /* boot device select */
-#define MPII_HOSTDIAG_BDS_DEFAULT (0<<11) /* default address map, flash */
+#define MPII_HOSTDIAG_BDS_DEFAULT (0<<11) /* default address map, flash */
#define MPII_HOSTDIAG_BDS_HCDW (1<<11) /* host code and data window */
#define MPII_HOSTDIAG_CLEARFBS (1<<10) /* clear flash bad sig */
#define MPII_HOSTDIAG_FORCE_HCB_ONBOOT (1<<9) /* force host controlled boot */
#define MPII_HOSTDIAG_HCB_MODE (1<<8) /* host controlled boot mode */
-#define MPII_HOSTDIAG_DWRE (1<<7) /* diag reg write enabled */
-#define MPII_HOSTDIAG_FBS (1<<6) /* flash bad sig */
-#define MPII_HOSTDIAG_RESET_HIST (1<<5) /* reset history */
-#define MPII_HOSTDIAG_DIAGWR_EN (1<<4) /* diagnostic write enabled */
-#define MPII_HOSTDIAG_RESET_ADAPTER (1<<2) /* reset adapter */
-#define MPII_HOSTDIAG_HOLD_IOC_RESET (1<<1) /* hold ioc in reset */
-#define MPII_HOSTDIAG_DIAGMEM_EN (1<<0) /* diag mem enable */
+#define MPII_HOSTDIAG_DWRE (1<<7) /* diag reg write enabled */
+#define MPII_HOSTDIAG_FBS (1<<6) /* flash bad sig */
+#define MPII_HOSTDIAG_RESET_HIST (1<<5) /* reset history */
+#define MPII_HOSTDIAG_DIAGWR_EN (1<<4) /* diagnostic write enabled */
+#define MPII_HOSTDIAG_RESET_ADAPTER (1<<2) /* reset adapter */
+#define MPII_HOSTDIAG_HOLD_IOC_RESET (1<<1) /* hold ioc in reset */
+#define MPII_HOSTDIAG_DIAGMEM_EN (1<<0) /* diag mem enable */
#define MPII_DIAGRWDATA (0x10)
@@ -81,12 +81,12 @@
#define MPII_INTR_STATUS_SYS2IOCDB (1<<31) /* ioc written to by host */
#define MPII_INTR_STATUS_RESET (1<<30) /* physical ioc reset */
#define MPII_INTR_STATUS_REPLY (1<<3) /* reply message interrupt */
-#define MPII_INTR_STATUS_IOC2SYSDB (1<<0) /* ioc write to doorbell */
+#define MPII_INTR_STATUS_IOC2SYSDB (1<<0) /* ioc write to doorbell */
#define MPII_INTR_MASK (0x34)
#define MPII_INTR_MASK_RESET (1<<30) /* ioc reset intr mask */
-#define MPII_INTR_MASK_REPLY (1<<3) /* reply message intr mask */
-#define MPII_INTR_MASK_DOORBELL (1<<0) /* doorbell interrupt mask */
+#define MPII_INTR_MASK_REPLY (1<<3) /* reply message intr mask */
+#define MPII_INTR_MASK_DOORBELL (1<<0) /* doorbell interrupt mask */
#define MPII_DCR_DATA (0x38)
@@ -125,9 +125,29 @@
struct mpii_sge {
u_int32_t sg_hdr;
- u_int32_t sg_lo_addr;
- u_int32_t sg_hi_addr;
-} __packed;
+ u_int32_t sg_addr_lo;
+ u_int32_t sg_addr_hi;
+} __packed __aligned(4);
+
+/*
+ * SAS3 (IEEE) Scatter Gather Lists
+ */
+
+#define MPII_IEEE_SGE_ADDR_MASK (0x03)
+#define MPII_IEEE_SGE_ADDR_SYSTEM (0x00)
+#define MPII_IEEE_SGE_ADDR_IOCDDR (0x01)
+#define MPII_IEEE_SGE_ADDR_IOCPLB (0x02)
+#define MPII_IEEE_SGE_ADDR_IOCPLBNTA (0x03)
+#define MPII_IEEE_SGE_END_OF_LIST (0x40)
+#define MPII_IEEE_SGE_CHAIN_ELEMENT (0x80)
+
+struct mpii_ieee_sge {
+ u_int64_t sg_addr;
+ u_int32_t sg_len;
+ u_int16_t _reserved;
+ u_int8_t sg_next_chain_offset;
+ u_int8_t sg_flags;
+} __packed __aligned(8);
struct mpii_fw_tce {
u_int8_t reserved1;
@@ -140,7 +160,7 @@ struct mpii_fw_tce {
u_int32_t image_offset;
u_int32_t image_size;
-} __packed;
+} __packed __aligned(4);
/*
* Messages
@@ -290,7 +310,7 @@ struct mpii_msg_request {
u_int8_t vp_id;
u_int8_t vf_id;
u_int16_t reserved6;
-} __packed;
+} __packed __aligned(4);
struct mpii_msg_reply {
u_int16_t reserved1;
@@ -304,12 +324,12 @@ struct mpii_msg_reply {
u_int8_t vp_id;
u_int8_t vf_if;
u_int16_t reserved4;
-
+
u_int16_t reserved5;
u_int16_t ioc_status;
u_int32_t ioc_loginfo;
-} __packed;
+} __packed __aligned(4);
/* ioc init */
@@ -346,14 +366,17 @@ struct mpii_msg_iocinit_request {
u_int32_t system_reply_address_high;
- u_int64_t system_request_frame_base_address;
+ u_int32_t system_request_frame_base_address_lo;
+ u_int32_t system_request_frame_base_address_hi;
- u_int64_t reply_descriptor_post_queue_address;
+ u_int32_t reply_descriptor_post_queue_address_lo;
+ u_int32_t reply_descriptor_post_queue_address_hi;
- u_int64_t reply_free_queue_address;
+ u_int32_t reply_free_queue_address_lo;
+ u_int32_t reply_free_queue_address_hi;
u_int64_t timestamp;
-} __packed;
+} __packed __aligned(4);
struct mpii_msg_iocinit_reply {
u_int8_t whoinit;
@@ -373,7 +396,7 @@ struct mpii_msg_iocinit_reply {
u_int16_t ioc_status;
u_int32_t ioc_loginfo;
-} __packed;
+} __packed __aligned(4);
struct mpii_msg_iocfacts_request {
u_int16_t reserved1;
@@ -387,7 +410,7 @@ struct mpii_msg_iocfacts_request {
u_int8_t vp_id;
u_int8_t vf_id;
u_int16_t reserved4;
-} __packed;
+} __packed __aligned(4);
struct mpii_msg_iocfacts_reply {
u_int8_t msg_version_min;
@@ -461,7 +484,7 @@ struct mpii_msg_iocfacts_reply {
u_int16_t max_persistent_entries;
u_int32_t reserved4;
-} __packed;
+} __packed __aligned(4);
struct mpii_msg_portfacts_request {
u_int16_t reserved1;
@@ -475,7 +498,7 @@ struct mpii_msg_portfacts_request {
u_int8_t vp_id;
u_int8_t vf_id;
u_int16_t reserved3;
-} __packed;
+} __packed __aligned(4);
struct mpii_msg_portfacts_reply {
u_int16_t reserved1;
@@ -502,11 +525,12 @@ struct mpii_msg_portfacts_reply {
#define MPII_PORTFACTS_PORTTYPE_ISCSI (0x20)
#define MPII_PORTFACTS_PORTTYPE_SAS_PHYSICAL (0x30)
#define MPII_PORTFACTS_PORTTYPE_SAS_VIRTUAL (0x31)
+#define MPII_PORTFACTS_PORTTYPE_TRI_MODE (0x40)
u_int16_t reserved6;
u_int16_t max_posted_cmd_buffers;
u_int16_t reserved7;
-} __packed;
+} __packed __aligned(4);
struct mpii_msg_portenable_request {
u_int16_t reserved1;
@@ -514,14 +538,14 @@ struct mpii_msg_portenable_request {
u_int8_t function;
u_int8_t reserved2;
- u_int8_t port_flags;
+ u_int8_t port_flags;
u_int8_t reserved3;
u_int8_t msg_flags;
u_int8_t vp_id;
u_int8_t vf_id;
u_int16_t reserved4;
-} __packed;
+} __packed __aligned(4);
struct mpii_msg_portenable_reply {
u_int16_t reserved1;
@@ -541,7 +565,7 @@ struct mpii_msg_portenable_reply {
u_int16_t ioc_status;
u_int32_t ioc_loginfo;
-} __packed;
+} __packed __aligned(4);
struct mpii_msg_event_request {
u_int16_t reserved1;
@@ -561,12 +585,12 @@ struct mpii_msg_event_request {
u_int32_t reserved6;
u_int32_t event_masks[4];
-
+
u_int16_t sas_broadcase_primitive_masks;
u_int16_t reserved7;
u_int32_t reserved8;
-} __packed;
+} __packed __aligned(4);
struct mpii_msg_event_reply {
u_int16_t event_data_length;
@@ -594,7 +618,7 @@ struct mpii_msg_event_reply {
u_int32_t event_context;
/* event data follows */
-} __packed;
+} __packed __aligned(4);
struct mpii_msg_eventack_request {
u_int16_t reserved1;
@@ -612,7 +636,7 @@ struct mpii_msg_eventack_request {
u_int16_t reserved4;
u_int32_t event_context;
-} __packed;
+} __packed __aligned(4);
struct mpii_msg_eventack_reply {
u_int16_t reserved1;
@@ -630,7 +654,7 @@ struct mpii_msg_eventack_reply {
u_int16_t ioc_status;
u_int32_t ioc_loginfo;
-} __packed;
+} __packed __aligned(4);
struct mpii_msg_fwupload_request {
u_int8_t image_type;
@@ -661,7 +685,7 @@ struct mpii_msg_fwupload_request {
struct mpii_fw_tce tce;
/* followed by an sgl */
-} __packed;
+} __packed __aligned(4);
struct mpii_msg_fwupload_reply {
u_int8_t image_type;
@@ -682,7 +706,7 @@ struct mpii_msg_fwupload_reply {
u_int32_t ioc_loginfo;
u_int32_t actual_image_size;
-} __packed;
+} __packed __aligned(4);
struct mpii_msg_scsi_io {
u_int16_t dev_handle;
@@ -696,7 +720,7 @@ struct mpii_msg_scsi_io {
u_int8_t vp_id;
u_int8_t vf_id;
u_int16_t reserved3;
-
+
u_int32_t sense_buffer_low_address;
u_int16_t sgl_flags;
@@ -745,7 +769,7 @@ struct mpii_msg_scsi_io {
u_int8_t cdb[MPII_CDB_LEN];
/* followed by an sgl */
-} __packed;
+} __packed __aligned(4);
struct mpii_msg_scsi_io_error {
u_int16_t dev_handle;
@@ -761,25 +785,23 @@ struct mpii_msg_scsi_io_error {
u_int16_t reserved3;
u_int8_t scsi_status;
-
-#define MPII_SCSIIO_ERR_STATUS_SUCCESS (0x00)
-#define MPII_SCSIIO_ERR_STATUS_CHECK_COND (0x02)
-#define MPII_SCSIIO_ERR_STATUS_BUSY (0x04)
-#define MPII_SCSIIO_ERR_STATUS_INTERMEDIATE (0x08)
-#define MPII_SCSIIO_ERR_STATUS_INTERMEDIATE_CONDMET (0x10)
-#define MPII_SCSIIO_ERR_STATUS_RESERVATION_CONFLICT (0x14)
-#define MPII_SCSIIO_ERR_STATUS_CMD_TERM (0x22)
-#define MPII_SCSIIO_ERR_STATUS_TASK_SET_FULL (0x28)
-#define MPII_SCSIIO_ERR_STATUS_ACA_ACTIVE (0x30)
-#define MPII_SCSIIO_ERR_STATUS_TASK_ABORTED (0x40)
-
+#define MPII_SCSIIO_STATUS_GOOD (0x00)
+#define MPII_SCSIIO_STATUS_CHECK_COND (0x02)
+#define MPII_SCSIIO_STATUS_COND_MET (0x04)
+#define MPII_SCSIIO_STATUS_BUSY (0x08)
+#define MPII_SCSIIO_STATUS_INTERMEDIATE (0x10)
+#define MPII_SCSIIO_STATUS_INTERMEDIATE_CONDMET (0x14)
+#define MPII_SCSIIO_STATUS_RESERVATION_CONFLICT (0x18)
+#define MPII_SCSIIO_STATUS_CMD_TERM (0x22)
+#define MPII_SCSIIO_STATUS_TASK_SET_FULL (0x28)
+#define MPII_SCSIIO_STATUS_ACA_ACTIVE (0x30)
+#define MPII_SCSIIO_STATUS_TASK_ABORTED (0x40)
u_int8_t scsi_state;
-#define MPII_SCSIIO_ERR_STATE_AUTOSENSE_VALID (1<<0)
-#define MPII_SCSIIO_ERR_STATE_AUTOSENSE_FAILED (1<<1)
-#define MPII_SCSIIO_ERR_STATE_NO_SCSI_STATUS (1<<2)
-#define MPII_SCSIIO_ERR_STATE_TERMINATED (1<<3)
-#define MPII_SCSIIO_ERR_STATE_RESPONSE_INFO_VALID (1<<4)
-#define MPII_SCSIIO_ERR_STATE_QUEUE_TAG_REJECTED (0xffff)
+#define MPII_SCSIIO_STATE_AUTOSENSE_VALID (1<<0)
+#define MPII_SCSIIO_STATE_AUTOSENSE_FAILED (1<<1)
+#define MPII_SCSIIO_STATE_NO_SCSI_STATUS (1<<2)
+#define MPII_SCSIIO_STATE_TERMINATED (1<<3)
+#define MPII_SCSIIO_STATE_RESPONSE_INFO_VALID (1<<4)
u_int16_t ioc_status;
u_int32_t ioc_loginfo;
@@ -798,7 +820,7 @@ struct mpii_msg_scsi_io_error {
u_int32_t reserved5;
u_int32_t reserved6;
-} __packed;
+} __packed __aligned(4);
struct mpii_request_descr {
u_int8_t request_flags;
@@ -812,16 +834,16 @@ struct mpii_request_descr {
u_int16_t lmid;
u_int16_t dev_handle;
-} __packed;
+} __packed __aligned(8);
struct mpii_reply_descr {
u_int8_t reply_flags;
-#define MPII_REPLY_DESCR_TYPE_MASK (0x0f)
-#define MPII_REPLY_DESCR_SCSI_IO_SUCCESS (0x00)
-#define MPII_REPLY_DESCR_ADDRESS_REPLY (0x01)
-#define MPII_REPLY_DESCR_TARGET_ASSIST_SUCCESS (0x02)
-#define MPII_REPLY_DESCR_TARGET_COMMAND_BUFFER (0x03)
-#define MPII_REPLY_DESCR_UNUSED (0x0f)
+#define MPII_REPLY_DESCR_TYPE_MASK (0x0f)
+#define MPII_REPLY_DESCR_SCSI_IO_SUCCESS (0x00)
+#define MPII_REPLY_DESCR_ADDRESS_REPLY (0x01)
+#define MPII_REPLY_DESCR_TARGET_ASSIST_SUCCESS (0x02)
+#define MPII_REPLY_DESCR_TARGET_COMMAND_BUFFER (0x03)
+#define MPII_REPLY_DESCR_UNUSED (0x0f)
u_int8_t vf_id;
u_int16_t smid;
@@ -829,7 +851,7 @@ struct mpii_reply_descr {
u_int32_t data;
u_int32_t frame_addr; /* Address Reply */
};
-} __packed;
+} __packed __aligned(8);
struct mpii_request_header {
u_int16_t function_dependent1;
@@ -843,7 +865,7 @@ struct mpii_request_header {
u_int8_t vp_id;
u_int8_t vf_id;
u_int16_t reserved;
-} __packed;
+} __packed __aligned(4);
struct mpii_msg_scsi_task_request {
u_int16_t dev_handle;
@@ -870,7 +892,7 @@ struct mpii_msg_scsi_task_request {
u_int16_t task_mid;
u_int16_t reserved5;
-} __packed;
+} __packed __aligned(4);
struct mpii_msg_scsi_task_reply {
u_int16_t dev_handle;
@@ -892,7 +914,7 @@ struct mpii_msg_scsi_task_reply {
u_int32_t ioc_loginfo;
u_int32_t termination_count;
-} __packed;
+} __packed __aligned(4);
struct mpii_msg_sas_oper_request {
u_int8_t operation;
@@ -936,7 +958,7 @@ struct mpii_msg_sas_oper_request {
u_int32_t ioc_param_value;
u_int64_t reserved5;
-} __packed;
+} __packed __aligned(4);
struct mpii_msg_sas_oper_reply {
u_int8_t operation;
@@ -956,7 +978,7 @@ struct mpii_msg_sas_oper_reply {
u_int16_t ioc_status;
u_int32_t ioc_loginfo;
-} __packed;
+} __packed __aligned(4);
struct mpii_msg_raid_action_request {
u_int8_t action;
@@ -981,7 +1003,7 @@ struct mpii_msg_raid_action_request {
#define MPII_RAID_VOL_WRITE_CACHE_ENABLE (0x02)
struct mpii_sge action_sge;
-} __packed;
+} __packed __aligned(4);
struct mpii_msg_raid_action_reply {
u_int8_t action;
@@ -1001,7 +1023,7 @@ struct mpii_msg_raid_action_reply {
u_int16_t ioc_status;
u_int32_t action_data[5];
-} __packed;
+} __packed __aligned(4);
struct mpii_cfg_hdr {
u_int8_t page_version;
@@ -1009,9 +1031,9 @@ struct mpii_cfg_hdr {
u_int8_t page_number;
u_int8_t page_type;
#define MPII_CONFIG_REQ_PAGE_TYPE_ATTRIBUTE (0xf0)
-#define MPI2_CONFIG_PAGEATTR_READ_ONLY (0x00)
-#define MPI2_CONFIG_PAGEATTR_CHANGEABLE (0x10)
-#define MPI2_CONFIG_PAGEATTR_PERSISTENT (0x20)
+#define MPI2_CONFIG_PAGEATTR_READ_ONLY (0x00)
+#define MPI2_CONFIG_PAGEATTR_CHANGEABLE (0x10)
+#define MPI2_CONFIG_PAGEATTR_PERSISTENT (0x20)
#define MPII_CONFIG_REQ_PAGE_TYPE_MASK (0x0f)
#define MPII_CONFIG_REQ_PAGE_TYPE_IO_UNIT (0x00)
@@ -1021,7 +1043,7 @@ struct mpii_cfg_hdr {
#define MPII_CONFIG_REQ_PAGE_TYPE_MANUFACTURING (0x09)
#define MPII_CONFIG_REQ_PAGE_TYPE_RAID_PD (0x0a)
#define MPII_CONFIG_REQ_PAGE_TYPE_EXTENDED (0x0f)
-} __packed;
+} __packed __aligned(4);
struct mpii_ecfg_hdr {
u_int8_t page_version;
@@ -1035,7 +1057,14 @@ struct mpii_ecfg_hdr {
#define MPII_CONFIG_REQ_PAGE_TYPE_RAID_CONFIG (0x16)
#define MPII_CONFIG_REQ_PAGE_TYPE_DRIVER_MAPPING (0x17)
u_int8_t reserved2;
-} __packed;
+} __packed __aligned(4);
+
+/* config page address formats */
+#define MPII_PGAD_SAS_DEVICE_FORM_MASK (0xf0000000)
+#define MPII_PGAD_SAS_DEVICE_FORM_GET_NEXT_HANDLE (0x00000000)
+#define MPII_PGAD_SAS_DEVICE_FORM_HANDLE (0x20000000)
+
+#define MPII_PGAD_SAS_DEVICE_HANDLE_MASK (0x0000ffff)
struct mpii_msg_config_request {
u_int8_t action;
@@ -1057,10 +1086,10 @@ struct mpii_msg_config_request {
#define MPII_CONFIG_REQ_EXTPAGE_TYPE_SAS_DEVICE (0x12)
#define MPII_CONFIG_REQ_EXTPAGE_TYPE_SAS_PHY (0x13)
#define MPII_CONFIG_REQ_EXTPAGE_TYPE_LOG (0x14)
-#define MPI2_CONFIG_EXTPAGETYPE_ENCLOSURE (0x15)
-#define MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG (0x16)
-#define MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING (0x17)
-#define MPI2_CONFIG_EXTPAGETYPE_SAS_PORT (0x18)
+#define MPI2_CONFIG_EXTPAGETYPE_ENCLOSURE (0x15)
+#define MPI2_CONFIG_EXTPAGETYPE_RAID_CONFIG (0x16)
+#define MPI2_CONFIG_EXTPAGETYPE_DRIVER_MAPPING (0x17)
+#define MPI2_CONFIG_EXTPAGETYPE_SAS_PORT (0x18)
u_int8_t msg_flags;
u_int8_t vp_id;
@@ -1075,7 +1104,7 @@ struct mpii_msg_config_request {
/* XXX lots of defns here */
struct mpii_sge page_buffer;
-} __packed;
+} __packed __aligned(4);
struct mpii_msg_config_reply {
u_int8_t action;
@@ -1097,7 +1126,7 @@ struct mpii_msg_config_reply {
u_int32_t ioc_loginfo;
struct mpii_cfg_hdr config_header;
-} __packed;
+} __packed __aligned(4);
struct mpii_cfg_manufacturing_pg0 {
struct mpii_cfg_hdr config_header;
@@ -1107,7 +1136,7 @@ struct mpii_cfg_manufacturing_pg0 {
char board_name[16];
char board_assembly[16];
char board_tracer_number[16];
-} __packed;
+} __packed __aligned(4);
struct mpii_cfg_ioc_pg1 {
struct mpii_cfg_hdr config_header;
@@ -1125,7 +1154,7 @@ struct mpii_cfg_ioc_pg1 {
u_int32_t reserved1;
u_int32_t reserved2;
-} __packed;
+} __packed __aligned(4);
struct mpii_cfg_ioc_pg3 {
struct mpii_cfg_hdr config_header;
@@ -1134,7 +1163,7 @@ struct mpii_cfg_ioc_pg3 {
u_int8_t reserved[3];
/* followed by a list of mpii_cfg_raid_physdisk structs */
-} __packed;
+} __packed __aligned(4);
struct mpii_cfg_ioc_pg8 {
struct mpii_cfg_hdr config_header;
@@ -1161,16 +1190,16 @@ struct mpii_cfg_ioc_pg8 {
#define MPII_IOC_PG8_IRFLAGS_LOW_VOLUME_MAPPING (0<<0)
#define MPII_IOC_PG8_IRFLAGS_HIGH_VOLUME_MAPPING (1<<0)
u_int16_t reserved4;
-
+
u_int32_t reserved5;
-} __packed;
+} __packed __aligned(4);
struct mpii_cfg_raid_physdisk {
u_int8_t phys_disk_id;
u_int8_t phys_disk_bus;
u_int8_t phys_disk_ioc;
u_int8_t phys_disk_num;
-} __packed;
+} __packed __aligned(4);
struct mpii_cfg_fc_port_pg0 {
struct mpii_cfg_hdr config_header;
@@ -1208,7 +1237,7 @@ struct mpii_cfg_fc_port_pg0 {
u_int8_t max_hard_aliases_supported;
u_int8_t num_current_aliases;
u_int8_t reserved2;
-} __packed;
+} __packed __aligned(4);
struct mpii_cfg_fc_port_pg1 {
struct mpii_cfg_hdr config_header;
@@ -1228,7 +1257,7 @@ struct mpii_cfg_fc_port_pg1 {
u_int8_t rr_tov;
u_int8_t initiator_dev_to;
u_int8_t initiator_lo_pend_to;
-} __packed;
+} __packed __aligned(4);
struct mpii_cfg_fc_device_pg0 {
struct mpii_cfg_hdr config_header;
@@ -1251,7 +1280,7 @@ struct mpii_cfg_fc_device_pg0 {
u_int8_t fc_ph_high_version;
u_int8_t current_target_id;
u_int8_t current_bus;
-} __packed;
+} __packed __aligned(4);
#define MPII_CFG_RAID_VOL_ADDR_HANDLE (1<<28)
@@ -1308,14 +1337,14 @@ struct mpii_cfg_raid_vol_pg0 {
#define MPII_CFG_RAID_VOL_0_INACTIVE_INSUF_META (0x05)
/* followed by a list of mpii_cfg_raid_vol_pg0_physdisk structs */
-} __packed;
+} __packed __aligned(4);
struct mpii_cfg_raid_vol_pg0_physdisk {
u_int8_t raid_set_num;
u_int8_t phys_disk_map;
u_int8_t phys_disk_num;
u_int8_t reserved;
-} __packed;
+} __packed __aligned(4);
struct mpii_cfg_raid_vol_pg1 {
struct mpii_cfg_hdr config_header;
@@ -1334,7 +1363,7 @@ struct mpii_cfg_raid_vol_pg1 {
u_int32_t reserved2;
u_int32_t reserved3;
-} __packed;
+} __packed __aligned(4);
#define MPII_CFG_RAID_PHYS_DISK_ADDR_NUMBER (1<<28)
@@ -1399,7 +1428,7 @@ struct mpii_cfg_raid_physdisk_pg0 {
u_int16_t reserved4;
u_int32_t reserved5;
-} __packed;
+} __packed __aligned(4);
struct mpii_cfg_raid_physdisk_pg1 {
struct mpii_cfg_hdr config_header;
@@ -1411,7 +1440,7 @@ struct mpii_cfg_raid_physdisk_pg1 {
u_int32_t reserved2;
/* followed by mpii_cfg_raid_physdisk_path structs */
-} __packed;
+} __packed __aligned(4);
struct mpii_cfg_raid_physdisk_path {
u_int8_t phys_disk_id;
@@ -1427,7 +1456,7 @@ struct mpii_cfg_raid_physdisk_path {
u_int16_t flags;
#define MPII_CFG_RAID_PHYDISK_PATH_INVALID (1<<0)
#define MPII_CFG_RAID_PHYDISK_PATH_BROKEN (1<<1)
-} __packed;
+} __packed __aligned(4);
#define MPII_CFG_SAS_DEV_ADDR_NEXT (0<<28)
#define MPII_CFG_SAS_DEV_ADDR_BUS (1<<28)
@@ -1490,7 +1519,7 @@ struct mpii_cfg_sas_dev_pg0 {
u_int8_t reserved1;
u_int64_t reserved2;
-} __packed;
+} __packed __aligned(4);
#define MPII_CFG_RAID_CONFIG_ACTIVE_CONFIG (2<<28)
@@ -1514,7 +1543,7 @@ struct mpii_cfg_raid_config_pg0 {
u_int8_t reserved2[3];
/* followed by struct mpii_raid_config_element structs */
-} __packed;
+} __packed __aligned(4);
struct mpii_raid_config_element {
u_int16_t element_flags;
@@ -1527,7 +1556,7 @@ struct mpii_raid_config_element {
u_int8_t hot_spare_pool;
u_int8_t phys_disk_num;
u_int16_t phys_disk_dev_handle;
-} __packed;
+} __packed __aligned(4);
struct mpii_cfg_dpm_pg0 {
struct mpii_ecfg_hdr config_header;
@@ -1538,7 +1567,7 @@ struct mpii_cfg_dpm_pg0 {
#define MPII_DPM_ADDRESS_START_ENTRY_MASK (0x0000ffff)
/* followed by struct mpii_dpm_entry structs */
-} __packed;
+} __packed __aligned(4);
struct mpii_dpm_entry {
u_int64_t physical_identifier;
@@ -1549,7 +1578,7 @@ struct mpii_dpm_entry {
u_int32_t physical_bits_mapping;
u_int32_t reserved1;
-} __packed;
+} __packed __aligned(4);
struct mpii_evt_sas_discovery {
u_int8_t flags;
@@ -1566,7 +1595,7 @@ struct mpii_evt_sas_discovery {
u_int8_t reserved1;
u_int32_t discovery_status;
-} __packed;
+} __packed __aligned(4);
struct mpii_evt_ir_status {
u_int16_t vol_dev_handle;
@@ -1594,7 +1623,7 @@ struct mpii_evt_ir_volume {
u_int32_t new_value;
u_int32_t prev_value;
-} __packed;
+} __packed __aligned(4);
struct mpii_evt_ir_physical_disk {
u_int16_t reserved1;
@@ -1612,7 +1641,7 @@ struct mpii_evt_ir_physical_disk {
u_int32_t new_value;
u_int32_t previous_value;
-} __packed;
+} __packed __aligned(4);
struct mpii_evt_sas_tcl {
u_int16_t enclosure_handle;
@@ -1631,7 +1660,7 @@ struct mpii_evt_sas_tcl {
u_int8_t physical_port;
/* followed by num_entries number of struct mpii_evt_phy_entry */
-} __packed;
+} __packed __aligned(4);
struct mpii_evt_phy_entry {
u_int16_t dev_handle;
@@ -1640,7 +1669,7 @@ struct mpii_evt_phy_entry {
#define MPII_EVENT_SAS_TOPO_PS_RC_MASK (0x0f)
#define MPII_EVENT_SAS_TOPO_PS_RC_ADDED (0x01)
#define MPII_EVENT_SAS_TOPO_PS_RC_MISSING (0x02)
-} __packed;
+} __packed __aligned(4);
struct mpii_evt_ir_cfg_change_list {
u_int8_t num_elements;
@@ -1651,7 +1680,7 @@ struct mpii_evt_ir_cfg_change_list {
#define MPII_EVT_IR_CFG_CHANGE_LIST_FOREIGN (0x1)
/* followed by num_elements struct mpii_evt_ir_cfg_elements */
-} __packed;
+} __packed __aligned(4);
struct mpii_evt_ir_cfg_element {
u_int16_t element_flags;
@@ -1673,4 +1702,4 @@ struct mpii_evt_ir_cfg_element {
#define MPII_EVT_IR_CFG_ELEMENT_RC_PD_DELETED (0x09)
u_int8_t phys_disk_num;
u_int16_t phys_disk_dev_handle;
-} __packed;
+} __packed __aligned(4);