Path: blob/main/website/static/security/patches/EN-13:03/mfi.patch
18096 views
Index: sys/dev/mfi/mfi.c1===================================================================2--- sys/dev/mfi/mfi.c (revision 254079)3+++ sys/dev/mfi/mfi.c (working copy)4@@ -107,7 +107,7 @@ static void mfi_bio_complete(struct mfi_command *)5static struct mfi_command *mfi_build_ldio(struct mfi_softc *,struct bio*);6static struct mfi_command *mfi_build_syspdio(struct mfi_softc *,struct bio*);7static int mfi_send_frame(struct mfi_softc *, struct mfi_command *);8-static int mfi_abort(struct mfi_softc *, struct mfi_command *);9+static int mfi_abort(struct mfi_softc *, struct mfi_command **);10static int mfi_linux_ioctl_int(struct cdev *, u_long, caddr_t, int, struct thread *);11static void mfi_timeout(void *);12static int mfi_user_command(struct mfi_softc *,13@@ -373,6 +373,8 @@ mfi_attach(struct mfi_softc *sc)14sx_init(&sc->mfi_config_lock, "MFI config");15TAILQ_INIT(&sc->mfi_ld_tqh);16TAILQ_INIT(&sc->mfi_syspd_tqh);17+ TAILQ_INIT(&sc->mfi_ld_pend_tqh);18+ TAILQ_INIT(&sc->mfi_syspd_pend_tqh);19TAILQ_INIT(&sc->mfi_evt_queue);20TASK_INIT(&sc->mfi_evt_task, 0, mfi_handle_evt, sc);21TASK_INIT(&sc->mfi_map_sync_task, 0, mfi_handle_map_sync, sc);22@@ -694,6 +696,7 @@ mfi_attach(struct mfi_softc *sc)23device_printf(sc->mfi_dev, "Cannot set up interrupt\n");24return (EINVAL);25}26+ sc->mfi_intr_ptr = mfi_intr_tbolt;27sc->mfi_enable_intr(sc);28} else {29if ((error = mfi_comms_init(sc)) != 0)30@@ -704,6 +707,7 @@ mfi_attach(struct mfi_softc *sc)31device_printf(sc->mfi_dev, "Cannot set up interrupt\n");32return (EINVAL);33}34+ sc->mfi_intr_ptr = mfi_intr;35sc->mfi_enable_intr(sc);36}37if ((error = mfi_get_controller_info(sc)) != 0)38@@ -1278,6 +1282,17 @@ mfi_shutdown(struct mfi_softc *sc)39struct mfi_command *cm;40int error;4142+43+ if (sc->mfi_aen_cm)44+ sc->cm_aen_abort = 1;45+ if (sc->mfi_aen_cm != NULL)46+ mfi_abort(sc, &sc->mfi_aen_cm);47+48+ if (sc->mfi_map_sync_cm)49+ sc->cm_map_abort = 1;50+ if (sc->mfi_map_sync_cm != NULL)51+ mfi_abort(sc, &sc->mfi_map_sync_cm);52+53mtx_lock(&sc->mfi_io_lock);54error = mfi_dcmd_command(sc, &cm, MFI_DCMD_CTRL_SHUTDOWN, NULL, 0);55if (error) {56@@ -1285,12 +1300,6 @@ mfi_shutdown(struct mfi_softc *sc)57return (error);58}5960- if (sc->mfi_aen_cm != NULL)61- mfi_abort(sc, sc->mfi_aen_cm);62-63- if (sc->mfi_map_sync_cm != NULL)64- mfi_abort(sc, sc->mfi_map_sync_cm);65-66dcmd = &cm->cm_frame->dcmd;67dcmd->header.flags = MFI_FRAME_DIR_NONE;68cm->cm_flags = MFI_CMD_POLLED;69@@ -1312,6 +1321,7 @@ mfi_syspdprobe(struct mfi_softc *sc)70struct mfi_command *cm = NULL;71struct mfi_pd_list *pdlist = NULL;72struct mfi_system_pd *syspd, *tmp;73+ struct mfi_system_pending *syspd_pend;74int error, i, found;7576sx_assert(&sc->mfi_config_lock, SA_XLOCKED);77@@ -1352,6 +1362,10 @@ mfi_syspdprobe(struct mfi_softc *sc)78if (syspd->pd_id == pdlist->addr[i].device_id)79found = 1;80}81+ TAILQ_FOREACH(syspd_pend, &sc->mfi_syspd_pend_tqh, pd_link) {82+ if (syspd_pend->pd_id == pdlist->addr[i].device_id)83+ found = 1;84+ }85if (found == 0)86mfi_add_sys_pd(sc, pdlist->addr[i].device_id);87}88@@ -1387,6 +1401,7 @@ mfi_ldprobe(struct mfi_softc *sc)89struct mfi_command *cm = NULL;90struct mfi_ld_list *list = NULL;91struct mfi_disk *ld;92+ struct mfi_disk_pending *ld_pend;93int error, i;9495sx_assert(&sc->mfi_config_lock, SA_XLOCKED);96@@ -1415,6 +1430,10 @@ mfi_ldprobe(struct mfi_softc *sc)97if (ld->ld_id == list->ld_list[i].ld.v.target_id)98goto skip_add;99}100+ TAILQ_FOREACH(ld_pend, &sc->mfi_ld_pend_tqh, ld_link) {101+ if (ld_pend->ld_id == list->ld_list[i].ld.v.target_id)102+ goto skip_add;103+ }104mfi_add_ld(sc, list->ld_list[i].ld.v.target_id);105skip_add:;106}107@@ -1617,9 +1636,7 @@ mfi_aen_register(struct mfi_softc *sc, int seq, in108< current_aen.members.evt_class)109current_aen.members.evt_class =110prior_aen.members.evt_class;111- mtx_lock(&sc->mfi_io_lock);112- mfi_abort(sc, sc->mfi_aen_cm);113- mtx_unlock(&sc->mfi_io_lock);114+ mfi_abort(sc, &sc->mfi_aen_cm);115}116}117118@@ -1811,10 +1828,17 @@ mfi_add_ld(struct mfi_softc *sc, int id)119struct mfi_command *cm;120struct mfi_dcmd_frame *dcmd = NULL;121struct mfi_ld_info *ld_info = NULL;122+ struct mfi_disk_pending *ld_pend;123int error;124125mtx_assert(&sc->mfi_io_lock, MA_OWNED);126127+ ld_pend = malloc(sizeof(*ld_pend), M_MFIBUF, M_NOWAIT | M_ZERO);128+ if (ld_pend != NULL) {129+ ld_pend->ld_id = id;130+ TAILQ_INSERT_TAIL(&sc->mfi_ld_pend_tqh, ld_pend, ld_link);131+ }132+133error = mfi_dcmd_command(sc, &cm, MFI_DCMD_LD_GET_INFO,134(void **)&ld_info, sizeof(*ld_info));135if (error) {136@@ -1855,11 +1879,13 @@ mfi_add_ld_complete(struct mfi_command *cm)137hdr = &cm->cm_frame->header;138ld_info = cm->cm_private;139140- if (hdr->cmd_status != MFI_STAT_OK) {141+ if (sc->cm_map_abort || hdr->cmd_status != MFI_STAT_OK) {142free(ld_info, M_MFIBUF);143+ wakeup(&sc->mfi_map_sync_cm);144mfi_release_command(cm);145return;146}147+ wakeup(&sc->mfi_map_sync_cm);148mfi_release_command(cm);149150mtx_unlock(&sc->mfi_io_lock);151@@ -1884,10 +1910,17 @@ static int mfi_add_sys_pd(struct mfi_softc *sc, in152struct mfi_command *cm;153struct mfi_dcmd_frame *dcmd = NULL;154struct mfi_pd_info *pd_info = NULL;155+ struct mfi_system_pending *syspd_pend;156int error;157158mtx_assert(&sc->mfi_io_lock, MA_OWNED);159160+ syspd_pend = malloc(sizeof(*syspd_pend), M_MFIBUF, M_NOWAIT | M_ZERO);161+ if (syspd_pend != NULL) {162+ syspd_pend->pd_id = id;163+ TAILQ_INSERT_TAIL(&sc->mfi_syspd_pend_tqh, syspd_pend, pd_link);164+ }165+166error = mfi_dcmd_command(sc, &cm, MFI_DCMD_PD_GET_INFO,167(void **)&pd_info, sizeof(*pd_info));168if (error) {169@@ -1981,19 +2014,87 @@ mfi_bio_command(struct mfi_softc *sc)170mfi_enqueue_bio(sc, bio);171return cm;172}173+174+/*175+ * mostly copied from cam/scsi/scsi_all.c:scsi_read_write176+ */177+178+int179+mfi_build_cdb(int readop, uint8_t byte2, u_int64_t lba, u_int32_t block_count, uint8_t *cdb)180+{181+ int cdb_len;182+183+ if (((lba & 0x1fffff) == lba)184+ && ((block_count & 0xff) == block_count)185+ && (byte2 == 0)) {186+ /* We can fit in a 6 byte cdb */187+ struct scsi_rw_6 *scsi_cmd;188+189+ scsi_cmd = (struct scsi_rw_6 *)cdb;190+ scsi_cmd->opcode = readop ? READ_6 : WRITE_6;191+ scsi_ulto3b(lba, scsi_cmd->addr);192+ scsi_cmd->length = block_count & 0xff;193+ scsi_cmd->control = 0;194+ cdb_len = sizeof(*scsi_cmd);195+ } else if (((block_count & 0xffff) == block_count) && ((lba & 0xffffffff) == lba)) {196+ /* Need a 10 byte CDB */197+ struct scsi_rw_10 *scsi_cmd;198+199+ scsi_cmd = (struct scsi_rw_10 *)cdb;200+ scsi_cmd->opcode = readop ? READ_10 : WRITE_10;201+ scsi_cmd->byte2 = byte2;202+ scsi_ulto4b(lba, scsi_cmd->addr);203+ scsi_cmd->reserved = 0;204+ scsi_ulto2b(block_count, scsi_cmd->length);205+ scsi_cmd->control = 0;206+ cdb_len = sizeof(*scsi_cmd);207+ } else if (((block_count & 0xffffffff) == block_count) &&208+ ((lba & 0xffffffff) == lba)) {209+ /* Block count is too big for 10 byte CDB use a 12 byte CDB */210+ struct scsi_rw_12 *scsi_cmd;211+212+ scsi_cmd = (struct scsi_rw_12 *)cdb;213+ scsi_cmd->opcode = readop ? READ_12 : WRITE_12;214+ scsi_cmd->byte2 = byte2;215+ scsi_ulto4b(lba, scsi_cmd->addr);216+ scsi_cmd->reserved = 0;217+ scsi_ulto4b(block_count, scsi_cmd->length);218+ scsi_cmd->control = 0;219+ cdb_len = sizeof(*scsi_cmd);220+ } else {221+ /*222+ * 16 byte CDB. We'll only get here if the LBA is larger223+ * than 2^32224+ */225+ struct scsi_rw_16 *scsi_cmd;226+227+ scsi_cmd = (struct scsi_rw_16 *)cdb;228+ scsi_cmd->opcode = readop ? READ_16 : WRITE_16;229+ scsi_cmd->byte2 = byte2;230+ scsi_u64to8b(lba, scsi_cmd->addr);231+ scsi_cmd->reserved = 0;232+ scsi_ulto4b(block_count, scsi_cmd->length);233+ scsi_cmd->control = 0;234+ cdb_len = sizeof(*scsi_cmd);235+ }236+237+ return cdb_len;238+}239+240static struct mfi_command *241mfi_build_syspdio(struct mfi_softc *sc, struct bio *bio)242{243struct mfi_command *cm;244struct mfi_pass_frame *pass;245- int flags = 0, blkcount = 0;246uint32_t context = 0;247+ int flags = 0, blkcount = 0, readop;248+ uint8_t cdb_len;249250if ((cm = mfi_dequeue_free(sc)) == NULL)251return (NULL);252253/* Zero out the MFI frame */254- context = cm->cm_frame->header.context;255+ context = cm->cm_frame->header.context;256bzero(cm->cm_frame, sizeof(union mfi_frame));257cm->cm_frame->header.context = context;258pass = &cm->cm_frame->pass;259@@ -2001,35 +2102,31 @@ mfi_build_syspdio(struct mfi_softc *sc, struct bio260pass->header.cmd = MFI_CMD_PD_SCSI_IO;261switch (bio->bio_cmd & 0x03) {262case BIO_READ:263-#define SCSI_READ 0x28264- pass->cdb[0] = SCSI_READ;265flags = MFI_CMD_DATAIN;266+ readop = 1;267break;268case BIO_WRITE:269-#define SCSI_WRITE 0x2a270- pass->cdb[0] = SCSI_WRITE;271flags = MFI_CMD_DATAOUT;272+ readop = 0;273break;274default:275- panic("Invalid bio command");276+ /* TODO: what about BIO_DELETE??? */277+ panic("Unsupported bio command %x\n", bio->bio_cmd);278}279280/* Cheat with the sector length to avoid a non-constant division */281blkcount = (bio->bio_bcount + MFI_SECTOR_LEN - 1) / MFI_SECTOR_LEN;282/* Fill the LBA and Transfer length in CDB */283- pass->cdb[2] = (bio->bio_pblkno & 0xff000000) >> 24;284- pass->cdb[3] = (bio->bio_pblkno & 0x00ff0000) >> 16;285- pass->cdb[4] = (bio->bio_pblkno & 0x0000ff00) >> 8;286- pass->cdb[5] = bio->bio_pblkno & 0x000000ff;287- pass->cdb[7] = (blkcount & 0xff00) >> 8;288- pass->cdb[8] = (blkcount & 0x00ff);289+ cdb_len = mfi_build_cdb(readop, 0, bio->bio_pblkno, blkcount,290+ pass->cdb);291pass->header.target_id = (uintptr_t)bio->bio_driver1;292+ pass->header.lun_id = 0;293pass->header.timeout = 0;294pass->header.flags = 0;295pass->header.scsi_status = 0;296pass->header.sense_len = MFI_SENSE_LEN;297pass->header.data_len = bio->bio_bcount;298- pass->header.cdb_len = 10;299+ pass->header.cdb_len = cdb_len;300pass->sense_addr_lo = (uint32_t)cm->cm_sense_busaddr;301pass->sense_addr_hi = (uint32_t)((uint64_t)cm->cm_sense_busaddr >> 32);302cm->cm_complete = mfi_bio_complete;303@@ -2047,7 +2144,8 @@ mfi_build_ldio(struct mfi_softc *sc, struct bio *b304{305struct mfi_io_frame *io;306struct mfi_command *cm;307- int flags, blkcount;308+ int flags;309+ uint32_t blkcount;310uint32_t context = 0;311312if ((cm = mfi_dequeue_free(sc)) == NULL)313@@ -2068,7 +2166,8 @@ mfi_build_ldio(struct mfi_softc *sc, struct bio *b314flags = MFI_CMD_DATAOUT;315break;316default:317- panic("Invalid bio command");318+ /* TODO: what about BIO_DELETE??? */319+ panic("Unsupported bio command %x\n", bio->bio_cmd);320}321322/* Cheat with the sector length to avoid a non-constant division */323@@ -2358,7 +2457,7 @@ mfi_complete(struct mfi_softc *sc, struct mfi_comm324}325326static int327-mfi_abort(struct mfi_softc *sc, struct mfi_command *cm_abort)328+mfi_abort(struct mfi_softc *sc, struct mfi_command **cm_abort)329{330struct mfi_command *cm;331struct mfi_abort_frame *abort;332@@ -2365,8 +2464,7 @@ static int333int i = 0;334uint32_t context = 0;335336- mtx_assert(&sc->mfi_io_lock, MA_OWNED);337-338+ mtx_lock(&sc->mfi_io_lock);339if ((cm = mfi_dequeue_free(sc)) == NULL) {340return (EBUSY);341}342@@ -2380,29 +2478,27 @@ static int343abort->header.cmd = MFI_CMD_ABORT;344abort->header.flags = 0;345abort->header.scsi_status = 0;346- abort->abort_context = cm_abort->cm_frame->header.context;347- abort->abort_mfi_addr_lo = (uint32_t)cm_abort->cm_frame_busaddr;348+ abort->abort_context = (*cm_abort)->cm_frame->header.context;349+ abort->abort_mfi_addr_lo = (uint32_t)(*cm_abort)->cm_frame_busaddr;350abort->abort_mfi_addr_hi =351- (uint32_t)((uint64_t)cm_abort->cm_frame_busaddr >> 32);352+ (uint32_t)((uint64_t)(*cm_abort)->cm_frame_busaddr >> 32);353cm->cm_data = NULL;354cm->cm_flags = MFI_CMD_POLLED;355356- if (sc->mfi_aen_cm)357- sc->cm_aen_abort = 1;358- if (sc->mfi_map_sync_cm)359- sc->cm_map_abort = 1;360mfi_mapcmd(sc, cm);361mfi_release_command(cm);362363- while (i < 5 && sc->mfi_aen_cm != NULL) {364- msleep(&sc->mfi_aen_cm, &sc->mfi_io_lock, 0, "mfiabort",365+ mtx_unlock(&sc->mfi_io_lock);366+ while (i < 5 && *cm_abort != NULL) {367+ tsleep(cm_abort, 0, "mfiabort",3685 * hz);369i++;370}371- while (i < 5 && sc->mfi_map_sync_cm != NULL) {372- msleep(&sc->mfi_map_sync_cm, &sc->mfi_io_lock, 0, "mfiabort",373- 5 * hz);374- i++;375+ if (*cm_abort != NULL) {376+ /* Force a complete if command didn't abort */377+ mtx_lock(&sc->mfi_io_lock);378+ (*cm_abort)->cm_complete(*cm_abort);379+ mtx_unlock(&sc->mfi_io_lock);380}381382return (0);383@@ -2458,8 +2554,8 @@ mfi_dump_syspd_blocks(struct mfi_softc *sc, int id384{385struct mfi_command *cm;386struct mfi_pass_frame *pass;387- int error;388- int blkcount = 0;389+ int error, readop, cdb_len;390+ uint32_t blkcount;391392if ((cm = mfi_dequeue_free(sc)) == NULL)393return (EBUSY);394@@ -2467,14 +2563,10 @@ mfi_dump_syspd_blocks(struct mfi_softc *sc, int id395pass = &cm->cm_frame->pass;396bzero(pass->cdb, 16);397pass->header.cmd = MFI_CMD_PD_SCSI_IO;398- pass->cdb[0] = SCSI_WRITE;399- pass->cdb[2] = (lba & 0xff000000) >> 24;400- pass->cdb[3] = (lba & 0x00ff0000) >> 16;401- pass->cdb[4] = (lba & 0x0000ff00) >> 8;402- pass->cdb[5] = (lba & 0x000000ff);403+404+ readop = 0;405blkcount = (len + MFI_SECTOR_LEN - 1) / MFI_SECTOR_LEN;406- pass->cdb[7] = (blkcount & 0xff00) >> 8;407- pass->cdb[8] = (blkcount & 0x00ff);408+ cdb_len = mfi_build_cdb(readop, 0, lba, blkcount, pass->cdb);409pass->header.target_id = id;410pass->header.timeout = 0;411pass->header.flags = 0;412@@ -2481,7 +2573,7 @@ mfi_dump_syspd_blocks(struct mfi_softc *sc, int id413pass->header.scsi_status = 0;414pass->header.sense_len = MFI_SENSE_LEN;415pass->header.data_len = len;416- pass->header.cdb_len = 10;417+ pass->header.cdb_len = cdb_len;418pass->sense_addr_lo = (uint32_t)cm->cm_sense_busaddr;419pass->sense_addr_hi = (uint32_t)((uint64_t)cm->cm_sense_busaddr >> 32);420cm->cm_data = virt;421@@ -2488,7 +2580,7 @@ mfi_dump_syspd_blocks(struct mfi_softc *sc, int id422cm->cm_len = len;423cm->cm_sg = &pass->sgl;424cm->cm_total_frame_size = MFI_PASS_FRAME_SIZE;425- cm->cm_flags = MFI_CMD_POLLED | MFI_CMD_DATAOUT;426+ cm->cm_flags = MFI_CMD_POLLED | MFI_CMD_DATAOUT | MFI_CMD_SCSI;427428error = mfi_mapcmd(sc, cm);429bus_dmamap_sync(sc->mfi_buffer_dmat, cm->cm_dmamap,430@@ -2687,16 +2779,24 @@ mfi_check_command_post(struct mfi_softc *sc, struc431}432}433434-static int mfi_check_for_sscd(struct mfi_softc *sc, struct mfi_command *cm)435+static int436+mfi_check_for_sscd(struct mfi_softc *sc, struct mfi_command *cm)437{438- struct mfi_config_data *conf_data=(struct mfi_config_data *)cm->cm_data;439+ struct mfi_config_data *conf_data;440struct mfi_command *ld_cm = NULL;441struct mfi_ld_info *ld_info = NULL;442+ struct mfi_ld_config *ld;443+ char *p;444int error = 0;445446- if ((cm->cm_frame->dcmd.opcode == MFI_DCMD_CFG_ADD) &&447- (conf_data->ld[0].params.isSSCD == 1)) {448- error = 1;449+ conf_data = (struct mfi_config_data *)cm->cm_data;450+451+ if (cm->cm_frame->dcmd.opcode == MFI_DCMD_CFG_ADD) {452+ p = (char *)conf_data->array;453+ p += conf_data->array_size * conf_data->array_count;454+ ld = (struct mfi_ld_config *)p;455+ if (ld->params.isSSCD == 1)456+ error = 1;457} else if (cm->cm_frame->dcmd.opcode == MFI_DCMD_LD_DELETE) {458error = mfi_dcmd_command (sc, &ld_cm, MFI_DCMD_LD_GET_INFO,459(void **)&ld_info, sizeof(*ld_info));460Index: sys/dev/mfi/mfi_cam.c461===================================================================462--- sys/dev/mfi/mfi_cam.c (revision 254079)463+++ sys/dev/mfi/mfi_cam.c (working copy)464@@ -79,6 +79,11 @@ static void mfip_cam_poll(struct cam_sim *);465static struct mfi_command * mfip_start(void *);466static void mfip_done(struct mfi_command *cm);467468+static int mfi_allow_disks = 0;469+TUNABLE_INT("hw.mfi.allow_cam_disk_passthrough", &mfi_allow_disks);470+SYSCTL_INT(_hw_mfi, OID_AUTO, allow_cam_disk_passthrough, CTLFLAG_RD,471+ &mfi_allow_disks, 0, "event message locale");472+473static devclass_t mfip_devclass;474static device_method_t mfip_methods[] = {475DEVMETHOD(device_probe, mfip_probe),476@@ -349,7 +354,8 @@ mfip_done(struct mfi_command *cm)477command = csio->cdb_io.cdb_bytes[0];478if (command == INQUIRY) {479device = csio->data_ptr[0] & 0x1f;480- if ((device == T_DIRECT) || (device == T_PROCESSOR))481+ if ((!mfi_allow_disks && device == T_DIRECT) ||482+ (device == T_PROCESSOR))483csio->data_ptr[0] =484(csio->data_ptr[0] & 0xe0) | T_NODEVICE;485}486@@ -392,6 +398,9 @@ mfip_done(struct mfi_command *cm)487static void488mfip_cam_poll(struct cam_sim *sim)489{490- return;491+ struct mfip_softc *sc = cam_sim_softc(sim);492+ struct mfi_softc *mfisc = sc->mfi_sc;493+494+ mfisc->mfi_intr_ptr(mfisc);495}496497Index: sys/dev/mfi/mfi_disk.c498===================================================================499--- sys/dev/mfi/mfi_disk.c (revision 254079)500+++ sys/dev/mfi/mfi_disk.c (working copy)501@@ -93,6 +93,7 @@ mfi_disk_attach(device_t dev)502{503struct mfi_disk *sc;504struct mfi_ld_info *ld_info;505+ struct mfi_disk_pending *ld_pend;506uint64_t sectors;507uint32_t secsize;508char *state;509@@ -111,6 +112,13 @@ mfi_disk_attach(device_t dev)510secsize = MFI_SECTOR_LEN;511mtx_lock(&sc->ld_controller->mfi_io_lock);512TAILQ_INSERT_TAIL(&sc->ld_controller->mfi_ld_tqh, sc, ld_link);513+ TAILQ_FOREACH(ld_pend, &sc->ld_controller->mfi_ld_pend_tqh,514+ ld_link) {515+ TAILQ_REMOVE(&sc->ld_controller->mfi_ld_pend_tqh,516+ ld_pend, ld_link);517+ free(ld_pend, M_MFIBUF);518+ break;519+ }520mtx_unlock(&sc->ld_controller->mfi_io_lock);521522switch (ld_info->ld_config.params.state) {523@@ -131,16 +139,16 @@ mfi_disk_attach(device_t dev)524break;525}526527- if ( strlen(ld_info->ld_config.properties.name) == 0 ) {528- device_printf(dev,529- "%juMB (%ju sectors) RAID volume (no label) is %s\n",530- sectors / (1024 * 1024 / secsize), sectors, state);531- } else {532- device_printf(dev,533- "%juMB (%ju sectors) RAID volume '%s' is %s\n",534- sectors / (1024 * 1024 / secsize), sectors,535- ld_info->ld_config.properties.name, state);536- }537+ if ( strlen(ld_info->ld_config.properties.name) == 0 ) {538+ device_printf(dev,539+ "%juMB (%ju sectors) RAID volume (no label) is %s\n",540+ sectors / (1024 * 1024 / secsize), sectors, state);541+ } else {542+ device_printf(dev,543+ "%juMB (%ju sectors) RAID volume '%s' is %s\n",544+ sectors / (1024 * 1024 / secsize), sectors,545+ ld_info->ld_config.properties.name, state);546+ }547548sc->ld_disk = disk_alloc();549sc->ld_disk->d_drv1 = sc;550Index: sys/dev/mfi/mfi_syspd.c551===================================================================552--- sys/dev/mfi/mfi_syspd.c (revision 254079)553+++ sys/dev/mfi/mfi_syspd.c (working copy)554@@ -89,7 +89,6 @@ DRIVER_MODULE(mfisyspd, mfi, mfi_syspd_driver, mfi555static int556mfi_syspd_probe(device_t dev)557{558-559return (0);560}561562@@ -98,12 +97,12 @@ mfi_syspd_attach(device_t dev)563{564struct mfi_system_pd *sc;565struct mfi_pd_info *pd_info;566+ struct mfi_system_pending *syspd_pend;567uint64_t sectors;568uint32_t secsize;569570sc = device_get_softc(dev);571pd_info = device_get_ivars(dev);572-573sc->pd_dev = dev;574sc->pd_id = pd_info->ref.v.device_id;575sc->pd_unit = device_get_unit(dev);576@@ -115,6 +114,13 @@ mfi_syspd_attach(device_t dev)577secsize = MFI_SECTOR_LEN;578mtx_lock(&sc->pd_controller->mfi_io_lock);579TAILQ_INSERT_TAIL(&sc->pd_controller->mfi_syspd_tqh, sc, pd_link);580+ TAILQ_FOREACH(syspd_pend, &sc->pd_controller->mfi_syspd_pend_tqh,581+ pd_link) {582+ TAILQ_REMOVE(&sc->pd_controller->mfi_syspd_pend_tqh,583+ syspd_pend, pd_link);584+ free(syspd_pend, M_MFIBUF);585+ break;586+ }587mtx_unlock(&sc->pd_controller->mfi_io_lock);588device_printf(dev, "%juMB (%ju sectors) SYSPD volume\n",589sectors / (1024 * 1024 / secsize), sectors);590@@ -139,6 +145,7 @@ mfi_syspd_attach(device_t dev)591disk_create(sc->pd_disk, DISK_VERSION);592593device_printf(dev, " SYSPD volume attached\n");594+595return (0);596}597598Index: sys/dev/mfi/mfi_tbolt.c599===================================================================600--- sys/dev/mfi/mfi_tbolt.c (revision 254079)601+++ sys/dev/mfi/mfi_tbolt.c (working copy)602@@ -69,13 +69,10 @@ uint8_t603mfi_build_mpt_pass_thru(struct mfi_softc *sc, struct mfi_command *mfi_cmd);604union mfi_mpi2_request_descriptor *mfi_build_and_issue_cmd(struct mfi_softc605*sc, struct mfi_command *mfi_cmd);606-int mfi_tbolt_is_ldio(struct mfi_command *mfi_cmd);607void mfi_tbolt_build_ldio(struct mfi_softc *sc, struct mfi_command *mfi_cmd,608struct mfi_cmd_tbolt *cmd);609static int mfi_tbolt_make_sgl(struct mfi_softc *sc, struct mfi_command610*mfi_cmd, pMpi25IeeeSgeChain64_t sgl_ptr, struct mfi_cmd_tbolt *cmd);611-static int mfi_tbolt_build_cdb(struct mfi_softc *sc, struct mfi_command612- *mfi_cmd, uint8_t *cdb);613void614map_tbolt_cmd_status(struct mfi_command *mfi_cmd, uint8_t status,615uint8_t ext_status);616@@ -502,6 +499,7 @@ mfi_tbolt_alloc_cmd(struct mfi_softc *sc)617+ i * MEGASAS_MAX_SZ_CHAIN_FRAME);618cmd->sg_frame_phys_addr = sc->sg_frame_busaddr + i619* MEGASAS_MAX_SZ_CHAIN_FRAME;620+ cmd->sync_cmd_idx = sc->mfi_max_fw_cmds;621622TAILQ_INSERT_TAIL(&(sc->mfi_cmd_tbolt_tqh), cmd, next);623}624@@ -574,11 +572,11 @@ void625map_tbolt_cmd_status(struct mfi_command *mfi_cmd, uint8_t status,626uint8_t ext_status)627{628-629switch (status) {630case MFI_STAT_OK:631- mfi_cmd->cm_frame->header.cmd_status = 0;632- mfi_cmd->cm_frame->dcmd.header.cmd_status = 0;633+ mfi_cmd->cm_frame->header.cmd_status = MFI_STAT_OK;634+ mfi_cmd->cm_frame->dcmd.header.cmd_status = MFI_STAT_OK;635+ mfi_cmd->cm_error = MFI_STAT_OK;636break;637638case MFI_STAT_SCSI_IO_FAILED:639@@ -618,6 +616,7 @@ mfi_tbolt_return_cmd(struct mfi_softc *sc, struct640{641mtx_assert(&sc->mfi_io_lock, MA_OWNED);642643+ cmd->sync_cmd_idx = sc->mfi_max_fw_cmds;644TAILQ_INSERT_TAIL(&sc->mfi_cmd_tbolt_tqh, cmd, next);645}646647@@ -667,16 +666,26 @@ mfi_tbolt_complete_cmd(struct mfi_softc *sc)648extStatus = cmd_mfi->cm_frame->dcmd.header.scsi_status;649map_tbolt_cmd_status(cmd_mfi, status, extStatus);650651- /* remove command from busy queue if not polled */652- TAILQ_FOREACH(cmd_mfi_check, &sc->mfi_busy, cm_link) {653- if (cmd_mfi_check == cmd_mfi) {654- mfi_remove_busy(cmd_mfi);655- break;656+ if (cmd_mfi->cm_flags & MFI_CMD_SCSI &&657+ (cmd_mfi->cm_flags & MFI_CMD_POLLED) != 0) {658+ /* polled LD/SYSPD IO command */659+ mfi_tbolt_return_cmd(sc, cmd_tbolt);660+ /* XXX mark okay for now DJA */661+ cmd_mfi->cm_frame->header.cmd_status = MFI_STAT_OK;662+ } else {663+664+ /* remove command from busy queue if not polled */665+ TAILQ_FOREACH(cmd_mfi_check, &sc->mfi_busy, cm_link) {666+ if (cmd_mfi_check == cmd_mfi) {667+ mfi_remove_busy(cmd_mfi);668+ break;669+ }670}671+672+ /* complete the command */673+ mfi_complete(sc, cmd_mfi);674+ mfi_tbolt_return_cmd(sc, cmd_tbolt);675}676- cmd_mfi->cm_error = 0;677- mfi_complete(sc, cmd_mfi);678- mfi_tbolt_return_cmd(sc, cmd_tbolt);679680sc->last_reply_idx++;681if (sc->last_reply_idx >= sc->mfi_max_fw_cmds) {682@@ -811,13 +820,13 @@ mfi_tbolt_build_ldio(struct mfi_softc *sc, struct683MFI_FRAME_DIR_READ)684io_info.isRead = 1;685686- io_request->RaidContext.timeoutValue687- = MFI_FUSION_FP_DEFAULT_TIMEOUT;688- io_request->Function = MPI2_FUNCTION_LD_IO_REQUEST;689- io_request->DevHandle = device_id;690- cmd->request_desc->header.RequestFlags691- = (MFI_REQ_DESCRIPT_FLAGS_LD_IO692- << MFI_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);693+ io_request->RaidContext.timeoutValue694+ = MFI_FUSION_FP_DEFAULT_TIMEOUT;695+ io_request->Function = MPI2_FUNCTION_LD_IO_REQUEST;696+ io_request->DevHandle = device_id;697+ cmd->request_desc->header.RequestFlags698+ = (MFI_REQ_DESCRIPT_FLAGS_LD_IO699+ << MFI_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);700if ((io_request->IoFlags == 6) && (io_info.numBlocks == 0))701io_request->RaidContext.RegLockLength = 0x100;702io_request->DataLength = mfi_cmd->cm_frame->io.header.data_len703@@ -825,41 +834,37 @@ mfi_tbolt_build_ldio(struct mfi_softc *sc, struct704}705706int707-mfi_tbolt_is_ldio(struct mfi_command *mfi_cmd)708-{709- if (mfi_cmd->cm_frame->header.cmd == MFI_CMD_LD_READ710- || mfi_cmd->cm_frame->header.cmd == MFI_CMD_LD_WRITE)711- return 1;712- else713- return 0;714-}715-716-int717mfi_tbolt_build_io(struct mfi_softc *sc, struct mfi_command *mfi_cmd,718struct mfi_cmd_tbolt *cmd)719{720- uint32_t device_id;721+ struct mfi_mpi2_request_raid_scsi_io *io_request;722uint32_t sge_count;723- uint8_t cdb[32], cdb_len;724+ uint8_t cdb_len;725+ int readop;726+ u_int64_t lba;727728- memset(cdb, 0, 32);729- struct mfi_mpi2_request_raid_scsi_io *io_request = cmd->io_request;730+ io_request = cmd->io_request;731+ if (!(mfi_cmd->cm_frame->header.cmd == MFI_CMD_LD_READ732+ || mfi_cmd->cm_frame->header.cmd == MFI_CMD_LD_WRITE))733+ return 1;734735- device_id = mfi_cmd->cm_frame->header.target_id;736+ mfi_tbolt_build_ldio(sc, mfi_cmd, cmd);737738- /* Have to build CDB here for TB as BSD don't have a scsi layer */739- if ((cdb_len = mfi_tbolt_build_cdb(sc, mfi_cmd, cdb)) == 1)740- return 1;741+ /* Convert to SCSI command CDB */742+ bzero(io_request->CDB.CDB32, sizeof(io_request->CDB.CDB32));743+ if (mfi_cmd->cm_frame->header.cmd == MFI_CMD_LD_WRITE)744+ readop = 0;745+ else746+ readop = 1;747748- /* Just the CDB length,rest of the Flags are zero */749+ lba = mfi_cmd->cm_frame->io.lba_hi;750+ lba = (lba << 32) + mfi_cmd->cm_frame->io.lba_lo;751+ cdb_len = mfi_build_cdb(readop, 0, lba,752+ mfi_cmd->cm_frame->io.header.data_len, io_request->CDB.CDB32);753+754+ /* Just the CDB length, rest of the Flags are zero */755io_request->IoFlags = cdb_len;756- memcpy(io_request->CDB.CDB32, cdb, 32);757758- if (mfi_tbolt_is_ldio(mfi_cmd))759- mfi_tbolt_build_ldio(sc, mfi_cmd , cmd);760- else761- return 1;762-763/*764* Construct SGL765*/766@@ -883,85 +888,13 @@ mfi_tbolt_build_io(struct mfi_softc *sc, struct mf767768io_request->SenseBufferLowAddress = mfi_cmd->cm_sense_busaddr;769io_request->SenseBufferLength = MFI_SENSE_LEN;770+ io_request->RaidContext.Status = MFI_STAT_INVALID_STATUS;771+ io_request->RaidContext.exStatus = MFI_STAT_INVALID_STATUS;772+773return 0;774}775776-static int777-mfi_tbolt_build_cdb(struct mfi_softc *sc, struct mfi_command *mfi_cmd,778- uint8_t *cdb)779-{780- uint32_t lba_lo, lba_hi, num_lba;781- uint8_t cdb_len;782783- if (mfi_cmd == NULL || cdb == NULL)784- return 1;785- num_lba = mfi_cmd->cm_frame->io.header.data_len;786- lba_lo = mfi_cmd->cm_frame->io.lba_lo;787- lba_hi = mfi_cmd->cm_frame->io.lba_hi;788-789- if (lba_hi == 0 && (num_lba <= 0xFF) && (lba_lo <= 0x1FFFFF)) {790- if (mfi_cmd->cm_frame->header.cmd == MFI_CMD_LD_WRITE)791- /* Read 6 or Write 6 */792- cdb[0] = (uint8_t) (0x0A);793- else794- cdb[0] = (uint8_t) (0x08);795-796- cdb[4] = (uint8_t) num_lba;797- cdb[3] = (uint8_t) (lba_lo & 0xFF);798- cdb[2] = (uint8_t) (lba_lo >> 8);799- cdb[1] = (uint8_t) ((lba_lo >> 16) & 0x1F);800- cdb_len = 6;801- }802- else if (lba_hi == 0 && (num_lba <= 0xFFFF) && (lba_lo <= 0xFFFFFFFF)) {803- if (mfi_cmd->cm_frame->header.cmd == MFI_CMD_LD_WRITE)804- /* Read 10 or Write 10 */805- cdb[0] = (uint8_t) (0x2A);806- else807- cdb[0] = (uint8_t) (0x28);808- cdb[8] = (uint8_t) (num_lba & 0xFF);809- cdb[7] = (uint8_t) (num_lba >> 8);810- cdb[5] = (uint8_t) (lba_lo & 0xFF);811- cdb[4] = (uint8_t) (lba_lo >> 8);812- cdb[3] = (uint8_t) (lba_lo >> 16);813- cdb[2] = (uint8_t) (lba_lo >> 24);814- cdb_len = 10;815- } else if ((num_lba > 0xFFFF) && (lba_hi == 0)) {816- if (mfi_cmd->cm_frame->header.cmd == MFI_CMD_LD_WRITE)817- /* Read 12 or Write 12 */818- cdb[0] = (uint8_t) (0xAA);819- else820- cdb[0] = (uint8_t) (0xA8);821- cdb[9] = (uint8_t) (num_lba & 0xFF);822- cdb[8] = (uint8_t) (num_lba >> 8);823- cdb[7] = (uint8_t) (num_lba >> 16);824- cdb[6] = (uint8_t) (num_lba >> 24);825- cdb[5] = (uint8_t) (lba_lo & 0xFF);826- cdb[4] = (uint8_t) (lba_lo >> 8);827- cdb[3] = (uint8_t) (lba_lo >> 16);828- cdb[2] = (uint8_t) (lba_lo >> 24);829- cdb_len = 12;830- } else {831- if (mfi_cmd->cm_frame->header.cmd == MFI_CMD_LD_WRITE)832- cdb[0] = (uint8_t) (0x8A);833- else834- cdb[0] = (uint8_t) (0x88);835- cdb[13] = (uint8_t) (num_lba & 0xFF);836- cdb[12] = (uint8_t) (num_lba >> 8);837- cdb[11] = (uint8_t) (num_lba >> 16);838- cdb[10] = (uint8_t) (num_lba >> 24);839- cdb[9] = (uint8_t) (lba_lo & 0xFF);840- cdb[8] = (uint8_t) (lba_lo >> 8);841- cdb[7] = (uint8_t) (lba_lo >> 16);842- cdb[6] = (uint8_t) (lba_lo >> 24);843- cdb[5] = (uint8_t) (lba_hi & 0xFF);844- cdb[4] = (uint8_t) (lba_hi >> 8);845- cdb[3] = (uint8_t) (lba_hi >> 16);846- cdb[2] = (uint8_t) (lba_hi >> 24);847- cdb_len = 16;848- }849- return cdb_len;850-}851-852static int853mfi_tbolt_make_sgl(struct mfi_softc *sc, struct mfi_command *mfi_cmd,854pMpi25IeeeSgeChain64_t sgl_ptr, struct mfi_cmd_tbolt *cmd)855@@ -1100,8 +1033,7 @@ mfi_tbolt_send_frame(struct mfi_softc *sc, struct856if ((cm->cm_flags & MFI_CMD_POLLED) == 0) {857cm->cm_timestamp = time_uptime;858mfi_enqueue_busy(cm);859- }860- else { /* still get interrupts for it */861+ } else { /* still get interrupts for it */862hdr->cmd_status = MFI_STAT_INVALID_STATUS;863hdr->flags |= MFI_FRAME_DONT_POST_IN_REPLY_QUEUE;864}865@@ -1118,19 +1050,28 @@ mfi_tbolt_send_frame(struct mfi_softc *sc, struct866}867else868device_printf(sc->mfi_dev, "DJA NA XXX SYSPDIO\n");869- }870- else if (hdr->cmd == MFI_CMD_LD_SCSI_IO ||871+ } else if (hdr->cmd == MFI_CMD_LD_SCSI_IO ||872hdr->cmd == MFI_CMD_LD_READ || hdr->cmd == MFI_CMD_LD_WRITE) {873+ cm->cm_flags |= MFI_CMD_SCSI;874if ((req_desc = mfi_build_and_issue_cmd(sc, cm)) == NULL) {875device_printf(sc->mfi_dev, "LDIO Failed \n");876return 1;877}878- } else879- if ((req_desc = mfi_tbolt_build_mpt_cmd(sc, cm)) == NULL) {880+ } else if ((req_desc = mfi_tbolt_build_mpt_cmd(sc, cm)) == NULL) {881device_printf(sc->mfi_dev, "Mapping from MFI to MPT "882"Failed\n");883return 1;884- }885+ }886+887+ if (cm->cm_flags & MFI_CMD_SCSI) {888+ /*889+ * LD IO needs to be posted since it doesn't get890+ * acknowledged via a status update so have the891+ * controller reply via mfi_tbolt_complete_cmd.892+ */893+ hdr->flags &= ~MFI_FRAME_DONT_POST_IN_REPLY_QUEUE;894+ }895+896MFI_WRITE4(sc, MFI_ILQP, (req_desc->words & 0xFFFFFFFF));897MFI_WRITE4(sc, MFI_IHQP, (req_desc->words >>0x20));898899@@ -1137,12 +1078,21 @@ mfi_tbolt_send_frame(struct mfi_softc *sc, struct900if ((cm->cm_flags & MFI_CMD_POLLED) == 0)901return 0;902903+ if (cm->cm_flags & MFI_CMD_SCSI) {904+ /* check reply queue */905+ mfi_tbolt_complete_cmd(sc);906+ }907+908/* This is a polled command, so busy-wait for it to complete. */909while (hdr->cmd_status == MFI_STAT_INVALID_STATUS) {910DELAY(1000);911tm -= 1;912if (tm <= 0)913- break;914+ break;915+ if (cm->cm_flags & MFI_CMD_SCSI) {916+ /* check reply queue */917+ mfi_tbolt_complete_cmd(sc);918+ }919}920921if (hdr->cmd_status == MFI_STAT_INVALID_STATUS) {922@@ -1375,7 +1325,7 @@ mfi_tbolt_sync_map_info(struct mfi_softc *sc)923free(ld_sync, M_MFIBUF);924goto out;925}926-927+928context = cmd->cm_frame->header.context;929bzero(cmd->cm_frame, sizeof(union mfi_frame));930cmd->cm_frame->header.context = context;931Index: sys/dev/mfi/mfivar.h932===================================================================933--- sys/dev/mfi/mfivar.h (revision 254079)934+++ sys/dev/mfi/mfivar.h (working copy)935@@ -105,6 +105,7 @@ struct mfi_command {936#define MFI_ON_MFIQ_READY (1<<6)937#define MFI_ON_MFIQ_BUSY (1<<7)938#define MFI_ON_MFIQ_MASK ((1<<5)|(1<<6)|(1<<7))939+#define MFI_CMD_SCSI (1<<8)940uint8_t retry_for_fw_reset;941void (* cm_complete)(struct mfi_command *cm);942void *cm_private;943@@ -125,6 +126,11 @@ struct mfi_disk {944#define MFI_DISK_FLAGS_DISABLED 0x02945};946947+struct mfi_disk_pending {948+ TAILQ_ENTRY(mfi_disk_pending) ld_link;949+ int ld_id;950+};951+952struct mfi_system_pd {953TAILQ_ENTRY(mfi_system_pd) pd_link;954device_t pd_dev;955@@ -136,6 +142,11 @@ struct mfi_system_pd {956int pd_flags;957};958959+struct mfi_system_pending {960+ TAILQ_ENTRY(mfi_system_pending) pd_link;961+ int pd_id;962+};963+964struct mfi_evt_queue_elm {965TAILQ_ENTRY(mfi_evt_queue_elm) link;966struct mfi_evt_detail detail;967@@ -284,6 +295,8 @@ struct mfi_softc {968969TAILQ_HEAD(,mfi_disk) mfi_ld_tqh;970TAILQ_HEAD(,mfi_system_pd) mfi_syspd_tqh;971+ TAILQ_HEAD(,mfi_disk_pending) mfi_ld_pend_tqh;972+ TAILQ_HEAD(,mfi_system_pending) mfi_syspd_pend_tqh;973eventhandler_tag mfi_eh;974struct cdev *mfi_cdev;975976@@ -302,6 +315,7 @@ struct mfi_softc {977uint32_t frame_cnt);978int (*mfi_adp_reset)(struct mfi_softc *sc);979int (*mfi_adp_check_reset)(struct mfi_softc *sc);980+ void (*mfi_intr_ptr)(void *sc);981982/* ThunderBolt */983uint32_t mfi_tbolt;984@@ -420,7 +434,8 @@ extern int mfi_tbolt_reset(struct mfi_softc *sc);985extern void mfi_tbolt_sync_map_info(struct mfi_softc *sc);986extern void mfi_handle_map_sync(void *context, int pending);987extern int mfi_dcmd_command(struct mfi_softc *, struct mfi_command **,988- uint32_t, void **, size_t);989+ uint32_t, void **, size_t);990+extern int mfi_build_cdb(int, uint8_t, u_int64_t, u_int32_t, uint8_t *);991992#define MFIQ_ADD(sc, qname) \993do { \994995996