Lines Matching +full:int +full:- +full:clock +full:- +full:stable +full:- +full:broken

1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
72 struct aac_mntinforesp *mir, int f);
78 static void aac_complete(void *context, int pending);
79 static int aac_bio_command(struct aac_softc *sc, struct aac_command **cmp);
81 static int aac_wait_command(struct aac_command *cm);
86 int nseg, int error);
88 int nseg, int error);
89 static int aac_alloc_commands(struct aac_softc *sc);
94 static int aac_alloc(struct aac_softc *sc);
95 static void aac_common_map(void *arg, bus_dma_segment_t *segs, int nseg,
96 int error);
97 static int aac_check_firmware(struct aac_softc *sc);
98 static int aac_init(struct aac_softc *sc);
99 static int aac_sync_command(struct aac_softc *sc, u_int32_t command,
102 static int aac_setup_intr(struct aac_softc *sc);
103 static int aac_enqueue_fib(struct aac_softc *sc, int queue,
105 static int aac_dequeue_fib(struct aac_softc *sc, int queue,
107 static int aac_enqueue_response(struct aac_softc *sc, int queue,
111 static int aac_sa_get_fwstatus(struct aac_softc *sc);
112 static void aac_sa_qnotify(struct aac_softc *sc, int qbit);
113 static int aac_sa_get_istatus(struct aac_softc *sc);
114 static void aac_sa_clear_istatus(struct aac_softc *sc, int mask);
118 static int aac_sa_get_mailbox(struct aac_softc *sc, int mb);
119 static void aac_sa_set_interrupts(struct aac_softc *sc, int enable);
133 static int aac_rx_get_fwstatus(struct aac_softc *sc);
134 static void aac_rx_qnotify(struct aac_softc *sc, int qbit);
135 static int aac_rx_get_istatus(struct aac_softc *sc);
136 static void aac_rx_clear_istatus(struct aac_softc *sc, int mask);
140 static int aac_rx_get_mailbox(struct aac_softc *sc, int mb);
141 static void aac_rx_set_interrupts(struct aac_softc *sc, int enable);
142 static int aac_rx_send_command(struct aac_softc *sc, struct aac_command *cm);
143 static int aac_rx_get_outb_queue(struct aac_softc *sc);
144 static void aac_rx_set_outb_queue(struct aac_softc *sc, int index);
160 static int aac_rkt_get_fwstatus(struct aac_softc *sc);
161 static void aac_rkt_qnotify(struct aac_softc *sc, int qbit);
162 static int aac_rkt_get_istatus(struct aac_softc *sc);
163 static void aac_rkt_clear_istatus(struct aac_softc *sc, int mask);
167 static int aac_rkt_get_mailbox(struct aac_softc *sc, int mb);
168 static void aac_rkt_set_interrupts(struct aac_softc *sc, int enable);
169 static int aac_rkt_send_command(struct aac_softc *sc, struct aac_command *cm);
170 static int aac_rkt_get_outb_queue(struct aac_softc *sc);
171 static void aac_rkt_set_outb_queue(struct aac_softc *sc, int index);
196 static int aac_ioctl_sendfib(struct aac_softc *sc, caddr_t ufib);
197 static int aac_ioctl_send_raw_srb(struct aac_softc *sc, caddr_t arg);
200 static int aac_rev_check(struct aac_softc *sc, caddr_t udata);
201 static int aac_open_aif(struct aac_softc *sc, caddr_t arg);
202 static int aac_close_aif(struct aac_softc *sc, caddr_t arg);
203 static int aac_getnext_aif(struct aac_softc *sc, caddr_t arg);
204 static int aac_return_aif(struct aac_softc *sc,
206 static int aac_query_disk(struct aac_softc *sc, caddr_t uptr);
207 static int aac_get_pci_info(struct aac_softc *sc, caddr_t uptr);
208 static int aac_supported_features(struct aac_softc *sc, caddr_t uptr);
212 aac_get_container_info(struct aac_softc *sc, struct aac_fib *fib, int cid);
236 int
239 int error, unit; in aac_attach()
244 * Initialize per-controller queues. in aac_attach()
252 * Initialize command-completion task. in aac_attach()
254 TASK_INIT(&sc->aac_task_complete, 0, aac_complete, sc); in aac_attach()
257 sc->aac_state |= AAC_STATE_SUSPEND; in aac_attach()
268 mtx_init(&sc->aac_aifq_lock, "AAC AIF lock", NULL, MTX_DEF); in aac_attach()
269 mtx_init(&sc->aac_io_lock, "AAC I/O lock", NULL, MTX_DEF); in aac_attach()
270 mtx_init(&sc->aac_container_lock, "AAC container lock", NULL, MTX_DEF); in aac_attach()
271 TAILQ_INIT(&sc->aac_container_tqh); in aac_attach()
272 TAILQ_INIT(&sc->aac_ev_cmfree); in aac_attach()
274 /* Initialize the clock daemon callout. */ in aac_attach()
275 callout_init_mtx(&sc->aac_daemontime, &sc->aac_io_lock, 0); in aac_attach()
299 SYSCTL_ADD_INT(device_get_sysctl_ctx(sc->aac_dev), in aac_attach()
300 SYSCTL_CHILDREN(device_get_sysctl_tree(sc->aac_dev)), in aac_attach()
302 &sc->aac_revision.buildNumber, 0, in aac_attach()
308 sc->aac_ich.ich_func = aac_startup; in aac_attach()
309 sc->aac_ich.ich_arg = sc; in aac_attach()
310 if (config_intrhook_establish(&sc->aac_ich) != 0) { in aac_attach()
311 device_printf(sc->aac_dev, in aac_attach()
319 unit = device_get_unit(sc->aac_dev); in aac_attach()
320 sc->aac_dev_t = make_dev(&aac_cdevsw, unit, UID_ROOT, GID_OPERATOR, in aac_attach()
322 (void)make_dev_alias(sc->aac_dev_t, "afa%d", unit); in aac_attach()
323 (void)make_dev_alias(sc->aac_dev_t, "hpn%d", unit); in aac_attach()
324 sc->aac_dev_t->si_drv1 = sc; in aac_attach()
328 &sc->aifthread, 0, 0, "aac%daif", unit)) in aac_attach()
331 /* Register the shutdown method to only be called post-dump */ in aac_attach()
332 if ((sc->eh = EVENTHANDLER_REGISTER(shutdown_final, aac_shutdown, in aac_attach()
333 sc->aac_dev, SHUTDOWN_PRI_DEFAULT)) == NULL) in aac_attach()
334 device_printf(sc->aac_dev, in aac_attach()
337 /* Register with CAM for the non-DASD devices */ in aac_attach()
338 if ((sc->flags & AAC_FLAGS_ENABLE_CAM) != 0) { in aac_attach()
339 TAILQ_INIT(&sc->aac_sim_tqh); in aac_attach()
343 mtx_lock(&sc->aac_io_lock); in aac_attach()
344 callout_reset(&sc->aac_daemontime, 60 * hz, aac_daemon, sc); in aac_attach()
345 mtx_unlock(&sc->aac_io_lock); in aac_attach()
358 mtx_assert(&sc->aac_io_lock, MA_OWNED); in aac_daemon()
360 if (callout_pending(&sc->aac_daemontime) || in aac_daemon()
361 callout_active(&sc->aac_daemontime) == 0) in aac_daemon()
365 *(uint32_t *)fib->data = tv.tv_sec; in aac_daemon()
368 callout_schedule(&sc->aac_daemontime, 30 * 60 * hz); in aac_daemon()
375 switch (event->ev_type & AAC_EVENT_MASK) { in aac_add_event()
377 TAILQ_INSERT_TAIL(&sc->aac_ev_cmfree, event, ev_links); in aac_add_event()
380 device_printf(sc->aac_dev, "aac_add event: unknown event %d\n", in aac_add_event()
381 event->ev_type); in aac_add_event()
390 aac_get_container_info(struct aac_softc *sc, struct aac_fib *fib, int cid) in aac_get_container_info()
394 mi = (struct aac_mntinfo *)&fib->data[0]; in aac_get_container_info()
395 /* use 64-bit LBA if enabled */ in aac_get_container_info()
396 mi->Command = (sc->flags & AAC_FLAGS_LBA_64BIT) ? in aac_get_container_info()
398 mi->MntType = FT_FILESYS; in aac_get_container_info()
399 mi->MntCount = cid; in aac_get_container_info()
403 device_printf(sc->aac_dev, "Error probing container %d\n", cid); in aac_get_container_info()
407 return ((struct aac_mntinforesp *)&fib->data[0]); in aac_get_container_info()
419 int count = 0, i = 0; in aac_startup()
424 mtx_lock(&sc->aac_io_lock); in aac_startup()
432 count = mir->MntRespCount; in aac_startup()
438 mtx_unlock(&sc->aac_io_lock); in aac_startup()
441 sc->aac_state &= ~AAC_STATE_SUSPEND; in aac_startup()
444 bus_attach_children(sc->aac_dev); in aac_startup()
447 config_intrhook_disestablish(&sc->aac_ich); in aac_startup()
457 aac_add_container(struct aac_softc *sc, struct aac_mntinforesp *mir, int f) in aac_add_container()
466 if ((mir->Status == ST_OK) && (mir->MntTable[0].VolType != CT_NONE)) { in aac_add_container()
472 mir->MntTable[0].ObjectId, in aac_add_container()
473 mir->MntTable[0].FileSystemName, in aac_add_container()
474 mir->MntTable[0].Capacity, mir->MntTable[0].VolType); in aac_add_container()
476 if ((child = device_add_child(sc->aac_dev, "aacd", -1)) == NULL) in aac_add_container()
477 device_printf(sc->aac_dev, "device_add_child failed\n"); in aac_add_container()
481 mir->MntTable[0].VolType)); in aac_add_container()
482 co->co_disk = child; in aac_add_container()
483 co->co_found = f; in aac_add_container()
484 bcopy(&mir->MntTable[0], &co->co_mntobj, in aac_add_container()
486 mtx_lock(&sc->aac_container_lock); in aac_add_container()
487 TAILQ_INSERT_TAIL(&sc->aac_container_tqh, co, co_link); in aac_add_container()
488 mtx_unlock(&sc->aac_container_lock); in aac_add_container()
495 static int
502 * Create DMA tag for mapping buffers into controller-addressable space. in aac_alloc()
504 if (bus_dma_tag_create(sc->aac_parent_dmat, /* parent */ in aac_alloc()
506 (sc->flags & AAC_FLAGS_SG_64BIT) ? in aac_alloc()
511 sc->aac_max_sectors << 9, /* maxsize */ in aac_alloc()
512 sc->aac_sg_tablesize, /* nsegments */ in aac_alloc()
516 &sc->aac_io_lock, /* lockfuncarg */ in aac_alloc()
517 &sc->aac_buffer_dmat)) { in aac_alloc()
518 device_printf(sc->aac_dev, "can't allocate buffer DMA tag\n"); in aac_alloc()
523 * Create DMA tag for mapping FIBs into controller-addressable space.. in aac_alloc()
525 if (bus_dma_tag_create(sc->aac_parent_dmat, /* parent */ in aac_alloc()
527 (sc->flags & AAC_FLAGS_4GB_WINDOW) ? in aac_alloc()
532 sc->aac_max_fibs_alloc * in aac_alloc()
533 sc->aac_max_fib_size, /* maxsize */ in aac_alloc()
535 sc->aac_max_fibs_alloc * in aac_alloc()
536 sc->aac_max_fib_size, /* maxsize */ in aac_alloc()
539 &sc->aac_fib_dmat)) { in aac_alloc()
540 device_printf(sc->aac_dev, "can't allocate FIB DMA tag\n"); in aac_alloc()
547 if (bus_dma_tag_create(sc->aac_parent_dmat, /* parent */ in aac_alloc()
549 (sc->flags & AAC_FLAGS_4GB_WINDOW) ? in aac_alloc()
559 &sc->aac_common_dmat)) { in aac_alloc()
560 device_printf(sc->aac_dev, in aac_alloc()
564 if (bus_dmamem_alloc(sc->aac_common_dmat, (void **)&sc->aac_common, in aac_alloc()
565 BUS_DMA_NOWAIT, &sc->aac_common_dmamap)) { in aac_alloc()
566 device_printf(sc->aac_dev, "can't allocate common structure\n"); in aac_alloc()
576 (void)bus_dmamap_load(sc->aac_common_dmat, sc->aac_common_dmamap, in aac_alloc()
577 sc->aac_common, 8192 + sizeof(*sc->aac_common), in aac_alloc()
580 if (sc->aac_common_busaddr < 8192) { in aac_alloc()
581 sc->aac_common = (struct aac_common *) in aac_alloc()
582 ((uint8_t *)sc->aac_common + 8192); in aac_alloc()
583 sc->aac_common_busaddr += 8192; in aac_alloc()
585 bzero(sc->aac_common, sizeof(*sc->aac_common)); in aac_alloc()
588 TAILQ_INIT(&sc->aac_fibmap_tqh); in aac_alloc()
589 sc->aac_commands = malloc(sc->aac_max_fibs * sizeof(struct aac_command), in aac_alloc()
591 while (sc->total_fibs < sc->aac_max_fibs) { in aac_alloc()
595 if (sc->total_fibs == 0) in aac_alloc()
613 if (sc->aac_dev_t != NULL) in aac_free()
614 destroy_dev(sc->aac_dev_t); in aac_free()
618 if (sc->aac_fib_dmat) in aac_free()
619 bus_dma_tag_destroy(sc->aac_fib_dmat); in aac_free()
621 free(sc->aac_commands, M_AACBUF); in aac_free()
624 if (sc->aac_common) { in aac_free()
625 bus_dmamap_unload(sc->aac_common_dmat, sc->aac_common_dmamap); in aac_free()
626 bus_dmamem_free(sc->aac_common_dmat, sc->aac_common, in aac_free()
627 sc->aac_common_dmamap); in aac_free()
629 if (sc->aac_common_dmat) in aac_free()
630 bus_dma_tag_destroy(sc->aac_common_dmat); in aac_free()
633 if (sc->aac_intr) in aac_free()
634 bus_teardown_intr(sc->aac_dev, sc->aac_irq, sc->aac_intr); in aac_free()
635 if (sc->aac_irq != NULL) { in aac_free()
636 bus_release_resource(sc->aac_dev, SYS_RES_IRQ, in aac_free()
637 rman_get_rid(sc->aac_irq), sc->aac_irq); in aac_free()
638 pci_release_msi(sc->aac_dev); in aac_free()
641 /* destroy data-transfer DMA tag */ in aac_free()
642 if (sc->aac_buffer_dmat) in aac_free()
643 bus_dma_tag_destroy(sc->aac_buffer_dmat); in aac_free()
646 if (sc->aac_parent_dmat) in aac_free()
647 bus_dma_tag_destroy(sc->aac_parent_dmat); in aac_free()
650 if (sc->aac_regs_res0 != NULL) in aac_free()
651 bus_release_resource(sc->aac_dev, SYS_RES_MEMORY, in aac_free()
652 rman_get_rid(sc->aac_regs_res0), sc->aac_regs_res0); in aac_free()
653 if (sc->aac_hwif == AAC_HWIF_NARK && sc->aac_regs_res1 != NULL) in aac_free()
654 bus_release_resource(sc->aac_dev, SYS_RES_MEMORY, in aac_free()
655 rman_get_rid(sc->aac_regs_res1), sc->aac_regs_res1); in aac_free()
661 int
667 int error; in aac_detach()
676 callout_drain(&sc->aac_daemontime); in aac_detach()
678 mtx_lock(&sc->aac_io_lock); in aac_detach()
679 while (sc->aifflags & AAC_AIFFLAGS_RUNNING) { in aac_detach()
680 sc->aifflags |= AAC_AIFFLAGS_EXIT; in aac_detach()
681 wakeup(sc->aifthread); in aac_detach()
682 msleep(sc->aac_dev, &sc->aac_io_lock, PUSER, "aacdch", 0); in aac_detach()
684 mtx_unlock(&sc->aac_io_lock); in aac_detach()
685 KASSERT((sc->aifflags & AAC_AIFFLAGS_RUNNING) == 0, in aac_detach()
689 while ((co = TAILQ_FIRST(&sc->aac_container_tqh)) != NULL) { in aac_detach()
690 TAILQ_REMOVE(&sc->aac_container_tqh, co, co_link); in aac_detach()
695 while ((sim = TAILQ_FIRST(&sc->aac_sim_tqh)) != NULL) { in aac_detach()
696 TAILQ_REMOVE(&sc->aac_sim_tqh, sim, sim_link); in aac_detach()
703 EVENTHANDLER_DEREGISTER(shutdown_final, sc->eh); in aac_detach()
707 mtx_destroy(&sc->aac_aifq_lock); in aac_detach()
708 mtx_destroy(&sc->aac_io_lock); in aac_detach()
709 mtx_destroy(&sc->aac_container_lock); in aac_detach()
722 int
732 sc->aac_state |= AAC_STATE_SUSPEND; in aac_shutdown()
739 device_printf(sc->aac_dev, "shutting down controller..."); in aac_shutdown()
741 mtx_lock(&sc->aac_io_lock); in aac_shutdown()
743 cc = (struct aac_close_command *)&fib->data[0]; in aac_shutdown()
746 cc->Command = VM_CloseAll; in aac_shutdown()
747 cc->ContainerId = 0xffffffff; in aac_shutdown()
755 fib->data[0] = 0; in aac_shutdown()
773 mtx_unlock(&sc->aac_io_lock); in aac_shutdown()
781 int
789 sc->aac_state |= AAC_STATE_SUSPEND; in aac_suspend()
798 int
806 sc->aac_state &= ~AAC_STATE_SUSPEND; in aac_resume()
821 int i; in aac_new_intr()
826 mtx_lock(&sc->aac_io_lock); in aac_new_intr()
865 cm = sc->aac_commands + (index >> 2); in aac_new_intr()
866 fib = cm->cm_fib; in aac_new_intr()
868 fib->Header.XferState |= AAC_FIBSTATE_DONEADAP; in aac_new_intr()
869 *((u_int32_t *)(fib->data)) = AAC_ERROR_NORMAL; in aac_new_intr()
873 cm->cm_flags |= AAC_CMD_COMPLETED; in aac_new_intr()
876 if (cm->cm_complete != NULL) { in aac_new_intr()
877 cm->cm_complete(cm); in aac_new_intr()
884 sc->flags &= ~AAC_QUEUE_FRZN; in aac_new_intr()
888 if ((sc->flags & AAC_QUEUE_FRZN) == 0) in aac_new_intr()
891 mtx_unlock(&sc->aac_io_lock); in aac_new_intr()
897 int
917 taskqueue_enqueue(taskqueue_fast, &sc->aac_task_complete); in aac_filter()
926 (sc->aac_common->ac_printf[0] == 0)) in aac_filter()
927 sc->aac_common->ac_printf[0] = 32; in aac_filter()
936 wakeup(sc->aifthread); in aac_filter()
952 int error; in aac_startio()
961 if (sc->flags & AAC_QUEUE_FRZN) in aac_startio()
982 if (cm->cm_flags & AAC_CMD_MAPPED) in aac_startio()
990 if (cm->cm_datalen != 0) { in aac_startio()
991 if (cm->cm_flags & AAC_REQ_BIO) in aac_startio()
993 sc->aac_buffer_dmat, cm->cm_datamap, in aac_startio()
994 (struct bio *)cm->cm_private, in aac_startio()
997 error = bus_dmamap_load(sc->aac_buffer_dmat, in aac_startio()
998 cm->cm_datamap, cm->cm_data, in aac_startio()
999 cm->cm_datalen, aac_map_command_sg, cm, 0); in aac_startio()
1002 sc->flags |= AAC_QUEUE_FRZN; in aac_startio()
1019 int size, retval; in aac_command_thread()
1023 mtx_lock(&sc->aac_io_lock); in aac_command_thread()
1024 sc->aifflags = AAC_AIFFLAGS_RUNNING; in aac_command_thread()
1026 while ((sc->aifflags & AAC_AIFFLAGS_EXIT) == 0) { in aac_command_thread()
1028 if ((sc->aifflags & AAC_AIFFLAGS_PENDING) == 0) in aac_command_thread()
1029 retval = msleep(sc->aifthread, &sc->aac_io_lock, PRIBIO, in aac_command_thread()
1037 if ((sc->aifflags & AAC_AIFFLAGS_ALLOCFIBS) != 0) { in aac_command_thread()
1038 mtx_unlock(&sc->aac_io_lock); in aac_command_thread()
1040 mtx_lock(&sc->aac_io_lock); in aac_command_thread()
1041 sc->aifflags &= ~AAC_AIFFLAGS_ALLOCFIBS; in aac_command_thread()
1047 * This is pretty low-priority, so it's ok if it doesn't in aac_command_thread()
1054 if (sc->aac_common->ac_printf[0] != 0) in aac_command_thread()
1058 if (sc->flags & AAC_FLAGS_NEW_COMM) in aac_command_thread()
1067 switch (fib->Header.Command) { in aac_command_thread()
1072 device_printf(sc->aac_dev, "unknown command " in aac_command_thread()
1077 if ((fib->Header.XferState == 0) || in aac_command_thread()
1078 (fib->Header.StructType != AAC_FIBTYPE_TFIB)) { in aac_command_thread()
1083 if (fib->Header.XferState & AAC_FIBSTATE_FROMADAP) { in aac_command_thread()
1084 fib->Header.XferState |= AAC_FIBSTATE_DONEHOST; in aac_command_thread()
1085 *(AAC_FSAStatus*)fib->data = ST_OK; in aac_command_thread()
1088 size = fib->Header.Size; in aac_command_thread()
1091 fib->Header.Size = size; in aac_command_thread()
1096 * enqueue->startio chain. in aac_command_thread()
1104 sc->aifflags &= ~AAC_AIFFLAGS_RUNNING; in aac_command_thread()
1105 mtx_unlock(&sc->aac_io_lock); in aac_command_thread()
1106 wakeup(sc->aac_dev); in aac_command_thread()
1115 aac_complete(void *context, int pending) in aac_complete()
1125 mtx_lock(&sc->aac_io_lock); in aac_complete()
1135 cm = sc->aac_commands + fib->Header.SenderData; in aac_complete()
1140 if ((cm->cm_flags & AAC_CMD_TIMEDOUT) != 0) in aac_complete()
1141 device_printf(sc->aac_dev, in aac_complete()
1143 cm, (int)(time_uptime-cm->cm_timestamp)); in aac_complete()
1148 cm->cm_flags |= AAC_CMD_COMPLETED; in aac_complete()
1151 if (cm->cm_complete != NULL) { in aac_complete()
1152 cm->cm_complete(cm); in aac_complete()
1160 sc->flags &= ~AAC_QUEUE_FRZN; in aac_complete()
1163 mtx_unlock(&sc->aac_io_lock); in aac_complete()
1175 ad = (struct aac_disk *)bp->bio_disk->d_drv1; in aac_submit_bio()
1176 sc = ad->ad_controller; in aac_submit_bio()
1187 static int
1206 cm->cm_datalen = bp->bio_bcount; in aac_bio_command()
1207 cm->cm_complete = aac_bio_complete; in aac_bio_command()
1208 cm->cm_flags = AAC_REQ_BIO; in aac_bio_command()
1209 cm->cm_private = bp; in aac_bio_command()
1210 cm->cm_timestamp = time_uptime; in aac_bio_command()
1213 fib = cm->cm_fib; in aac_bio_command()
1214 fib->Header.Size = sizeof(struct aac_fib_header); in aac_bio_command()
1215 fib->Header.XferState = in aac_bio_command()
1226 ad = (struct aac_disk *)bp->bio_disk->d_drv1; in aac_bio_command()
1228 if (sc->flags & AAC_FLAGS_RAW_IO) { in aac_bio_command()
1230 raw = (struct aac_raw_io *)&fib->data[0]; in aac_bio_command()
1231 fib->Header.Command = RawIo; in aac_bio_command()
1232 raw->BlockNumber = (u_int64_t)bp->bio_pblkno; in aac_bio_command()
1233 raw->ByteCount = bp->bio_bcount; in aac_bio_command()
1234 raw->ContainerId = ad->ad_container->co_mntobj.ObjectId; in aac_bio_command()
1235 raw->BpTotal = 0; in aac_bio_command()
1236 raw->BpComplete = 0; in aac_bio_command()
1237 fib->Header.Size += sizeof(struct aac_raw_io); in aac_bio_command()
1238 cm->cm_sgtable = (struct aac_sg_table *)&raw->SgMapRaw; in aac_bio_command()
1239 if (bp->bio_cmd == BIO_READ) { in aac_bio_command()
1240 raw->Flags = 1; in aac_bio_command()
1241 cm->cm_flags |= AAC_CMD_DATAIN; in aac_bio_command()
1243 raw->Flags = 0; in aac_bio_command()
1244 cm->cm_flags |= AAC_CMD_DATAOUT; in aac_bio_command()
1246 } else if ((sc->flags & AAC_FLAGS_SG_64BIT) == 0) { in aac_bio_command()
1247 fib->Header.Command = ContainerCommand; in aac_bio_command()
1248 if (bp->bio_cmd == BIO_READ) { in aac_bio_command()
1250 br = (struct aac_blockread *)&fib->data[0]; in aac_bio_command()
1251 br->Command = VM_CtBlockRead; in aac_bio_command()
1252 br->ContainerId = ad->ad_container->co_mntobj.ObjectId; in aac_bio_command()
1253 br->BlockNumber = bp->bio_pblkno; in aac_bio_command()
1254 br->ByteCount = bp->bio_bcount; in aac_bio_command()
1255 fib->Header.Size += sizeof(struct aac_blockread); in aac_bio_command()
1256 cm->cm_sgtable = &br->SgMap; in aac_bio_command()
1257 cm->cm_flags |= AAC_CMD_DATAIN; in aac_bio_command()
1260 bw = (struct aac_blockwrite *)&fib->data[0]; in aac_bio_command()
1261 bw->Command = VM_CtBlockWrite; in aac_bio_command()
1262 bw->ContainerId = ad->ad_container->co_mntobj.ObjectId; in aac_bio_command()
1263 bw->BlockNumber = bp->bio_pblkno; in aac_bio_command()
1264 bw->ByteCount = bp->bio_bcount; in aac_bio_command()
1265 bw->Stable = CUNSTABLE; in aac_bio_command()
1266 fib->Header.Size += sizeof(struct aac_blockwrite); in aac_bio_command()
1267 cm->cm_flags |= AAC_CMD_DATAOUT; in aac_bio_command()
1268 cm->cm_sgtable = &bw->SgMap; in aac_bio_command()
1271 fib->Header.Command = ContainerCommand64; in aac_bio_command()
1272 if (bp->bio_cmd == BIO_READ) { in aac_bio_command()
1274 br = (struct aac_blockread64 *)&fib->data[0]; in aac_bio_command()
1275 br->Command = VM_CtHostRead64; in aac_bio_command()
1276 br->ContainerId = ad->ad_container->co_mntobj.ObjectId; in aac_bio_command()
1277 br->SectorCount = bp->bio_bcount / AAC_BLOCK_SIZE; in aac_bio_command()
1278 br->BlockNumber = bp->bio_pblkno; in aac_bio_command()
1279 br->Pad = 0; in aac_bio_command()
1280 br->Flags = 0; in aac_bio_command()
1281 fib->Header.Size += sizeof(struct aac_blockread64); in aac_bio_command()
1282 cm->cm_flags |= AAC_CMD_DATAIN; in aac_bio_command()
1283 cm->cm_sgtable = (struct aac_sg_table *)&br->SgMap64; in aac_bio_command()
1286 bw = (struct aac_blockwrite64 *)&fib->data[0]; in aac_bio_command()
1287 bw->Command = VM_CtHostWrite64; in aac_bio_command()
1288 bw->ContainerId = ad->ad_container->co_mntobj.ObjectId; in aac_bio_command()
1289 bw->SectorCount = bp->bio_bcount / AAC_BLOCK_SIZE; in aac_bio_command()
1290 bw->BlockNumber = bp->bio_pblkno; in aac_bio_command()
1291 bw->Pad = 0; in aac_bio_command()
1292 bw->Flags = 0; in aac_bio_command()
1293 fib->Header.Size += sizeof(struct aac_blockwrite64); in aac_bio_command()
1294 cm->cm_flags |= AAC_CMD_DATAOUT; in aac_bio_command()
1295 cm->cm_sgtable = (struct aac_sg_table *)&bw->SgMap64; in aac_bio_command()
1311 * Handle a bio-instigated command that has been completed.
1322 bp = (struct bio *)cm->cm_private; in aac_bio_complete()
1323 if (bp->bio_cmd == BIO_READ) { in aac_bio_complete()
1324 brr = (struct aac_blockread_response *)&cm->cm_fib->data[0]; in aac_bio_complete()
1325 status = brr->Status; in aac_bio_complete()
1327 bwr = (struct aac_blockwrite_response *)&cm->cm_fib->data[0]; in aac_bio_complete()
1328 status = bwr->Status; in aac_bio_complete()
1334 bp->bio_resid = 0; in aac_bio_complete()
1336 bp->bio_error = EIO; in aac_bio_complete()
1337 bp->bio_flags |= BIO_ERROR; in aac_bio_complete()
1352 static int
1356 int error; in aac_wait_command()
1358 sc = cm->cm_sc; in aac_wait_command()
1364 error = msleep(cm, &sc->aac_io_lock, PRIBIO, "aacwait", 0); in aac_wait_command()
1375 int
1383 if (sc->total_fibs < sc->aac_max_fibs) { in aac_alloc_command()
1384 mtx_lock(&sc->aac_io_lock); in aac_alloc_command()
1385 sc->aifflags |= AAC_AIFFLAGS_ALLOCFIBS; in aac_alloc_command()
1386 mtx_unlock(&sc->aac_io_lock); in aac_alloc_command()
1387 wakeup(sc->aifthread); in aac_alloc_command()
1405 sc = cm->cm_sc; in aac_release_command()
1409 cm->cm_datalen = 0; in aac_release_command()
1410 cm->cm_sgtable = NULL; in aac_release_command()
1411 cm->cm_flags = 0; in aac_release_command()
1412 cm->cm_complete = NULL; in aac_release_command()
1413 cm->cm_private = NULL; in aac_release_command()
1414 cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE; in aac_release_command()
1415 cm->cm_fib->Header.XferState = AAC_FIBSTATE_EMPTY; in aac_release_command()
1416 cm->cm_fib->Header.StructType = AAC_FIBTYPE_TFIB; in aac_release_command()
1417 cm->cm_fib->Header.Flags = 0; in aac_release_command()
1418 cm->cm_fib->Header.SenderSize = cm->cm_sc->aac_max_fib_size; in aac_release_command()
1425 cm->cm_fib->Header.ReceiverFibAddress = (u_int32_t)cm->cm_fibphys; in aac_release_command()
1426 cm->cm_fib->Header.SenderData = 0; in aac_release_command()
1430 if ((event = TAILQ_FIRST(&sc->aac_ev_cmfree)) != NULL) { in aac_release_command()
1431 TAILQ_REMOVE(&sc->aac_ev_cmfree, event, ev_links); in aac_release_command()
1432 event->ev_callback(sc, event, event->ev_arg); in aac_release_command()
1440 aac_map_command_helper(void *arg, bus_dma_segment_t *segs, int nseg, int error) in aac_map_command_helper()
1452 static int
1458 int i, error; in aac_alloc_commands()
1462 if (sc->total_fibs + sc->aac_max_fibs_alloc > sc->aac_max_fibs) in aac_alloc_commands()
1470 if (bus_dmamem_alloc(sc->aac_fib_dmat, (void **)&fm->aac_fibs, in aac_alloc_commands()
1471 BUS_DMA_NOWAIT, &fm->aac_fibmap)) { in aac_alloc_commands()
1472 device_printf(sc->aac_dev, in aac_alloc_commands()
1479 (void)bus_dmamap_load(sc->aac_fib_dmat, fm->aac_fibmap, fm->aac_fibs, in aac_alloc_commands()
1480 sc->aac_max_fibs_alloc * sc->aac_max_fib_size, in aac_alloc_commands()
1484 bzero(fm->aac_fibs, sc->aac_max_fibs_alloc * sc->aac_max_fib_size); in aac_alloc_commands()
1485 for (i = 0; i < sc->aac_max_fibs_alloc; i++) { in aac_alloc_commands()
1486 cm = sc->aac_commands + sc->total_fibs; in aac_alloc_commands()
1487 fm->aac_commands = cm; in aac_alloc_commands()
1488 cm->cm_sc = sc; in aac_alloc_commands()
1489 cm->cm_fib = (struct aac_fib *) in aac_alloc_commands()
1490 ((u_int8_t *)fm->aac_fibs + i*sc->aac_max_fib_size); in aac_alloc_commands()
1491 cm->cm_fibphys = fibphys + i*sc->aac_max_fib_size; in aac_alloc_commands()
1492 cm->cm_index = sc->total_fibs; in aac_alloc_commands()
1494 if ((error = bus_dmamap_create(sc->aac_buffer_dmat, 0, in aac_alloc_commands()
1495 &cm->cm_datamap)) != 0) in aac_alloc_commands()
1497 mtx_lock(&sc->aac_io_lock); in aac_alloc_commands()
1499 sc->total_fibs++; in aac_alloc_commands()
1500 mtx_unlock(&sc->aac_io_lock); in aac_alloc_commands()
1504 mtx_lock(&sc->aac_io_lock); in aac_alloc_commands()
1505 TAILQ_INSERT_TAIL(&sc->aac_fibmap_tqh, fm, fm_link); in aac_alloc_commands()
1506 fwprintf(sc, HBA_FLAGS_DBG_COMM_B, "total_fibs= %d\n", sc->total_fibs); in aac_alloc_commands()
1507 mtx_unlock(&sc->aac_io_lock); in aac_alloc_commands()
1511 bus_dmamap_unload(sc->aac_fib_dmat, fm->aac_fibmap); in aac_alloc_commands()
1512 bus_dmamem_free(sc->aac_fib_dmat, fm->aac_fibs, fm->aac_fibmap); in aac_alloc_commands()
1525 int i; in aac_free_commands()
1529 while ((fm = TAILQ_FIRST(&sc->aac_fibmap_tqh)) != NULL) { in aac_free_commands()
1530 TAILQ_REMOVE(&sc->aac_fibmap_tqh, fm, fm_link); in aac_free_commands()
1535 for (i = 0; i < sc->aac_max_fibs_alloc && sc->total_fibs--; i++) { in aac_free_commands()
1536 cm = fm->aac_commands + i; in aac_free_commands()
1537 bus_dmamap_destroy(sc->aac_buffer_dmat, cm->cm_datamap); in aac_free_commands()
1539 bus_dmamap_unload(sc->aac_fib_dmat, fm->aac_fibmap); in aac_free_commands()
1540 bus_dmamem_free(sc->aac_fib_dmat, fm->aac_fibs, fm->aac_fibmap); in aac_free_commands()
1546 * Command-mapping helper function - populate this command's s/g table.
1549 aac_map_command_sg(void *arg, bus_dma_segment_t *segs, int nseg, int error) in aac_map_command_sg()
1554 int i; in aac_map_command_sg()
1557 sc = cm->cm_sc; in aac_map_command_sg()
1558 fib = cm->cm_fib; in aac_map_command_sg()
1562 if (cm->cm_sgtable != NULL) { in aac_map_command_sg()
1563 if (fib->Header.Command == RawIo) { in aac_map_command_sg()
1565 sg = (struct aac_sg_tableraw *)cm->cm_sgtable; in aac_map_command_sg()
1566 sg->SgCount = nseg; in aac_map_command_sg()
1568 sg->SgEntryRaw[i].SgAddress = segs[i].ds_addr; in aac_map_command_sg()
1569 sg->SgEntryRaw[i].SgByteCount = segs[i].ds_len; in aac_map_command_sg()
1570 sg->SgEntryRaw[i].Next = 0; in aac_map_command_sg()
1571 sg->SgEntryRaw[i].Prev = 0; in aac_map_command_sg()
1572 sg->SgEntryRaw[i].Flags = 0; in aac_map_command_sg()
1575 fib->Header.Size += nseg*sizeof(struct aac_sg_entryraw); in aac_map_command_sg()
1576 } else if ((cm->cm_sc->flags & AAC_FLAGS_SG_64BIT) == 0) { in aac_map_command_sg()
1578 sg = cm->cm_sgtable; in aac_map_command_sg()
1579 sg->SgCount = nseg; in aac_map_command_sg()
1581 sg->SgEntry[i].SgAddress = segs[i].ds_addr; in aac_map_command_sg()
1582 sg->SgEntry[i].SgByteCount = segs[i].ds_len; in aac_map_command_sg()
1585 fib->Header.Size += nseg*sizeof(struct aac_sg_entry); in aac_map_command_sg()
1588 sg = (struct aac_sg_table64 *)cm->cm_sgtable; in aac_map_command_sg()
1589 sg->SgCount = nseg; in aac_map_command_sg()
1591 sg->SgEntry64[i].SgAddress = segs[i].ds_addr; in aac_map_command_sg()
1592 sg->SgEntry64[i].SgByteCount = segs[i].ds_len; in aac_map_command_sg()
1595 fib->Header.Size += nseg*sizeof(struct aac_sg_entry64); in aac_map_command_sg()
1604 cm->cm_fib->Header.SenderFibAddress = (cm->cm_index << 2); in aac_map_command_sg()
1605 cm->cm_fib->Header.ReceiverFibAddress = (u_int32_t)cm->cm_fibphys; in aac_map_command_sg()
1607 /* save a pointer to the command for speedy reverse-lookup */ in aac_map_command_sg()
1608 cm->cm_fib->Header.SenderData = cm->cm_index; in aac_map_command_sg()
1610 if (cm->cm_flags & AAC_CMD_DATAIN) in aac_map_command_sg()
1611 bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap, in aac_map_command_sg()
1613 if (cm->cm_flags & AAC_CMD_DATAOUT) in aac_map_command_sg()
1614 bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap, in aac_map_command_sg()
1616 cm->cm_flags |= AAC_CMD_MAPPED; in aac_map_command_sg()
1618 if (sc->flags & AAC_FLAGS_NEW_COMM) { in aac_map_command_sg()
1619 int count = 10000000L; in aac_map_command_sg()
1621 if (--count == 0) { in aac_map_command_sg()
1623 sc->flags |= AAC_QUEUE_FRZN; in aac_map_command_sg()
1630 if (aac_enqueue_fib(sc, cm->cm_queue, cm) == EBUSY) { in aac_map_command_sg()
1632 sc->flags |= AAC_QUEUE_FRZN; in aac_map_command_sg()
1639 * Unmap a command from controller-visible space.
1646 sc = cm->cm_sc; in aac_unmap_command()
1649 if (!(cm->cm_flags & AAC_CMD_MAPPED)) in aac_unmap_command()
1652 if (cm->cm_datalen != 0) { in aac_unmap_command()
1653 if (cm->cm_flags & AAC_CMD_DATAIN) in aac_unmap_command()
1654 bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap, in aac_unmap_command()
1656 if (cm->cm_flags & AAC_CMD_DATAOUT) in aac_unmap_command()
1657 bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap, in aac_unmap_command()
1660 bus_dmamap_unload(sc->aac_buffer_dmat, cm->cm_datamap); in aac_unmap_command()
1662 cm->cm_flags &= ~AAC_CMD_MAPPED; in aac_unmap_command()
1673 aac_common_map(void *arg, bus_dma_segment_t *segs, int nseg, int error) in aac_common_map()
1680 sc->aac_common_busaddr = segs[0].ds_addr; in aac_common_map()
1683 static int
1687 int rid, status; in aac_check_firmware()
1698 device_printf(sc->aac_dev, "FATAL: selftest failed\n"); in aac_check_firmware()
1702 device_printf(sc->aac_dev, in aac_check_firmware()
1707 device_printf(sc->aac_dev, in aac_check_firmware()
1718 if (sc->flags & AAC_FLAGS_PERC2QC) { in aac_check_firmware()
1721 device_printf(sc->aac_dev, in aac_check_firmware()
1727 major = (AAC_GET_MAILBOX(sc, 1) & 0xff) - 0x30; in aac_check_firmware()
1728 minor = (AAC_GET_MAILBOX(sc, 2) & 0xff) - 0x30; in aac_check_firmware()
1730 device_printf(sc->aac_dev, in aac_check_firmware()
1739 * work-arounds to enable. Some firmware revs don't support this in aac_check_firmware()
1744 device_printf(sc->aac_dev, in aac_check_firmware()
1751 sc->supported_options = options; in aac_check_firmware()
1754 (sc->flags & AAC_FLAGS_NO4GB) == 0) in aac_check_firmware()
1755 sc->flags |= AAC_FLAGS_4GB_WINDOW; in aac_check_firmware()
1757 sc->flags |= AAC_FLAGS_ENABLE_CAM; in aac_check_firmware()
1760 device_printf(sc->aac_dev, in aac_check_firmware()
1761 "Enabling 64-bit address support\n"); in aac_check_firmware()
1762 sc->flags |= AAC_FLAGS_SG_64BIT; in aac_check_firmware()
1765 && sc->aac_if->aif_send_command) in aac_check_firmware()
1766 sc->flags |= AAC_FLAGS_NEW_COMM; in aac_check_firmware()
1768 sc->flags |= AAC_FLAGS_ARRAY_64BIT; in aac_check_firmware()
1771 /* Check for broken hardware that does a lower number of commands */ in aac_check_firmware()
1772 sc->aac_max_fibs = (sc->flags & AAC_FLAGS_256FIBS ? 256:512); in aac_check_firmware()
1775 if ((sc->flags & AAC_FLAGS_NEW_COMM) && in aac_check_firmware()
1776 atu_size > rman_get_size(sc->aac_regs_res1)) { in aac_check_firmware()
1777 rid = rman_get_rid(sc->aac_regs_res1); in aac_check_firmware()
1778 bus_release_resource(sc->aac_dev, SYS_RES_MEMORY, rid, in aac_check_firmware()
1779 sc->aac_regs_res1); in aac_check_firmware()
1780 sc->aac_regs_res1 = bus_alloc_resource_anywhere(sc->aac_dev, in aac_check_firmware()
1782 if (sc->aac_regs_res1 == NULL) { in aac_check_firmware()
1783 sc->aac_regs_res1 = bus_alloc_resource_any( in aac_check_firmware()
1784 sc->aac_dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); in aac_check_firmware()
1785 if (sc->aac_regs_res1 == NULL) { in aac_check_firmware()
1786 device_printf(sc->aac_dev, in aac_check_firmware()
1790 sc->flags &= ~AAC_FLAGS_NEW_COMM; in aac_check_firmware()
1792 sc->aac_btag1 = rman_get_bustag(sc->aac_regs_res1); in aac_check_firmware()
1793 sc->aac_bhandle1 = rman_get_bushandle(sc->aac_regs_res1); in aac_check_firmware()
1795 if (sc->aac_hwif == AAC_HWIF_NARK) { in aac_check_firmware()
1796 sc->aac_regs_res0 = sc->aac_regs_res1; in aac_check_firmware()
1797 sc->aac_btag0 = sc->aac_btag1; in aac_check_firmware()
1798 sc->aac_bhandle0 = sc->aac_bhandle1; in aac_check_firmware()
1803 sc->aac_max_fib_size = sizeof(struct aac_fib); in aac_check_firmware()
1804 sc->aac_max_sectors = 128; /* 64KB */ in aac_check_firmware()
1805 if (sc->flags & AAC_FLAGS_SG_64BIT) in aac_check_firmware()
1806 sc->aac_sg_tablesize = (AAC_FIB_DATASIZE in aac_check_firmware()
1807 - sizeof(struct aac_blockwrite64)) in aac_check_firmware()
1810 sc->aac_sg_tablesize = (AAC_FIB_DATASIZE in aac_check_firmware()
1811 - sizeof(struct aac_blockwrite)) in aac_check_firmware()
1816 sc->aac_max_fib_size = (options & 0xFFFF); in aac_check_firmware()
1817 sc->aac_max_sectors = (options >> 16) << 1; in aac_check_firmware()
1819 sc->aac_sg_tablesize = (options >> 16); in aac_check_firmware()
1821 sc->aac_max_fibs = (options & 0xFFFF); in aac_check_firmware()
1823 if (sc->aac_max_fib_size > PAGE_SIZE) in aac_check_firmware()
1824 sc->aac_max_fib_size = PAGE_SIZE; in aac_check_firmware()
1825 sc->aac_max_fibs_alloc = PAGE_SIZE / sc->aac_max_fib_size; in aac_check_firmware()
1827 if (sc->aac_max_fib_size > sizeof(struct aac_fib)) { in aac_check_firmware()
1828 sc->flags |= AAC_FLAGS_RAW_IO; in aac_check_firmware()
1829 device_printf(sc->aac_dev, "Enable Raw I/O\n"); in aac_check_firmware()
1831 if ((sc->flags & AAC_FLAGS_RAW_IO) && in aac_check_firmware()
1832 (sc->flags & AAC_FLAGS_ARRAY_64BIT)) { in aac_check_firmware()
1833 sc->flags |= AAC_FLAGS_LBA_64BIT; in aac_check_firmware()
1834 device_printf(sc->aac_dev, "Enable 64-bit array\n"); in aac_check_firmware()
1840 static int
1845 int error; in aac_init()
1853 ip = &sc->aac_common->ac_init; in aac_init()
1854 ip->InitStructRevision = AAC_INIT_STRUCT_REVISION; in aac_init()
1855 if (sc->aac_max_fib_size > sizeof(struct aac_fib)) { in aac_init()
1856 ip->InitStructRevision = AAC_INIT_STRUCT_REVISION_4; in aac_init()
1857 sc->flags |= AAC_FLAGS_RAW_IO; in aac_init()
1859 ip->MiniPortRevision = AAC_INIT_STRUCT_MINIPORT_REVISION; in aac_init()
1861 ip->AdapterFibsPhysicalAddress = sc->aac_common_busaddr + in aac_init()
1863 ip->AdapterFibsVirtualAddress = 0; in aac_init()
1864 ip->AdapterFibsSize = AAC_ADAPTER_FIBS * sizeof(struct aac_fib); in aac_init()
1865 ip->AdapterFibAlign = sizeof(struct aac_fib); in aac_init()
1867 ip->PrintfBufferAddress = sc->aac_common_busaddr + in aac_init()
1869 ip->PrintfBufferSize = AAC_PRINTF_BUFSIZE; in aac_init()
1873 * broken firmware versions that do the page->byte conversion twice, in aac_init()
1877 ip->HostPhysMemPages = ctob(physmem) / AAC_PAGE_SIZE; in aac_init()
1878 if (sc->flags & AAC_FLAGS_BROKEN_MEMMAP) { in aac_init()
1879 ip->HostPhysMemPages = in aac_init()
1880 (ip->HostPhysMemPages + AAC_PAGE_SIZE) / AAC_PAGE_SIZE; in aac_init()
1882 ip->HostElapsedSeconds = time_uptime; /* reset later if invalid */ in aac_init()
1884 ip->InitFlags = 0; in aac_init()
1885 if (sc->flags & AAC_FLAGS_NEW_COMM) { in aac_init()
1886 ip->InitFlags |= AAC_INITFLAGS_NEW_COMM_SUPPORTED; in aac_init()
1887 device_printf(sc->aac_dev, "New comm. interface enabled\n"); in aac_init()
1890 ip->MaxIoCommands = sc->aac_max_fibs; in aac_init()
1891 ip->MaxIoSize = sc->aac_max_sectors << 9; in aac_init()
1892 ip->MaxFibSize = sc->aac_max_fib_size; in aac_init()
1911 qoffset &= ~(AAC_QUEUE_ALIGN - 1); in aac_init()
1912 sc->aac_queues = in aac_init()
1913 (struct aac_queue_table *)((uintptr_t)sc->aac_common + qoffset); in aac_init()
1914 ip->CommHeaderAddress = sc->aac_common_busaddr + qoffset; in aac_init()
1916 sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] = in aac_init()
1918 sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] = in aac_init()
1920 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] = in aac_init()
1922 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] = in aac_init()
1924 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] = in aac_init()
1926 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] = in aac_init()
1928 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] = in aac_init()
1930 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] = in aac_init()
1932 sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX]= in aac_init()
1934 sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX]= in aac_init()
1936 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX]= in aac_init()
1938 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX]= in aac_init()
1940 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX]= in aac_init()
1942 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX]= in aac_init()
1944 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX]= in aac_init()
1946 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX]= in aac_init()
1948 sc->aac_qentries[AAC_HOST_NORM_CMD_QUEUE] = in aac_init()
1949 &sc->aac_queues->qt_HostNormCmdQueue[0]; in aac_init()
1950 sc->aac_qentries[AAC_HOST_HIGH_CMD_QUEUE] = in aac_init()
1951 &sc->aac_queues->qt_HostHighCmdQueue[0]; in aac_init()
1952 sc->aac_qentries[AAC_ADAP_NORM_CMD_QUEUE] = in aac_init()
1953 &sc->aac_queues->qt_AdapNormCmdQueue[0]; in aac_init()
1954 sc->aac_qentries[AAC_ADAP_HIGH_CMD_QUEUE] = in aac_init()
1955 &sc->aac_queues->qt_AdapHighCmdQueue[0]; in aac_init()
1956 sc->aac_qentries[AAC_HOST_NORM_RESP_QUEUE] = in aac_init()
1957 &sc->aac_queues->qt_HostNormRespQueue[0]; in aac_init()
1958 sc->aac_qentries[AAC_HOST_HIGH_RESP_QUEUE] = in aac_init()
1959 &sc->aac_queues->qt_HostHighRespQueue[0]; in aac_init()
1960 sc->aac_qentries[AAC_ADAP_NORM_RESP_QUEUE] = in aac_init()
1961 &sc->aac_queues->qt_AdapNormRespQueue[0]; in aac_init()
1962 sc->aac_qentries[AAC_ADAP_HIGH_RESP_QUEUE] = in aac_init()
1963 &sc->aac_queues->qt_AdapHighRespQueue[0]; in aac_init()
1966 * Do controller-type-specific initialisation in aac_init()
1968 switch (sc->aac_hwif) { in aac_init()
1983 sc->aac_common_busaddr + in aac_init()
1986 device_printf(sc->aac_dev, in aac_init()
1997 static int
2001 if (sc->flags & AAC_FLAGS_NEW_COMM) { in aac_setup_intr()
2002 if (bus_setup_intr(sc->aac_dev, sc->aac_irq, in aac_setup_intr()
2004 aac_new_intr, sc, &sc->aac_intr)) { in aac_setup_intr()
2005 device_printf(sc->aac_dev, "can't set up interrupt\n"); in aac_setup_intr()
2009 if (bus_setup_intr(sc->aac_dev, sc->aac_irq, in aac_setup_intr()
2011 sc, &sc->aac_intr)) { in aac_setup_intr()
2012 device_printf(sc->aac_dev, in aac_setup_intr()
2024 static int
2061 return (-1); in aac_sync_command()
2065 int
2070 mtx_assert(&sc->aac_io_lock, MA_OWNED); in aac_sync_fib()
2078 fib->Header.XferState = AAC_FIBSTATE_HOSTOWNED | in aac_sync_fib()
2081 fib->Header.XferState |= xferstate; in aac_sync_fib()
2082 fib->Header.Command = command; in aac_sync_fib()
2083 fib->Header.StructType = AAC_FIBTYPE_TFIB; in aac_sync_fib()
2084 fib->Header.Size = sizeof(struct aac_fib_header) + datasize; in aac_sync_fib()
2085 fib->Header.SenderSize = sizeof(struct aac_fib); in aac_sync_fib()
2086 fib->Header.SenderFibAddress = 0; /* Not needed */ in aac_sync_fib()
2087 fib->Header.ReceiverFibAddress = sc->aac_common_busaddr + in aac_sync_fib()
2095 fib->Header.ReceiverFibAddress, 0, 0, 0, NULL)) { in aac_sync_fib()
2104 * Adapter-space FIB queue manipulation
2110 int size;
2111 int notify;
2132 static int
2133 aac_enqueue_fib(struct aac_softc *sc, int queue, struct aac_command *cm) in aac_enqueue_fib()
2136 int error; in aac_enqueue_fib()
2142 fib_size = cm->cm_fib->Header.Size; in aac_enqueue_fib()
2143 fib_addr = cm->cm_fib->Header.ReceiverFibAddress; in aac_enqueue_fib()
2146 pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX]; in aac_enqueue_fib()
2147 ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX]; in aac_enqueue_fib()
2166 (sc->aac_qentries[queue] + pi)->aq_fib_size = fib_size; in aac_enqueue_fib()
2167 (sc->aac_qentries[queue] + pi)->aq_fib_addr = fib_addr; in aac_enqueue_fib()
2170 sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX] = pi + 1; in aac_enqueue_fib()
2186 static int
2187 aac_dequeue_fib(struct aac_softc *sc, int queue, u_int32_t *fib_size, in aac_dequeue_fib()
2192 int error; in aac_dequeue_fib()
2193 int notify; in aac_dequeue_fib()
2198 pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX]; in aac_dequeue_fib()
2199 ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX]; in aac_dequeue_fib()
2220 *fib_size = (sc->aac_qentries[queue] + ci)->aq_fib_size; in aac_dequeue_fib()
2231 fib_index = (sc->aac_qentries[queue] + ci)->aq_fib_addr / in aac_dequeue_fib()
2233 *fib_addr = &sc->aac_common->ac_fibs[fib_index]; in aac_dequeue_fib()
2248 fib_index = (sc->aac_qentries[queue] + ci)->aq_fib_addr; in aac_dequeue_fib()
2249 cm = sc->aac_commands + (fib_index >> 2); in aac_dequeue_fib()
2250 *fib_addr = cm->cm_fib; in aac_dequeue_fib()
2257 (*fib_addr)->Header.XferState |= AAC_FIBSTATE_DONEADAP; in aac_dequeue_fib()
2258 *((u_int32_t*)((*fib_addr)->data)) = AAC_ERROR_NORMAL; in aac_dequeue_fib()
2268 sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX] = ci + 1; in aac_dequeue_fib()
2270 /* if we have made the queue un-full, notify the adapter */ in aac_dequeue_fib()
2282 static int
2283 aac_enqueue_response(struct aac_softc *sc, int queue, struct aac_fib *fib) in aac_enqueue_response()
2286 int error; in aac_enqueue_response()
2293 fib_size = fib->Header.Size; in aac_enqueue_response()
2294 fib_addr = fib->Header.SenderFibAddress; in aac_enqueue_response()
2295 fib->Header.ReceiverFibAddress = fib_addr; in aac_enqueue_response()
2298 pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX]; in aac_enqueue_response()
2299 ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX]; in aac_enqueue_response()
2312 (sc->aac_qentries[queue] + pi)->aq_fib_size = fib_size; in aac_enqueue_response()
2313 (sc->aac_qentries[queue] + pi)->aq_fib_addr = fib_addr; in aac_enqueue_response()
2316 sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX] = pi + 1; in aac_enqueue_response()
2337 int timedout, code; in aac_timeout()
2344 deadline = time_uptime - AAC_CMD_TIMEOUT; in aac_timeout()
2345 TAILQ_FOREACH(cm, &sc->aac_busy, cm_link) { in aac_timeout()
2346 if ((cm->cm_timestamp < deadline) in aac_timeout()
2347 && !(cm->cm_flags & AAC_CMD_TIMEDOUT)) { in aac_timeout()
2348 cm->cm_flags |= AAC_CMD_TIMEDOUT; in aac_timeout()
2349 device_printf(sc->aac_dev, in aac_timeout()
2351 cm, cm->cm_fib->Header.Command, in aac_timeout()
2352 (int)(time_uptime-cm->cm_timestamp)); in aac_timeout()
2353 AAC_PRINT_FIB(sc, cm->cm_fib); in aac_timeout()
2361 device_printf(sc->aac_dev, "WARNING! Controller is no " in aac_timeout()
2374 static int
2382 static int
2387 return(AAC_MEM0_GETREG4(sc, sc->flags & AAC_FLAGS_NEW_COMM ? in aac_rx_get_fwstatus()
2391 static int
2396 return(AAC_MEM0_GETREG4(sc, sc->flags & AAC_FLAGS_NEW_COMM ? in aac_rkt_get_fwstatus()
2405 aac_sa_qnotify(struct aac_softc *sc, int qbit) in aac_sa_qnotify()
2413 aac_rx_qnotify(struct aac_softc *sc, int qbit) in aac_rx_qnotify()
2421 aac_rkt_qnotify(struct aac_softc *sc, int qbit) in aac_rkt_qnotify()
2431 static int
2439 static int
2447 static int
2459 aac_sa_clear_istatus(struct aac_softc *sc, int mask) in aac_sa_clear_istatus()
2467 aac_rx_clear_istatus(struct aac_softc *sc, int mask) in aac_rx_clear_istatus()
2475 aac_rkt_clear_istatus(struct aac_softc *sc, int mask) in aac_rkt_clear_istatus()
2527 static int
2528 aac_sa_get_mailbox(struct aac_softc *sc, int mb) in aac_sa_get_mailbox()
2535 static int
2536 aac_rx_get_mailbox(struct aac_softc *sc, int mb) in aac_rx_get_mailbox()
2543 static int
2544 aac_rkt_get_mailbox(struct aac_softc *sc, int mb) in aac_rkt_get_mailbox()
2555 aac_sa_set_interrupts(struct aac_softc *sc, int enable) in aac_sa_set_interrupts()
2567 aac_rx_set_interrupts(struct aac_softc *sc, int enable) in aac_rx_set_interrupts()
2572 if (sc->flags & AAC_FLAGS_NEW_COMM) in aac_rx_set_interrupts()
2582 aac_rkt_set_interrupts(struct aac_softc *sc, int enable) in aac_rkt_set_interrupts()
2587 if (sc->flags & AAC_FLAGS_NEW_COMM) in aac_rkt_set_interrupts()
2599 static int
2613 AAC_MEM1_SETREG4(sc, device, (u_int32_t)(cm->cm_fibphys & 0xffffffffUL)); in aac_rx_send_command()
2615 AAC_MEM1_SETREG4(sc, device, (u_int32_t)(cm->cm_fibphys >> 32)); in aac_rx_send_command()
2617 AAC_MEM1_SETREG4(sc, device, cm->cm_fib->Header.Size); in aac_rx_send_command()
2622 static int
2636 AAC_MEM1_SETREG4(sc, device, (u_int32_t)(cm->cm_fibphys & 0xffffffffUL)); in aac_rkt_send_command()
2638 AAC_MEM1_SETREG4(sc, device, (u_int32_t)(cm->cm_fibphys >> 32)); in aac_rkt_send_command()
2640 AAC_MEM1_SETREG4(sc, device, cm->cm_fib->Header.Size); in aac_rkt_send_command()
2648 static int
2656 static int
2665 aac_rx_set_outb_queue(struct aac_softc *sc, int index) in aac_rx_set_outb_queue()
2673 aac_rkt_set_outb_queue(struct aac_softc *sc, int index) in aac_rkt_set_outb_queue()
2696 mtx_lock(&sc->aac_io_lock); in aac_describe_controller()
2699 fib->data[0] = 0; in aac_describe_controller()
2701 device_printf(sc->aac_dev, "RequestAdapterInfo failed\n"); in aac_describe_controller()
2703 mtx_unlock(&sc->aac_io_lock); in aac_describe_controller()
2708 info = (struct aac_adapter_info *)&fib->data[0]; in aac_describe_controller()
2709 sc->aac_revision = info->KernelRevision; in aac_describe_controller()
2712 device_printf(sc->aac_dev, "%s %dMHz, %dMB memory " in aac_describe_controller()
2714 aac_describe_code(aac_cpu_variant, info->CpuVariant), in aac_describe_controller()
2715 info->ClockSpeed, info->TotalMem / (1024 * 1024), in aac_describe_controller()
2716 info->BufferMem / (1024 * 1024), in aac_describe_controller()
2717 info->ExecutionMem / (1024 * 1024), in aac_describe_controller()
2719 info->batteryPlatform)); in aac_describe_controller()
2721 device_printf(sc->aac_dev, in aac_describe_controller()
2722 "Kernel %d.%d-%d, Build %d, S/N %6X\n", in aac_describe_controller()
2723 info->KernelRevision.external.comp.major, in aac_describe_controller()
2724 info->KernelRevision.external.comp.minor, in aac_describe_controller()
2725 info->KernelRevision.external.comp.dash, in aac_describe_controller()
2726 info->KernelRevision.buildNumber, in aac_describe_controller()
2727 (u_int32_t)(info->SerialNumber & 0xffffff)); in aac_describe_controller()
2729 device_printf(sc->aac_dev, "Supported Options=%b\n", in aac_describe_controller()
2730 sc->supported_options, in aac_describe_controller()
2753 if (sc->supported_options & AAC_SUPPORTED_SUPPLEMENT_ADAPTER_INFO) { in aac_describe_controller()
2754 fib->data[0] = 0; in aac_describe_controller()
2756 device_printf(sc->aac_dev, in aac_describe_controller()
2760 &fib->data[0])->AdapterTypeText; in aac_describe_controller()
2762 device_printf(sc->aac_dev, "%s, aac driver %d.%d.%d-%d\n", in aac_describe_controller()
2768 mtx_unlock(&sc->aac_io_lock); in aac_describe_controller()
2778 int i; in aac_describe_code()
2790 static int
2791 aac_open(struct cdev *dev, int flags, int fmt, struct thread *td) in aac_open()
2795 sc = dev->si_drv1; in aac_open()
2797 device_busy(sc->aac_dev); in aac_open()
2803 static int
2804 aac_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, struct thread *td) in aac_ioctl()
2808 int error = 0; in aac_ioctl()
2811 sc = dev->si_drv1; in aac_ioctl()
2816 switch (as->as_item) { in aac_ioctl()
2821 bcopy(&sc->aac_qstat[as->as_item], &as->as_qstat, in aac_ioctl()
2908 static int
2909 aac_poll(struct cdev *dev, int poll_events, struct thread *td) in aac_poll()
2913 int revents; in aac_poll()
2915 sc = dev->si_drv1; in aac_poll()
2918 mtx_lock(&sc->aac_aifq_lock); in aac_poll()
2920 for (ctx = sc->fibctx; ctx; ctx = ctx->next) { in aac_poll()
2921 if (ctx->ctx_idx != sc->aifq_idx || ctx->ctx_wrap) { in aac_poll()
2927 mtx_unlock(&sc->aac_aifq_lock); in aac_poll()
2931 selrecord(td, &sc->rcv_select); in aac_poll()
2941 switch (event->ev_type) { in aac_ioctl_event()
2943 mtx_assert(&sc->aac_io_lock, MA_OWNED); in aac_ioctl_event()
2959 static int
2963 int size, error; in aac_ioctl_sendfib()
2972 mtx_lock(&sc->aac_io_lock); in aac_ioctl_sendfib()
2980 mtx_unlock(&sc->aac_io_lock); in aac_ioctl_sendfib()
2983 event->ev_type = AAC_EVENT_CMFREE; in aac_ioctl_sendfib()
2984 event->ev_callback = aac_ioctl_event; in aac_ioctl_sendfib()
2985 event->ev_arg = &cm; in aac_ioctl_sendfib()
2987 msleep(&cm, &sc->aac_io_lock, 0, "sendfib", 0); in aac_ioctl_sendfib()
2989 mtx_unlock(&sc->aac_io_lock); in aac_ioctl_sendfib()
2992 * Fetch the FIB header, then re-copy to get data as well. in aac_ioctl_sendfib()
2994 if ((error = copyin(ufib, cm->cm_fib, in aac_ioctl_sendfib()
2997 size = cm->cm_fib->Header.Size + sizeof(struct aac_fib_header); in aac_ioctl_sendfib()
2998 if (size > sc->aac_max_fib_size) { in aac_ioctl_sendfib()
2999 device_printf(sc->aac_dev, "incoming FIB oversized (%d > %d)\n", in aac_ioctl_sendfib()
3000 size, sc->aac_max_fib_size); in aac_ioctl_sendfib()
3001 size = sc->aac_max_fib_size; in aac_ioctl_sendfib()
3003 if ((error = copyin(ufib, cm->cm_fib, size)) != 0) in aac_ioctl_sendfib()
3005 cm->cm_fib->Header.Size = size; in aac_ioctl_sendfib()
3006 cm->cm_timestamp = time_uptime; in aac_ioctl_sendfib()
3011 mtx_lock(&sc->aac_io_lock); in aac_ioctl_sendfib()
3013 mtx_unlock(&sc->aac_io_lock); in aac_ioctl_sendfib()
3015 device_printf(sc->aac_dev, in aac_ioctl_sendfib()
3023 size = cm->cm_fib->Header.Size; in aac_ioctl_sendfib()
3024 if (size > sc->aac_max_fib_size) { in aac_ioctl_sendfib()
3025 device_printf(sc->aac_dev, "outbound FIB oversized (%d > %d)\n", in aac_ioctl_sendfib()
3026 size, sc->aac_max_fib_size); in aac_ioctl_sendfib()
3027 size = sc->aac_max_fib_size; in aac_ioctl_sendfib()
3029 error = copyout(cm->cm_fib, ufib, size); in aac_ioctl_sendfib()
3033 mtx_lock(&sc->aac_io_lock); in aac_ioctl_sendfib()
3035 mtx_unlock(&sc->aac_io_lock); in aac_ioctl_sendfib()
3043 static int
3053 int error, transfer_data; in aac_ioctl_send_raw_srb()
3062 mtx_lock(&sc->aac_io_lock); in aac_ioctl_send_raw_srb()
3068 mtx_unlock(&sc->aac_io_lock); in aac_ioctl_send_raw_srb()
3071 event->ev_type = AAC_EVENT_CMFREE; in aac_ioctl_send_raw_srb()
3072 event->ev_callback = aac_ioctl_event; in aac_ioctl_send_raw_srb()
3073 event->ev_arg = &cm; in aac_ioctl_send_raw_srb()
3075 msleep(cm, &sc->aac_io_lock, 0, "aacraw", 0); in aac_ioctl_send_raw_srb()
3077 mtx_unlock(&sc->aac_io_lock); in aac_ioctl_send_raw_srb()
3079 cm->cm_data = NULL; in aac_ioctl_send_raw_srb()
3080 fib = cm->cm_fib; in aac_ioctl_send_raw_srb()
3081 srbcmd = (struct aac_srb *)fib->data; in aac_ioctl_send_raw_srb()
3082 error = copyin(&user_srb->data_len, &fibsize, sizeof(uint32_t)); in aac_ioctl_send_raw_srb()
3085 if (fibsize > (sc->aac_max_fib_size - sizeof(struct aac_fib_header))) { in aac_ioctl_send_raw_srb()
3092 srbcmd->function = 0; in aac_ioctl_send_raw_srb()
3093 srbcmd->retry_limit = 0; in aac_ioctl_send_raw_srb()
3094 if (srbcmd->sg_map.SgCount > 1) { in aac_ioctl_send_raw_srb()
3101 srbcmd->sg_map.SgCount * sizeof(struct aac_sg_entry))) { in aac_ioctl_send_raw_srb()
3104 sge = srbcmd->sg_map.SgEntry; in aac_ioctl_send_raw_srb()
3114 srbcmd->sg_map.SgCount * sizeof(struct aac_sg_entry64))) { in aac_ioctl_send_raw_srb()
3119 sge64 = (struct aac_sg_entry64 *)srbcmd->sg_map.SgEntry; in aac_ioctl_send_raw_srb()
3126 if (sge64->SgAddress > 0xffffffffull && in aac_ioctl_send_raw_srb()
3127 (sc->flags & AAC_FLAGS_SG_64BIT) == 0) { in aac_ioctl_send_raw_srb()
3138 srbcmd->data_len = srb_sg_bytecount; in aac_ioctl_send_raw_srb()
3139 if (srbcmd->sg_map.SgCount == 1) in aac_ioctl_send_raw_srb()
3142 cm->cm_sgtable = (struct aac_sg_table *)&srbcmd->sg_map; in aac_ioctl_send_raw_srb()
3144 cm->cm_datalen = srb_sg_bytecount; in aac_ioctl_send_raw_srb()
3145 cm->cm_data = malloc(cm->cm_datalen, M_AACBUF, M_NOWAIT); in aac_ioctl_send_raw_srb()
3146 if (cm->cm_data == NULL) { in aac_ioctl_send_raw_srb()
3150 if (srbcmd->flags & AAC_SRB_FLAGS_DATA_IN) in aac_ioctl_send_raw_srb()
3151 cm->cm_flags |= AAC_CMD_DATAIN; in aac_ioctl_send_raw_srb()
3152 if (srbcmd->flags & AAC_SRB_FLAGS_DATA_OUT) { in aac_ioctl_send_raw_srb()
3153 cm->cm_flags |= AAC_CMD_DATAOUT; in aac_ioctl_send_raw_srb()
3154 error = copyin(srb_sg_address, cm->cm_data, in aac_ioctl_send_raw_srb()
3155 cm->cm_datalen); in aac_ioctl_send_raw_srb()
3161 fib->Header.Size = sizeof(struct aac_fib_header) + in aac_ioctl_send_raw_srb()
3163 fib->Header.XferState = in aac_ioctl_send_raw_srb()
3172 fib->Header.Command = (sc->flags & AAC_FLAGS_SG_64BIT) != 0 ? in aac_ioctl_send_raw_srb()
3175 mtx_lock(&sc->aac_io_lock); in aac_ioctl_send_raw_srb()
3177 mtx_unlock(&sc->aac_io_lock); in aac_ioctl_send_raw_srb()
3179 if (transfer_data && (srbcmd->flags & AAC_SRB_FLAGS_DATA_IN) != 0) { in aac_ioctl_send_raw_srb()
3180 error = copyout(cm->cm_data, srb_sg_address, cm->cm_datalen); in aac_ioctl_send_raw_srb()
3184 error = copyout(fib->data, ureply, sizeof(struct aac_srb_response)); in aac_ioctl_send_raw_srb()
3187 if (cm->cm_data != NULL) in aac_ioctl_send_raw_srb()
3188 free(cm->cm_data, M_AACBUF); in aac_ioctl_send_raw_srb()
3189 mtx_lock(&sc->aac_io_lock); in aac_ioctl_send_raw_srb()
3191 mtx_unlock(&sc->aac_io_lock); in aac_ioctl_send_raw_srb()
3206 device_unbusy(sc->aac_dev); in aac_cdevpriv_dtor()
3220 int next, current, found; in aac_handle_aif()
3221 int count = 0, added = 0, i = 0; in aac_handle_aif()
3226 aif = (struct aac_aif_command*)&fib->data[0]; in aac_handle_aif()
3230 switch (aif->command) { in aac_handle_aif()
3232 switch (aif->data.EN.type) { in aac_handle_aif()
3237 * doesn't tell us anything else! Re-enumerate the in aac_handle_aif()
3252 count = mir->MntRespCount; in aac_handle_aif()
3255 * co->co_found was already set to 0 in a in aac_handle_aif()
3258 if ((mir->Status == ST_OK) && in aac_handle_aif()
3259 (mir->MntTable[0].VolType != CT_NONE)) { in aac_handle_aif()
3262 &sc->aac_container_tqh, in aac_handle_aif()
3264 if (co->co_mntobj.ObjectId == in aac_handle_aif()
3265 mir->MntTable[0].ObjectId) { in aac_handle_aif()
3266 co->co_found = 1; in aac_handle_aif()
3296 * the co->co_found field. in aac_handle_aif()
3298 co = TAILQ_FIRST(&sc->aac_container_tqh); in aac_handle_aif()
3300 if (co->co_found == 0) { in aac_handle_aif()
3301 mtx_unlock(&sc->aac_io_lock); in aac_handle_aif()
3303 device_delete_child(sc->aac_dev, in aac_handle_aif()
3304 co->co_disk); in aac_handle_aif()
3306 mtx_lock(&sc->aac_io_lock); in aac_handle_aif()
3308 mtx_lock(&sc->aac_container_lock); in aac_handle_aif()
3309 TAILQ_REMOVE(&sc->aac_container_tqh, co, in aac_handle_aif()
3311 mtx_unlock(&sc->aac_container_lock); in aac_handle_aif()
3315 co->co_found = 0; in aac_handle_aif()
3322 mtx_unlock(&sc->aac_io_lock); in aac_handle_aif()
3324 bus_attach_children(sc->aac_dev); in aac_handle_aif()
3326 mtx_lock(&sc->aac_io_lock); in aac_handle_aif()
3332 switch (aif->data.EN.data.EEE.eventType) { in aac_handle_aif()
3335 channel = aif->data.EN.data.EEE.unitID; in aac_handle_aif()
3336 if (sc->cam_rescan_cb != NULL) in aac_handle_aif()
3337 sc->cam_rescan_cb(sc, in aac_handle_aif()
3346 channel = aif->data.EN.data.ECE.container; in aac_handle_aif()
3347 if (sc->cam_rescan_cb != NULL) in aac_handle_aif()
3348 sc->cam_rescan_cb(sc, (channel >> 24) & 0xF, in aac_handle_aif()
3361 mtx_lock(&sc->aac_aifq_lock); in aac_handle_aif()
3362 current = sc->aifq_idx; in aac_handle_aif()
3365 sc->aifq_filled = 1; in aac_handle_aif()
3366 bcopy(fib, &sc->aac_aifq[current], sizeof(struct aac_fib)); in aac_handle_aif()
3368 if (sc->aifq_filled) { in aac_handle_aif()
3369 for (ctx = sc->fibctx; ctx; ctx = ctx->next) { in aac_handle_aif()
3370 if (next == ctx->ctx_idx) in aac_handle_aif()
3371 ctx->ctx_wrap = 1; in aac_handle_aif()
3372 else if (current == ctx->ctx_idx && ctx->ctx_wrap) in aac_handle_aif()
3373 ctx->ctx_idx = next; in aac_handle_aif()
3376 sc->aifq_idx = next; in aac_handle_aif()
3378 if (sc->aac_state & AAC_STATE_AIF_SLEEPER) in aac_handle_aif()
3379 wakeup(sc->aac_aifq); in aac_handle_aif()
3381 selwakeuppri(&sc->rcv_select, PRIBIO); in aac_handle_aif()
3382 mtx_unlock(&sc->aac_aifq_lock); in aac_handle_aif()
3391 static int
3396 int error = 0; in aac_rev_check()
3433 static int
3437 int error = 0; in aac_open_aif()
3445 mtx_lock(&sc->aac_aifq_lock); in aac_open_aif()
3447 if (sc->fibctx == NULL) in aac_open_aif()
3448 sc->fibctx = fibctx; in aac_open_aif()
3450 for (ctx = sc->fibctx; ctx->next; ctx = ctx->next) in aac_open_aif()
3452 ctx->next = fibctx; in aac_open_aif()
3453 fibctx->prev = ctx; in aac_open_aif()
3457 fibctx->unique = (*(u_int32_t *)&fibctx & 0xffffffff); in aac_open_aif()
3458 ctx = sc->fibctx; in aac_open_aif()
3460 if (ctx->unique == fibctx->unique) { in aac_open_aif()
3461 fibctx->unique++; in aac_open_aif()
3462 ctx = sc->fibctx; in aac_open_aif()
3464 ctx = ctx->next; in aac_open_aif()
3467 mtx_unlock(&sc->aac_aifq_lock); in aac_open_aif()
3469 error = copyout(&fibctx->unique, (void *)arg, sizeof(u_int32_t)); in aac_open_aif()
3478 static int
3485 mtx_lock(&sc->aac_aifq_lock); in aac_close_aif()
3486 for (ctx = sc->fibctx; ctx; ctx = ctx->next) { in aac_close_aif()
3487 if (ctx->unique == *(uint32_t *)&arg) { in aac_close_aif()
3488 if (ctx == sc->fibctx) in aac_close_aif()
3489 sc->fibctx = NULL; in aac_close_aif()
3491 ctx->prev->next = ctx->next; in aac_close_aif()
3492 if (ctx->next) in aac_close_aif()
3493 ctx->next->prev = ctx->prev; in aac_close_aif()
3498 mtx_unlock(&sc->aac_aifq_lock); in aac_close_aif()
3508 static int
3513 int error; in aac_getnext_aif()
3530 for (ctx = sc->fibctx; ctx; ctx = ctx->next) { in aac_getnext_aif()
3531 if (agf.AdapterFibContext == ctx->unique) in aac_getnext_aif()
3540 sc->aac_state |= AAC_STATE_AIF_SLEEPER; in aac_getnext_aif()
3542 error = tsleep(sc->aac_aifq, PRIBIO | in aac_getnext_aif()
3547 sc->aac_state &= ~AAC_STATE_AIF_SLEEPER; in aac_getnext_aif()
3556 static int
3559 int current, error; in aac_return_aif()
3563 mtx_lock(&sc->aac_aifq_lock); in aac_return_aif()
3564 current = ctx->ctx_idx; in aac_return_aif()
3565 if (current == sc->aifq_idx && !ctx->ctx_wrap) { in aac_return_aif()
3567 mtx_unlock(&sc->aac_aifq_lock); in aac_return_aif()
3571 copyout(&sc->aac_aifq[current], (void *)uptr, sizeof(struct aac_fib)); in aac_return_aif()
3573 device_printf(sc->aac_dev, in aac_return_aif()
3576 ctx->ctx_wrap = 0; in aac_return_aif()
3577 ctx->ctx_idx = (current + 1) % AAC_AIFQ_LENGTH; in aac_return_aif()
3579 mtx_unlock(&sc->aac_aifq_lock); in aac_return_aif()
3583 static int
3590 int error; in aac_get_pci_info()
3594 pciinf.bus = pci_get_bus(sc->aac_dev); in aac_get_pci_info()
3595 pciinf.slot = pci_get_slot(sc->aac_dev); in aac_get_pci_info()
3603 static int
3607 int error; in aac_supported_features()
3627 (sc->flags & AAC_FLAGS_LBA_64BIT) ? 1 : 0; in aac_supported_features()
3632 (sc->flags & AAC_FLAGS_LBA_64BIT) ? 1 : 0; in aac_supported_features()
3645 static int
3651 int error, id; in aac_query_disk()
3663 if (id == -1) in aac_query_disk()
3666 mtx_lock(&sc->aac_container_lock); in aac_query_disk()
3667 TAILQ_FOREACH(co, &sc->aac_container_tqh, co_link) { in aac_query_disk()
3668 if (co->co_mntobj.ObjectId == id) in aac_query_disk()
3677 disk = device_get_softc(co->co_disk); in aac_query_disk()
3680 (disk->ad_flags & AAC_DISK_OPEN) ? 1 : 0; in aac_query_disk()
3682 query_disk.Bus = device_get_unit(sc->aac_dev); in aac_query_disk()
3683 query_disk.Target = disk->unit; in aac_query_disk()
3687 disk->ad_disk->d_name, disk->ad_disk->d_unit); in aac_query_disk()
3689 mtx_unlock(&sc->aac_container_lock); in aac_query_disk()
3708 int i, found, error; in aac_get_bus_info()
3710 mtx_lock(&sc->aac_io_lock); in aac_get_bus_info()
3712 c_cmd = (struct aac_ctcfg *)&fib->data[0]; in aac_get_bus_info()
3715 c_cmd->Command = VM_ContainerConfig; in aac_get_bus_info()
3716 c_cmd->cmd = CT_GET_SCSI_METHOD; in aac_get_bus_info()
3717 c_cmd->param = 0; in aac_get_bus_info()
3722 device_printf(sc->aac_dev, "Error %d sending " in aac_get_bus_info()
3725 mtx_unlock(&sc->aac_io_lock); in aac_get_bus_info()
3729 c_resp = (struct aac_ctcfg_resp *)&fib->data[0]; in aac_get_bus_info()
3730 if (c_resp->Status != ST_OK) { in aac_get_bus_info()
3731 device_printf(sc->aac_dev, "VM_ContainerConfig returned 0x%x\n", in aac_get_bus_info()
3732 c_resp->Status); in aac_get_bus_info()
3734 mtx_unlock(&sc->aac_io_lock); in aac_get_bus_info()
3738 sc->scsi_method_id = c_resp->param; in aac_get_bus_info()
3740 vmi = (struct aac_vmioctl *)&fib->data[0]; in aac_get_bus_info()
3743 vmi->Command = VM_Ioctl; in aac_get_bus_info()
3744 vmi->ObjType = FT_DRIVE; in aac_get_bus_info()
3745 vmi->MethId = sc->scsi_method_id; in aac_get_bus_info()
3746 vmi->ObjId = 0; in aac_get_bus_info()
3747 vmi->IoctlCmd = GetBusInfo; in aac_get_bus_info()
3752 device_printf(sc->aac_dev, "Error %d sending VMIoctl command\n", in aac_get_bus_info()
3755 mtx_unlock(&sc->aac_io_lock); in aac_get_bus_info()
3759 vmi_resp = (struct aac_vmi_businf_resp *)&fib->data[0]; in aac_get_bus_info()
3760 if (vmi_resp->Status != ST_OK) { in aac_get_bus_info()
3761 device_printf(sc->aac_dev, "VM_Ioctl returned %d\n", in aac_get_bus_info()
3762 vmi_resp->Status); in aac_get_bus_info()
3764 mtx_unlock(&sc->aac_io_lock); in aac_get_bus_info()
3768 bcopy(&vmi_resp->BusInf, &businfo, sizeof(struct aac_getbusinf)); in aac_get_bus_info()
3770 mtx_unlock(&sc->aac_io_lock); in aac_get_bus_info()
3780 device_printf(sc->aac_dev, in aac_get_bus_info()
3785 child = device_add_child(sc->aac_dev, "aacp", DEVICE_UNIT_ANY); in aac_get_bus_info()
3787 device_printf(sc->aac_dev, in aac_get_bus_info()
3794 caminf->TargetsPerBus = businfo.TargetsPerBus; in aac_get_bus_info()
3795 caminf->BusNumber = i; in aac_get_bus_info()
3796 caminf->InitiatorBusId = businfo.InitiatorBusId[i]; in aac_get_bus_info()
3797 caminf->aac_sc = sc; in aac_get_bus_info()
3798 caminf->sim_dev = child; in aac_get_bus_info()
3802 TAILQ_INSERT_TAIL(&sc->aac_sim_tqh, caminf, sim_link); in aac_get_bus_info()
3808 bus_attach_children(sc->aac_dev); in aac_get_bus_info()