Index: mfi.c =================================================================== RCS file: /usr/cvs/src/sys/dev/mfi/mfi.c,v retrieving revision 1.3.2.2 diff -u -r1.3.2.2 mfi.c --- mfi.c 15 Jun 2006 16:07:56 -0000 1.3.2.2 +++ mfi.c 17 Jul 2006 17:07:47 -0000 @@ -57,26 +57,25 @@ static void mfi_release_command(struct mfi_command *cm); static int mfi_comms_init(struct mfi_softc *); static int mfi_polled_command(struct mfi_softc *, struct mfi_command *); +static int mfi_wait_command(struct mfi_softc *, struct mfi_command *); static int mfi_get_controller_info(struct mfi_softc *); static int mfi_get_log_state(struct mfi_softc *, - struct mfi_evt_log_state *); + struct mfi_evt_log_state **); #ifdef NOTYET static int mfi_get_entry(struct mfi_softc *, int); #endif +static int mfi_dcmd_command(struct mfi_softc *, struct mfi_command **, + uint32_t, void **, size_t); static void mfi_data_cb(void *, bus_dma_segment_t *, int, int); static void mfi_startup(void *arg); static void mfi_intr(void *arg); static void mfi_enable_intr(struct mfi_softc *sc); -static void mfi_ldprobe_inq(struct mfi_softc *sc); -static void mfi_ldprobe_inq_complete(struct mfi_command *); -static int mfi_ldprobe_capacity(struct mfi_softc *sc, int id); -static void mfi_ldprobe_capacity_complete(struct mfi_command *); -static int mfi_ldprobe_tur(struct mfi_softc *sc, int id); -static void mfi_ldprobe_tur_complete(struct mfi_command *); +static void mfi_ldprobe(struct mfi_softc *sc); static int mfi_aen_register(struct mfi_softc *sc, int seq, int locale); static void mfi_aen_complete(struct mfi_command *); static int mfi_aen_setup(struct mfi_softc *, uint32_t); -static int mfi_add_ld(struct mfi_softc *sc, int id, uint64_t, uint32_t); +static int mfi_add_ld(struct mfi_softc *sc, int); +static void mfi_add_ld_complete(struct mfi_command *); static struct mfi_command * mfi_bio_command(struct mfi_softc *); static void mfi_bio_complete(struct mfi_command *); static int mfi_mapcmd(struct mfi_softc *, struct mfi_command *); @@ -442,6 +441,53 @@ } static int +mfi_dcmd_command(struct mfi_softc *sc, struct mfi_command **cmp, uint32_t opcode, + void **bufp, size_t bufsize) +{ + struct mfi_command *cm; + struct mfi_dcmd_frame *dcmd; + void *buf = NULL; + + mtx_assert(&sc->mfi_io_lock, MA_OWNED); + + cm = mfi_dequeue_free(sc); + if (cm == NULL) + return (EBUSY); + + if ((bufsize > 0) && (bufp != NULL)) { + if (*bufp == NULL) { + buf = malloc(bufsize, M_MFIBUF, M_NOWAIT|M_ZERO); + if (buf == NULL) { + mfi_release_command(cm); + return (ENOMEM); + } + *bufp = buf; + } else { + buf = *bufp; + } + } + + dcmd = &cm->cm_frame->dcmd; + bzero(dcmd->mbox, MFI_MBOX_SIZE); + dcmd->header.cmd = MFI_CMD_DCMD; + dcmd->header.timeout = 0; + dcmd->header.flags = 0; + dcmd->header.data_len = bufsize; + dcmd->opcode = opcode; + cm->cm_sg = &dcmd->sgl; + cm->cm_total_frame_size = MFI_DCMD_FRAME_SIZE; + cm->cm_flags = 0; + cm->cm_data = buf; + cm->cm_private = buf; + cm->cm_len = bufsize; + + *cmp = cm; + if ((bufp != NULL) && (*bufp == NULL) && (buf != NULL)) + *bufp = buf; + return (0); +} + +static int mfi_comms_init(struct mfi_softc *sc) { struct mfi_command *cm; @@ -484,35 +530,20 @@ static int mfi_get_controller_info(struct mfi_softc *sc) { - struct mfi_command *cm; - struct mfi_dcmd_frame *dcmd; - struct mfi_ctrl_info *ci; + struct mfi_command *cm = NULL; + struct mfi_ctrl_info *ci = NULL; uint32_t max_sectors_1, max_sectors_2; int error; - if ((cm = mfi_dequeue_free(sc)) == NULL) - return (EBUSY); - - ci = malloc(sizeof(struct mfi_ctrl_info), M_MFIBUF, M_NOWAIT | M_ZERO); - if (ci == NULL) { - mfi_release_command(cm); - return (ENOMEM); - } - - dcmd = &cm->cm_frame->dcmd; - bzero(dcmd->mbox, MFI_MBOX_SIZE); - dcmd->header.cmd = MFI_CMD_DCMD; - dcmd->header.timeout = 0; - dcmd->header.data_len = sizeof(struct mfi_ctrl_info); - dcmd->opcode = MFI_DCMD_CTRL_GETINFO; - cm->cm_sg = &dcmd->sgl; - cm->cm_total_frame_size = MFI_DCMD_FRAME_SIZE; + mtx_lock(&sc->mfi_io_lock); + error = mfi_dcmd_command(sc, &cm, MFI_DCMD_CTRL_GETINFO, + (void **)&ci, sizeof(*ci)); + if (error) + goto out; cm->cm_flags = MFI_CMD_DATAIN | MFI_CMD_POLLED; - cm->cm_data = ci; - cm->cm_len = sizeof(struct mfi_ctrl_info); if ((error = mfi_mapcmd(sc, cm)) != 0) { - device_printf(sc->mfi_dev, "Controller info buffer map failed"); + device_printf(sc->mfi_dev, "Controller info buffer map failed\n"); free(ci, M_MFIBUF); mfi_release_command(cm); return (error); @@ -523,9 +554,8 @@ device_printf(sc->mfi_dev, "Failed to get controller info\n"); sc->mfi_max_io = (sc->mfi_total_sgl - 1) * PAGE_SIZE / MFI_SECTOR_LEN; - free(ci, M_MFIBUF); - mfi_release_command(cm); - return (0); + error = 0; + goto out; } bus_dmamap_sync(sc->mfi_buffer_dmat, cm->cm_dmamap, @@ -536,55 +566,46 @@ max_sectors_2 = ci->max_request_size; sc->mfi_max_io = min(max_sectors_1, max_sectors_2); - free(ci, M_MFIBUF); - mfi_release_command(cm); - +out: + if (ci) + free(ci, M_MFIBUF); + if (cm) + mfi_release_command(cm); + mtx_unlock(&sc->mfi_io_lock); return (error); } static int -mfi_get_log_state(struct mfi_softc *sc, struct mfi_evt_log_state *log_state) +mfi_get_log_state(struct mfi_softc *sc, struct mfi_evt_log_state **log_state) { - struct mfi_command *cm; - struct mfi_dcmd_frame *dcmd; + struct mfi_command *cm = NULL; int error; - if ((cm = mfi_dequeue_free(sc)) == NULL) - return (EBUSY); - - - dcmd = &cm->cm_frame->dcmd; - bzero(dcmd->mbox, MFI_MBOX_SIZE); - dcmd->header.cmd = MFI_CMD_DCMD; - dcmd->header.timeout = 0; - dcmd->header.data_len = sizeof(struct mfi_evt_log_state); - dcmd->opcode = MFI_DCMD_CTRL_EVENT_GETINFO; - cm->cm_sg = &dcmd->sgl; - cm->cm_total_frame_size = MFI_DCMD_FRAME_SIZE; + mtx_lock(&sc->mfi_io_lock); + error = mfi_dcmd_command(sc, &cm, MFI_DCMD_CTRL_EVENT_GETINFO, + (void **)log_state, sizeof(**log_state)); + if (error) + goto out; cm->cm_flags = MFI_CMD_DATAIN | MFI_CMD_POLLED; - cm->cm_data = log_state; - cm->cm_len = sizeof(struct mfi_evt_log_state); if ((error = mfi_mapcmd(sc, cm)) != 0) { - device_printf(sc->mfi_dev, "Controller info buffer map failed"); - mfi_release_command(cm); - return (error); + device_printf(sc->mfi_dev, "Log state buffer map failed\n"); + goto out; } - /* It's ok if this fails, just use default info instead */ if ((error = mfi_polled_command(sc, cm)) != 0) { - device_printf(sc->mfi_dev, "Failed to get controller state\n"); - sc->mfi_max_io = (sc->mfi_total_sgl - 1) * PAGE_SIZE / - MFI_SECTOR_LEN; - mfi_release_command(cm); - return (0); + device_printf(sc->mfi_dev, "Failed to get log state\n"); + goto out; } bus_dmamap_sync(sc->mfi_buffer_dmat, cm->cm_dmamap, BUS_DMASYNC_POSTREAD); bus_dmamap_unload(sc->mfi_buffer_dmat, cm->cm_dmamap); - mfi_release_command(cm); +out: + if (cm) + mfi_release_command(cm); + mtx_unlock(&sc->mfi_io_lock); return (error); } @@ -592,7 +613,7 @@ static int mfi_aen_setup(struct mfi_softc *sc, uint32_t seq_start) { - struct mfi_evt_log_state log_state; + struct mfi_evt_log_state *log_state = NULL; union mfi_evt class_locale; int error = 0; uint32_t seq; @@ -603,8 +624,11 @@ if (seq_start == 0) { error = mfi_get_log_state(sc, &log_state); - if (error) + if (error) { + if (log_state) + free(log_state, M_MFIBUF); return (error); + } /* * Don't run them yet since we can't parse them. * We can indirectly get the contents from @@ -612,16 +636,17 @@ * current. The firmware will iterate through them. */ #ifdef NOTYET - for (seq = log_state.shutdown_seq_num; - seq <= log_state.newest_seq_num; seq++) { + for (seq = log_state->shutdown_seq_num; + seq <= log_state->newest_seq_num; seq++) { mfi_get_entry(sc, seq); } #endif - seq = log_state.shutdown_seq_num + 1; + seq = log_state->shutdown_seq_num + 1; } else seq = seq_start; mfi_aen_register(sc, seq, class_locale.word); + free(log_state, M_MFIBUF); return 0; } @@ -653,6 +678,18 @@ return (0); } +static int +mfi_wait_command(struct mfi_softc *sc, struct mfi_command *cm) +{ + + mtx_assert(&sc->mfi_io_lock, MA_OWNED); + cm->cm_complete = NULL; + + mfi_enqueue_ready(cm); + mfi_startio(sc); + return (msleep(cm, &sc->mfi_io_lock, PRIBIO, "mfiwait", 0)); +} + void mfi_free(struct mfi_softc *sc) { @@ -721,7 +758,7 @@ config_intrhook_disestablish(&sc->mfi_ich); mfi_enable_intr(sc); - mfi_ldprobe_inq(sc); + mfi_ldprobe(sc); } static void @@ -771,25 +808,23 @@ struct mfi_command *cm; int error; - if ((cm = mfi_dequeue_free(sc)) == NULL) - return (EBUSY); + mtx_lock(&sc->mfi_io_lock); + error = mfi_dcmd_command(sc, &cm, MFI_DCMD_CTRL_SHUTDOWN, NULL, 0); + mtx_unlock(&sc->mfi_io_lock); + if (error) + return (error); if (sc->mfi_aen_cm != NULL) mfi_abort(sc, sc->mfi_aen_cm); dcmd = &cm->cm_frame->dcmd; - bzero(dcmd->mbox, MFI_MBOX_SIZE); - dcmd->header.cmd = MFI_CMD_DCMD; - dcmd->header.sg_count = 0; dcmd->header.flags = MFI_FRAME_DIR_NONE; - dcmd->header.timeout = 0; - dcmd->header.data_len = 0; - dcmd->opcode = MFI_DCMD_CTRL_SHUTDOWN; if ((error = mfi_polled_command(sc, cm)) != 0) { device_printf(sc->mfi_dev, "Failed to shutdown controller\n"); } + mfi_release_command(cm); return (error); } @@ -801,136 +836,41 @@ } static void -mfi_ldprobe_inq(struct mfi_softc *sc) -{ - struct mfi_command *cm; - struct mfi_pass_frame *pass; - char *inq; - int i; - - /* Probe all possible targets with a SCSI INQ command */ - mtx_lock(&sc->mfi_io_lock); - sc->mfi_probe_count = 0; - for (i = 0; i < MFI_MAX_CHANNEL_DEVS; i++) { - inq = malloc(MFI_INQ_LENGTH, M_MFIBUF, M_NOWAIT|M_ZERO); - if (inq == NULL) - break; - cm = mfi_dequeue_free(sc); - if (cm == NULL) { - free(inq, M_MFIBUF); - msleep(mfi_startup, &sc->mfi_io_lock, 0, "mfistart", - 5 * hz); - i--; - continue; - } - pass = &cm->cm_frame->pass; - pass->header.cmd = MFI_CMD_LD_SCSI_IO; - pass->header.target_id = i; - pass->header.lun_id = 0; - pass->header.cdb_len = 6; - pass->header.timeout = 0; - pass->header.data_len = MFI_INQ_LENGTH; - bzero(pass->cdb, 16); - pass->cdb[0] = INQUIRY; - pass->cdb[4] = MFI_INQ_LENGTH; - pass->header.sense_len = MFI_SENSE_LEN; - pass->sense_addr_lo = cm->cm_sense_busaddr; - pass->sense_addr_hi = 0; - cm->cm_complete = mfi_ldprobe_inq_complete; - cm->cm_private = inq; - cm->cm_sg = &pass->sgl; - cm->cm_total_frame_size = MFI_PASS_FRAME_SIZE; - cm->cm_flags |= MFI_CMD_DATAIN; - cm->cm_data = inq; - cm->cm_len = MFI_INQ_LENGTH; - sc->mfi_probe_count++; - mfi_enqueue_ready(cm); - mfi_startio(sc); - } - - /* Sleep while the arrays are attaching */ - msleep(mfi_startup, &sc->mfi_io_lock, 0, "mfistart", 60 * hz); - mtx_unlock(&sc->mfi_io_lock); - - return; -} - -static void -mfi_ldprobe_inq_complete(struct mfi_command *cm) +mfi_ldprobe(struct mfi_softc *sc) { struct mfi_frame_header *hdr; - struct mfi_softc *sc; - struct scsi_inquiry_data *inq; + struct mfi_command *cm = NULL; + struct mfi_ld_list *list = NULL; + int error, i; - sc = cm->cm_sc; - inq = cm->cm_private; - hdr = &cm->cm_frame->header; + mtx_lock(&sc->mfi_io_lock); + error = mfi_dcmd_command(sc, &cm, MFI_DCMD_LD_GET_LIST, + (void **)&list, sizeof(*list)); + if (error) + goto out; - if ((hdr->cmd_status != MFI_STAT_OK) || (hdr->scsi_status != 0x00) || - (SID_TYPE(inq) != T_DIRECT)) { - free(inq, M_MFIBUF); - mfi_release_command(cm); - if (--sc->mfi_probe_count <= 0) - wakeup(mfi_startup); - return; + cm->cm_flags = MFI_CMD_DATAIN; + if (mfi_wait_command(sc, cm) != 0) { + device_printf(sc->mfi_dev, "Failed to get device listing\n"); + goto out; } - free(inq, M_MFIBUF); - mfi_release_command(cm); - mfi_ldprobe_tur(sc, hdr->target_id); -} - -static int -mfi_ldprobe_tur(struct mfi_softc *sc, int id) -{ - struct mfi_command *cm; - struct mfi_pass_frame *pass; - - cm = mfi_dequeue_free(sc); - if (cm == NULL) - return (EBUSY); - pass = &cm->cm_frame->pass; - pass->header.cmd = MFI_CMD_LD_SCSI_IO; - pass->header.target_id = id; - pass->header.lun_id = 0; - pass->header.cdb_len = 6; - pass->header.timeout = 0; - pass->header.data_len = 0; - bzero(pass->cdb, 16); - pass->cdb[0] = TEST_UNIT_READY; - pass->header.sense_len = MFI_SENSE_LEN; - pass->sense_addr_lo = cm->cm_sense_busaddr; - pass->sense_addr_hi = 0; - cm->cm_complete = mfi_ldprobe_tur_complete; - cm->cm_total_frame_size = MFI_PASS_FRAME_SIZE; - cm->cm_flags = 0; - mfi_enqueue_ready(cm); - mfi_startio(sc); - - return (0); -} - -static void -mfi_ldprobe_tur_complete(struct mfi_command *cm) -{ - struct mfi_frame_header *hdr; - struct mfi_softc *sc; - - sc = cm->cm_sc; hdr = &cm->cm_frame->header; + if (hdr->cmd_status != MFI_STAT_OK) { + device_printf(sc->mfi_dev, "MFI_DCMD_LD_GET_LIST failed %x\n", + hdr->cmd_status); + goto out; + } - if ((hdr->cmd_status != MFI_STAT_OK) || (hdr->scsi_status != 0x00)) { - device_printf(sc->mfi_dev, "Logical disk %d is not ready, " - "cmd_status= %d scsi_status= %d\n", hdr->target_id, - hdr->cmd_status, hdr->scsi_status); - mfi_print_sense(sc, cm->cm_sense); + for (i = 0; i < list->ld_count; i++) + mfi_add_ld(sc, list->ld_list[i].ld.target_id); +out: + if (list) + free(list, M_MFIBUF); + if (cm) mfi_release_command(cm); - if (--sc->mfi_probe_count <= 0) - wakeup(mfi_startup); - return; - } - mfi_release_command(cm); - mfi_ldprobe_capacity(sc, hdr->target_id); + mtx_unlock(&sc->mfi_io_lock); + return; } #ifdef NOTYET @@ -1179,7 +1119,8 @@ struct mfi_command *cm; struct mfi_dcmd_frame *dcmd; union mfi_evt current_aen, prior_aen; - struct mfi_evt_detail *ed; + struct mfi_evt_detail *ed = NULL; + int error; current_aen.word = locale; if (sc->mfi_aen_cm != NULL) { @@ -1200,34 +1141,16 @@ } mtx_lock(&sc->mfi_io_lock); - if ((cm = mfi_dequeue_free(sc)) == NULL) { - mtx_unlock(&sc->mfi_io_lock); - return (EBUSY); - } + error = mfi_dcmd_command(sc, &cm, MFI_DCMD_CTRL_EVENT_WAIT, + (void **)&ed, sizeof(*ed)); mtx_unlock(&sc->mfi_io_lock); - - ed = malloc(sizeof(struct mfi_evt_detail), M_MFIBUF, - M_NOWAIT | M_ZERO); - if (ed == NULL) { - mtx_lock(&sc->mfi_io_lock); - mfi_release_command(cm); - mtx_unlock(&sc->mfi_io_lock); - return (ENOMEM); - } + if (error) + return (error); dcmd = &cm->cm_frame->dcmd; - bzero(dcmd->mbox, MFI_MBOX_SIZE); - dcmd->header.cmd = MFI_CMD_DCMD; - dcmd->header.timeout = 0; - dcmd->header.data_len = sizeof(struct mfi_evt_detail); - dcmd->opcode = MFI_DCMD_CTRL_EVENT_WAIT; ((uint32_t *)&dcmd->mbox)[0] = seq; ((uint32_t *)&dcmd->mbox)[1] = locale; - cm->cm_sg = &dcmd->sgl; - cm->cm_total_frame_size = MFI_DCMD_FRAME_SIZE; cm->cm_flags = MFI_CMD_DATAIN; - cm->cm_data = ed; - cm->cm_len = sizeof(struct mfi_evt_detail); cm->cm_complete = mfi_aen_complete; sc->mfi_aen_cm = cm; @@ -1355,111 +1278,75 @@ #endif static int -mfi_ldprobe_capacity(struct mfi_softc *sc, int id) +mfi_add_ld(struct mfi_softc *sc, int id) { struct mfi_command *cm; - struct mfi_pass_frame *pass; - struct scsi_read_capacity_data_long *cap; + struct mfi_dcmd_frame *dcmd = NULL; + struct mfi_ld_info *ld_info = NULL; + int error; - cap = malloc(sizeof(*cap), M_MFIBUF, M_NOWAIT|M_ZERO); - if (cap == NULL) - return (ENOMEM); - cm = mfi_dequeue_free(sc); - if (cm == NULL) { - free(cap, M_MFIBUF); - return (EBUSY); + mtx_assert(&sc->mfi_io_lock, MA_OWNED); + + error = mfi_dcmd_command(sc, &cm, MFI_DCMD_LD_GET_INFO, + (void **)&ld_info, sizeof(*ld_info)); + if (error) { + device_printf(sc->mfi_dev, + "Failed to allocate for MFI_DCMD_LD_GET_INFO %d\n", error); + if (ld_info) + free(ld_info, M_MFIBUF); + return (error); + } + cm->cm_flags = MFI_CMD_DATAIN; + dcmd = &cm->cm_frame->dcmd; + dcmd->mbox[0] = id; + if (mfi_wait_command(sc, cm) != 0) { + device_printf(sc->mfi_dev, + "Failed to get logical drive: %d\n", id); + free(ld_info, M_MFIBUF); + return (0); } - pass = &cm->cm_frame->pass; - pass->header.cmd = MFI_CMD_LD_SCSI_IO; - pass->header.target_id = id; - pass->header.lun_id = 0; - pass->header.cdb_len = 6; - pass->header.timeout = 0; - pass->header.data_len = sizeof(*cap); - bzero(pass->cdb, 16); - pass->cdb[0] = 0x9e; /* READ CAPACITY 16 */ - pass->cdb[13] = sizeof(*cap); - pass->header.sense_len = MFI_SENSE_LEN; - pass->sense_addr_lo = cm->cm_sense_busaddr; - pass->sense_addr_hi = 0; - cm->cm_complete = mfi_ldprobe_capacity_complete; - cm->cm_private = cap; - cm->cm_sg = &pass->sgl; - cm->cm_total_frame_size = MFI_PASS_FRAME_SIZE; - cm->cm_flags |= MFI_CMD_DATAIN; - cm->cm_data = cap; - cm->cm_len = sizeof(*cap); - mfi_enqueue_ready(cm); - mfi_startio(sc); + mfi_add_ld_complete(cm); return (0); } static void -mfi_ldprobe_capacity_complete(struct mfi_command *cm) +mfi_add_ld_complete(struct mfi_command *cm) { struct mfi_frame_header *hdr; + struct mfi_ld_info *ld_info; struct mfi_softc *sc; - struct scsi_read_capacity_data_long *cap; - uint64_t sectors; - uint32_t secsize; - int target; + struct mfi_ld *ld; + device_t child; sc = cm->cm_sc; - cap = cm->cm_private; hdr = &cm->cm_frame->header; + ld_info = cm->cm_private; - if ((hdr->cmd_status != MFI_STAT_OK) || (hdr->scsi_status != 0x00)) { - device_printf(sc->mfi_dev, "Failed to read capacity for " - "logical disk\n"); - device_printf(sc->mfi_dev, "cmd_status= %d scsi_status= %d\n", - hdr->cmd_status, hdr->scsi_status); - free(cap, M_MFIBUF); + if (hdr->cmd_status != MFI_STAT_OK) { + free(ld_info, M_MFIBUF); mfi_release_command(cm); - if (--sc->mfi_probe_count <= 0) - wakeup(mfi_startup); return; } - target = hdr->target_id; - sectors = scsi_8btou64(cap->addr); - secsize = scsi_4btoul(cap->length); - free(cap, M_MFIBUF); mfi_release_command(cm); - mfi_add_ld(sc, target, sectors, secsize); - if (--sc->mfi_probe_count <= 0) - wakeup(mfi_startup); - - return; -} - -static int -mfi_add_ld(struct mfi_softc *sc, int id, uint64_t sectors, uint32_t secsize) -{ - struct mfi_ld *ld; - device_t child; - - if ((secsize == 0) || (sectors == 0)) { - device_printf(sc->mfi_dev, "Invalid capacity parameters for " - "logical disk %d\n", id); - return (EINVAL); - } ld = malloc(sizeof(struct mfi_ld), M_MFIBUF, M_NOWAIT|M_ZERO); if (ld == NULL) { device_printf(sc->mfi_dev, "Cannot allocate ld\n"); - return (ENOMEM); + free(ld_info, M_MFIBUF); + return; } if ((child = device_add_child(sc->mfi_dev, "mfid", -1)) == NULL) { device_printf(sc->mfi_dev, "Failed to add logical disk\n"); free(ld, M_MFIBUF); - return (EINVAL); + free(ld_info, M_MFIBUF); + return; } - ld->ld_id = id; + ld->ld_id = ld_info->ld_config.properties.ld.target_id; ld->ld_disk = child; - ld->ld_secsize = secsize; - ld->ld_sectors = sectors; + ld->ld_info = ld_info; device_set_ivars(child, ld); device_set_desc(child, "MFI Logical Disk"); @@ -1468,8 +1355,6 @@ bus_generic_attach(sc->mfi_dev); mtx_unlock(&Giant); mtx_lock(&sc->mfi_io_lock); - - return (0); } static struct mfi_command * @@ -1699,6 +1584,8 @@ if (cm->cm_complete != NULL) cm->cm_complete(cm); + else + wakeup(cm); sc->mfi_flags &= ~MFI_FLAGS_QFRZN; mfi_startio(sc); @@ -1804,7 +1691,6 @@ if (mfi_aen_entry->p == curproc) { TAILQ_REMOVE(&sc->mfi_aen_pids, mfi_aen_entry, aen_link); -printf("REMOVED pid %d\n",mfi_aen_entry->p->p_pid); free(mfi_aen_entry, M_MFIBUF); } } @@ -2062,7 +1948,6 @@ sc = dev->si_drv1; - printf("MFI POLL\n"); if (poll_events & (POLLIN | POLLRDNORM)) { if (sc->mfi_aen_triggered != 0) revents |= poll_events & (POLLIN | POLLRDNORM); Index: mfi_disk.c =================================================================== RCS file: /usr/cvs/src/sys/dev/mfi/mfi_disk.c,v retrieving revision 1.2.2.2 diff -u -r1.2.2.2 mfi_disk.c --- mfi_disk.c 15 Jun 2006 16:07:56 -0000 1.2.2.2 +++ mfi_disk.c 17 Jul 2006 17:07:05 -0000 @@ -113,14 +113,8 @@ sc->ld_ld = device_get_ivars(dev); sc->ld_controller = device_get_softc(device_get_parent(dev)); - sectors = sc->ld_ld->ld_sectors; - secsize = sc->ld_ld->ld_secsize; - if (secsize != MFI_SECTOR_LEN) { - device_printf(sc->ld_dev, "Reported sector length %d is not " - "512, aborting\n", secsize); - free(sc->ld_ld, M_MFIBUF); - return (EINVAL); - } + sectors = ld->ld_info->size; + secsize = MFI_SECTOR_LEN; TAILQ_INSERT_TAIL(&sc->ld_controller->mfi_ld_tqh, ld, ld_link); device_printf(dev, "%juMB (%ju sectors) RAID\n", @@ -235,7 +229,7 @@ if (len > 0) { if ((error = mfi_dump_blocks(parent_sc, sc->ld_id, offset / - sc->ld_ld->ld_secsize, virt, len)) != 0) + MFI_SECTOR_LEN, virt, len)) != 0) return (error); } else { /* mfi_sync_cache(parent_sc, sc->ld_id); */ Index: mfi_pci.c =================================================================== RCS file: /usr/cvs/src/sys/dev/mfi/mfi_pci.c,v retrieving revision 1.1.2.2 diff -u -r1.1.2.2 mfi_pci.c --- mfi_pci.c 15 Jun 2006 16:07:56 -0000 1.1.2.2 +++ mfi_pci.c 17 Jul 2006 17:07:05 -0000 @@ -207,6 +207,7 @@ if (error) return (error); TAILQ_REMOVE(&sc->mfi_ld_tqh, ld, ld_link); + free(ld->ld_info, M_MFIBUF); free(ld, M_MFIBUF); } Index: mfireg.h =================================================================== RCS file: /usr/cvs/src/sys/dev/mfi/mfireg.h,v retrieving revision 1.1.2.2 diff -u -r1.1.2.2 mfireg.h --- mfireg.h 15 Jun 2006 16:07:57 -0000 1.1.2.2 +++ mfireg.h 17 Jul 2006 17:07:05 -0000 @@ -106,7 +106,10 @@ MFI_DCMD_CTRL_EVENT_GETINFO = 0x01040100, MFI_DCMD_CTRL_EVENT_GET = 0x01040300, MFI_DCMD_CTRL_EVENT_WAIT = 0x01040500, + MFI_DCMD_LD_GET_LIST = 0x03010000, + MFI_DCMD_LD_GET_INFO = 0x03020000, MFI_DCMD_LD_GET_PROP = 0x03030000, + MFI_DCMD_LD_SET_PROP = 0x03040000, MFI_DCMD_CLUSTER = 0x08000000, MFI_DCMD_CLUSTER_RESET_ALL = 0x08010100, MFI_DCMD_CLUSTER_RESET_LD = 0x08010200 @@ -727,4 +730,97 @@ char description[128]; } __packed; +struct mfi_ldref { + uint8_t target_id; + uint8_t reserved; + uint16_t seq; +} __packed; + +struct mfi_ld_list { + uint32_t ld_count; + uint32_t reserved1; + struct { + struct mfi_ldref ld; + uint8_t state; + uint8_t reserved2[3]; + uint64_t size; + } ld_list[MFI_MAX_LD]; +} __packed; + +enum mfi_ld_access { + MFI_LD_ACCESS_RW = 0, + MFI_LD_ACCSSS_RO = 2, + MFI_LD_ACCESS_BLOCKED = 3, +}; +#define MFI_LD_ACCESS_MASK 3 + +enum mfi_ld_state { + MFI_LD_STATE_OFFLINE = 0, + MFI_LD_STATE_PARTIALLY_DEGRADED = 1, + MFI_LD_STATE_DEGRADED = 2, + MFI_LD_STATE_OPTIMAL = 3 +}; + +struct mfi_ld_props { + struct mfi_ldref ld; + char name[16]; + uint8_t default_cache_policy; + uint8_t access_policy; + uint8_t disk_cache_policy; + uint8_t current_cache_policy; + uint8_t no_bgi; + uint8_t reserved[7]; +} __packed; + +struct mfi_ld_params { + uint8_t primary_raid_level; + uint8_t raid_level_qualifier; + uint8_t secondary_raid_level; + uint8_t stripe_size; + uint8_t num_drives; + uint8_t span_depth; + uint8_t state; + uint8_t init_state; + uint8_t is_consistent; + uint8_t reserved[23]; +} __packed; + +struct mfi_ld_progress { + uint32_t active; +#define MFI_LD_PROGRESS_CC (1<<0) +#define MFI_LD_PROGRESS_BGI (1<<1) +#define MFI_LD_PROGRESS_FGI (1<<2) +#define MFI_LD_PORGRESS_RECON (1<<3) + struct mfi_progress cc; + struct mfi_progress bgi; + struct mfi_progress fgi; + struct mfi_progress recon; + struct mfi_progress reserved[4]; +} __packed; + +struct mfi_span { + uint64_t start_block; + uint64_t num_blocks; + uint16_t array_ref; + uint8_t reserved[6]; +} __packed; + +#define MFI_MAX_SPAN_DEPTH 8 +struct mfi_ld_config { + struct mfi_ld_props properties; + struct mfi_ld_params params; + struct mfi_span span[MFI_MAX_SPAN_DEPTH]; +} __packed; + +struct mfi_ld_info { + struct mfi_ld_config ld_config; + uint64_t size; + struct mfi_ld_progress progress; + uint16_t cluster_owner; + uint8_t reconstruct_active; + uint8_t reserved1[1]; + uint8_t vpd_page83[64]; + uint8_t reserved2[16]; +} __packed; + #endif /* _MFIREG_H */ Index: mfivar.h =================================================================== RCS file: /usr/cvs/src/sys/dev/mfi/mfivar.h,v retrieving revision 1.1.2.2 diff -u -r1.1.2.2 mfivar.h --- mfivar.h 15 Jun 2006 16:07:57 -0000 1.1.2.2 +++ mfivar.h 17 Jul 2006 17:07:05 -0000 @@ -75,8 +75,7 @@ struct mfi_ld { TAILQ_ENTRY(mfi_ld) ld_link; device_t ld_disk; - uint64_t ld_sectors; - uint32_t ld_secsize; + struct mfi_ld_info *ld_info; int ld_id; }; @@ -133,7 +132,6 @@ struct intr_config_hook mfi_ich; eventhandler_tag eh; - int mfi_probe_count; /* * Allocation for the command array. Used as an indexable array to