Lines Matching full:sc

57 static inline uint32_t pvscsi_reg_read(struct pvscsi_softc *sc,
59 static inline void pvscsi_reg_write(struct pvscsi_softc *sc, uint32_t offset,
61 static inline uint32_t pvscsi_read_intr_status(struct pvscsi_softc *sc);
62 static inline void pvscsi_write_intr_status(struct pvscsi_softc *sc,
64 static inline void pvscsi_intr_enable(struct pvscsi_softc *sc);
65 static inline void pvscsi_intr_disable(struct pvscsi_softc *sc);
66 static void pvscsi_kick_io(struct pvscsi_softc *sc, uint8_t cdb0);
67 static void pvscsi_write_cmd(struct pvscsi_softc *sc, uint32_t cmd, void *data,
69 static uint32_t pvscsi_get_max_targets(struct pvscsi_softc *sc);
70 static int pvscsi_setup_req_call(struct pvscsi_softc *sc, uint32_t enable);
71 static void pvscsi_setup_rings(struct pvscsi_softc *sc);
72 static void pvscsi_setup_msg_ring(struct pvscsi_softc *sc);
73 static int pvscsi_hw_supports_msg(struct pvscsi_softc *sc);
76 static void pvscsi_freeze(struct pvscsi_softc *sc);
77 static void pvscsi_adapter_reset(struct pvscsi_softc *sc);
78 static void pvscsi_bus_reset(struct pvscsi_softc *sc);
79 static void pvscsi_device_reset(struct pvscsi_softc *sc, uint32_t target);
80 static void pvscsi_abort(struct pvscsi_softc *sc, uint32_t target,
83 static void pvscsi_process_completion(struct pvscsi_softc *sc,
85 static void pvscsi_process_cmp_ring(struct pvscsi_softc *sc);
86 static void pvscsi_process_msg(struct pvscsi_softc *sc,
88 static void pvscsi_process_msg_ring(struct pvscsi_softc *sc);
90 static void pvscsi_intr_locked(struct pvscsi_softc *sc);
98 static inline uint64_t pvscsi_hcb_to_context(struct pvscsi_softc *sc,
100 static inline struct pvscsi_hcb* pvscsi_context_to_hcb(struct pvscsi_softc *sc,
102 static struct pvscsi_hcb * pvscsi_hcb_get(struct pvscsi_softc *sc);
103 static void pvscsi_hcb_put(struct pvscsi_softc *sc, struct pvscsi_hcb *hcb);
107 static void pvscsi_dma_free(struct pvscsi_softc *sc, struct pvscsi_dma *dma);
108 static int pvscsi_dma_alloc(struct pvscsi_softc *sc, struct pvscsi_dma *dma,
110 static int pvscsi_dma_alloc_ppns(struct pvscsi_softc *sc,
112 static void pvscsi_dma_free_per_hcb(struct pvscsi_softc *sc,
114 static int pvscsi_dma_alloc_per_hcb(struct pvscsi_softc *sc);
115 static void pvscsi_free_rings(struct pvscsi_softc *sc);
116 static int pvscsi_allocate_rings(struct pvscsi_softc *sc);
117 static void pvscsi_free_interrupts(struct pvscsi_softc *sc);
118 static int pvscsi_setup_interrupts(struct pvscsi_softc *sc);
119 static void pvscsi_free_all(struct pvscsi_softc *sc);
125 static int pvscsi_get_tunable(struct pvscsi_softc *sc, char *name, int value);
231 static int pvscsi_get_tunable(struct pvscsi_softc *sc, char *name, int value) in pvscsi_get_tunable() argument
235 snprintf(cfg, sizeof(cfg), "hw.pvscsi.%d.%s", device_get_unit(sc->dev), in pvscsi_get_tunable()
243 pvscsi_freeze(struct pvscsi_softc *sc) in pvscsi_freeze() argument
246 if (!sc->frozen) { in pvscsi_freeze()
247 xpt_freeze_simq(sc->sim, 1); in pvscsi_freeze()
248 sc->frozen = 1; in pvscsi_freeze()
253 pvscsi_reg_read(struct pvscsi_softc *sc, uint32_t offset) in pvscsi_reg_read() argument
256 return (bus_read_4(sc->mm_res, offset)); in pvscsi_reg_read()
260 pvscsi_reg_write(struct pvscsi_softc *sc, uint32_t offset, uint32_t val) in pvscsi_reg_write() argument
263 bus_write_4(sc->mm_res, offset, val); in pvscsi_reg_write()
267 pvscsi_read_intr_status(struct pvscsi_softc *sc) in pvscsi_read_intr_status() argument
270 return (pvscsi_reg_read(sc, PVSCSI_REG_OFFSET_INTR_STATUS)); in pvscsi_read_intr_status()
274 pvscsi_write_intr_status(struct pvscsi_softc *sc, uint32_t val) in pvscsi_write_intr_status() argument
277 pvscsi_reg_write(sc, PVSCSI_REG_OFFSET_INTR_STATUS, val); in pvscsi_write_intr_status()
281 pvscsi_intr_enable(struct pvscsi_softc *sc) in pvscsi_intr_enable() argument
286 if (sc->use_msg) { in pvscsi_intr_enable()
290 pvscsi_reg_write(sc, PVSCSI_REG_OFFSET_INTR_MASK, mask); in pvscsi_intr_enable()
294 pvscsi_intr_disable(struct pvscsi_softc *sc) in pvscsi_intr_disable() argument
297 pvscsi_reg_write(sc, PVSCSI_REG_OFFSET_INTR_MASK, 0); in pvscsi_intr_disable()
301 pvscsi_kick_io(struct pvscsi_softc *sc, uint8_t cdb0) in pvscsi_kick_io() argument
309 s = sc->rings_state; in pvscsi_kick_io()
311 if (!sc->use_req_call_threshold || in pvscsi_kick_io()
314 pvscsi_reg_write(sc, PVSCSI_REG_OFFSET_KICK_RW_IO, 0); in pvscsi_kick_io()
317 pvscsi_reg_write(sc, PVSCSI_REG_OFFSET_KICK_NON_RW_IO, 0); in pvscsi_kick_io()
322 pvscsi_write_cmd(struct pvscsi_softc *sc, uint32_t cmd, void *data, in pvscsi_write_cmd() argument
334 pvscsi_reg_write(sc, PVSCSI_REG_OFFSET_COMMAND, cmd); in pvscsi_write_cmd()
336 pvscsi_reg_write(sc, PVSCSI_REG_OFFSET_COMMAND_DATA, in pvscsi_write_cmd()
341 static inline uint64_t pvscsi_hcb_to_context(struct pvscsi_softc *sc, in pvscsi_hcb_to_context() argument
346 return (hcb - sc->hcbs + 1); in pvscsi_hcb_to_context()
349 static inline struct pvscsi_hcb* pvscsi_context_to_hcb(struct pvscsi_softc *sc, in pvscsi_context_to_hcb() argument
353 return (sc->hcbs + (context - 1)); in pvscsi_context_to_hcb()
357 pvscsi_hcb_get(struct pvscsi_softc *sc) in pvscsi_hcb_get() argument
361 mtx_assert(&sc->lock, MA_OWNED); in pvscsi_hcb_get()
363 hcb = SLIST_FIRST(&sc->free_list); in pvscsi_hcb_get()
365 SLIST_REMOVE_HEAD(&sc->free_list, links); in pvscsi_hcb_get()
372 pvscsi_hcb_put(struct pvscsi_softc *sc, struct pvscsi_hcb *hcb) in pvscsi_hcb_put() argument
375 mtx_assert(&sc->lock, MA_OWNED); in pvscsi_hcb_put()
379 SLIST_INSERT_HEAD(&sc->free_list, hcb, links); in pvscsi_hcb_put()
383 pvscsi_get_max_targets(struct pvscsi_softc *sc) in pvscsi_get_max_targets() argument
387 pvscsi_write_cmd(sc, PVSCSI_CMD_GET_MAX_TARGETS, NULL, 0); in pvscsi_get_max_targets()
389 max_targets = pvscsi_reg_read(sc, PVSCSI_REG_OFFSET_COMMAND_STATUS); in pvscsi_get_max_targets()
398 static int pvscsi_setup_req_call(struct pvscsi_softc *sc, uint32_t enable) in pvscsi_setup_req_call() argument
403 if (!pvscsi_get_tunable(sc, "pvscsi_use_req_call_threshold", in pvscsi_setup_req_call()
408 pvscsi_reg_write(sc, PVSCSI_REG_OFFSET_COMMAND, in pvscsi_setup_req_call()
410 status = pvscsi_reg_read(sc, PVSCSI_REG_OFFSET_COMMAND_STATUS); in pvscsi_setup_req_call()
415 pvscsi_write_cmd(sc, PVSCSI_CMD_SETUP_REQCALLTHRESHOLD, in pvscsi_setup_req_call()
417 status = pvscsi_reg_read(sc, PVSCSI_REG_OFFSET_COMMAND_STATUS); in pvscsi_setup_req_call()
440 pvscsi_dma_free(struct pvscsi_softc *sc, struct pvscsi_dma *dma) in pvscsi_dma_free() argument
459 pvscsi_dma_alloc(struct pvscsi_softc *sc, struct pvscsi_dma *dma, in pvscsi_dma_alloc() argument
466 error = bus_dma_tag_create(sc->parent_dmat, alignment, 0, in pvscsi_dma_alloc()
470 device_printf(sc->dev, "error creating dma tag, error %d\n", in pvscsi_dma_alloc()
478 device_printf(sc->dev, "error allocating dma mem, error %d\n", in pvscsi_dma_alloc()
486 device_printf(sc->dev, "error mapping dma mam, error %d\n", in pvscsi_dma_alloc()
495 pvscsi_dma_free(sc, dma); in pvscsi_dma_alloc()
501 pvscsi_dma_alloc_ppns(struct pvscsi_softc *sc, struct pvscsi_dma *dma, in pvscsi_dma_alloc_ppns() argument
508 error = pvscsi_dma_alloc(sc, dma, num_pages * PAGE_SIZE, PAGE_SIZE); in pvscsi_dma_alloc_ppns()
510 device_printf(sc->dev, "Error allocating pages, error %d\n", in pvscsi_dma_alloc_ppns()
524 pvscsi_dma_free_per_hcb(struct pvscsi_softc *sc, uint32_t hcbs_allocated) in pvscsi_dma_free_per_hcb() argument
530 lock_owned = mtx_owned(&sc->lock); in pvscsi_dma_free_per_hcb()
533 mtx_unlock(&sc->lock); in pvscsi_dma_free_per_hcb()
536 hcb = sc->hcbs + i; in pvscsi_dma_free_per_hcb()
540 mtx_lock(&sc->lock); in pvscsi_dma_free_per_hcb()
544 hcb = sc->hcbs + i; in pvscsi_dma_free_per_hcb()
545 bus_dmamap_destroy(sc->buffer_dmat, hcb->dma_map); in pvscsi_dma_free_per_hcb()
548 pvscsi_dma_free(sc, &sc->sense_buffer_dma); in pvscsi_dma_free_per_hcb()
549 pvscsi_dma_free(sc, &sc->sg_list_dma); in pvscsi_dma_free_per_hcb()
553 pvscsi_dma_alloc_per_hcb(struct pvscsi_softc *sc) in pvscsi_dma_alloc_per_hcb() argument
561 error = pvscsi_dma_alloc(sc, &sc->sg_list_dma, in pvscsi_dma_alloc_per_hcb()
562 sizeof(struct pvscsi_sg_list) * sc->hcb_cnt, 1); in pvscsi_dma_alloc_per_hcb()
564 device_printf(sc->dev, in pvscsi_dma_alloc_per_hcb()
569 error = pvscsi_dma_alloc(sc, &sc->sense_buffer_dma, in pvscsi_dma_alloc_per_hcb()
570 PVSCSI_SENSE_LENGTH * sc->hcb_cnt, 1); in pvscsi_dma_alloc_per_hcb()
572 device_printf(sc->dev, in pvscsi_dma_alloc_per_hcb()
577 for (i = 0; i < sc->hcb_cnt; ++i) { in pvscsi_dma_alloc_per_hcb()
578 hcb = sc->hcbs + i; in pvscsi_dma_alloc_per_hcb()
580 error = bus_dmamap_create(sc->buffer_dmat, 0, &hcb->dma_map); in pvscsi_dma_alloc_per_hcb()
582 device_printf(sc->dev, in pvscsi_dma_alloc_per_hcb()
589 (void *)((caddr_t)sc->sense_buffer_dma.vaddr + in pvscsi_dma_alloc_per_hcb()
592 sc->sense_buffer_dma.paddr + PVSCSI_SENSE_LENGTH * i; in pvscsi_dma_alloc_per_hcb()
595 (struct pvscsi_sg_list *)((caddr_t)sc->sg_list_dma.vaddr + in pvscsi_dma_alloc_per_hcb()
598 sc->sg_list_dma.paddr + sizeof(struct pvscsi_sg_list) * i; in pvscsi_dma_alloc_per_hcb()
600 callout_init_mtx(&hcb->callout, &sc->lock, 0); in pvscsi_dma_alloc_per_hcb()
603 SLIST_INIT(&sc->free_list); in pvscsi_dma_alloc_per_hcb()
604 for (i = (sc->hcb_cnt - 1); i >= 0; --i) { in pvscsi_dma_alloc_per_hcb()
605 hcb = sc->hcbs + i; in pvscsi_dma_alloc_per_hcb()
606 SLIST_INSERT_HEAD(&sc->free_list, hcb, links); in pvscsi_dma_alloc_per_hcb()
611 pvscsi_dma_free_per_hcb(sc, i); in pvscsi_dma_alloc_per_hcb()
618 pvscsi_free_rings(struct pvscsi_softc *sc) in pvscsi_free_rings() argument
621 pvscsi_dma_free(sc, &sc->rings_state_dma); in pvscsi_free_rings()
622 pvscsi_dma_free(sc, &sc->req_ring_dma); in pvscsi_free_rings()
623 pvscsi_dma_free(sc, &sc->cmp_ring_dma); in pvscsi_free_rings()
624 if (sc->use_msg) { in pvscsi_free_rings()
625 pvscsi_dma_free(sc, &sc->msg_ring_dma); in pvscsi_free_rings()
630 pvscsi_allocate_rings(struct pvscsi_softc *sc) in pvscsi_allocate_rings() argument
634 error = pvscsi_dma_alloc_ppns(sc, &sc->rings_state_dma, in pvscsi_allocate_rings()
635 &sc->rings_state_ppn, 1); in pvscsi_allocate_rings()
637 device_printf(sc->dev, in pvscsi_allocate_rings()
641 sc->rings_state = sc->rings_state_dma.vaddr; in pvscsi_allocate_rings()
643 error = pvscsi_dma_alloc_ppns(sc, &sc->req_ring_dma, sc->req_ring_ppn, in pvscsi_allocate_rings()
644 sc->req_ring_num_pages); in pvscsi_allocate_rings()
646 device_printf(sc->dev, in pvscsi_allocate_rings()
650 sc->req_ring = sc->req_ring_dma.vaddr; in pvscsi_allocate_rings()
652 error = pvscsi_dma_alloc_ppns(sc, &sc->cmp_ring_dma, sc->cmp_ring_ppn, in pvscsi_allocate_rings()
653 sc->cmp_ring_num_pages); in pvscsi_allocate_rings()
655 device_printf(sc->dev, in pvscsi_allocate_rings()
659 sc->cmp_ring = sc->cmp_ring_dma.vaddr; in pvscsi_allocate_rings()
661 sc->msg_ring = NULL; in pvscsi_allocate_rings()
662 if (sc->use_msg) { in pvscsi_allocate_rings()
663 error = pvscsi_dma_alloc_ppns(sc, &sc->msg_ring_dma, in pvscsi_allocate_rings()
664 sc->msg_ring_ppn, sc->msg_ring_num_pages); in pvscsi_allocate_rings()
666 device_printf(sc->dev, in pvscsi_allocate_rings()
671 sc->msg_ring = sc->msg_ring_dma.vaddr; in pvscsi_allocate_rings()
674 DEBUG_PRINTF(1, sc->dev, "rings_state: %p\n", sc->rings_state); in pvscsi_allocate_rings()
675 DEBUG_PRINTF(1, sc->dev, "req_ring: %p - %u pages\n", sc->req_ring, in pvscsi_allocate_rings()
676 sc->req_ring_num_pages); in pvscsi_allocate_rings()
677 DEBUG_PRINTF(1, sc->dev, "cmp_ring: %p - %u pages\n", sc->cmp_ring, in pvscsi_allocate_rings()
678 sc->cmp_ring_num_pages); in pvscsi_allocate_rings()
679 DEBUG_PRINTF(1, sc->dev, "msg_ring: %p - %u pages\n", sc->msg_ring, in pvscsi_allocate_rings()
680 sc->msg_ring_num_pages); in pvscsi_allocate_rings()
684 pvscsi_free_rings(sc); in pvscsi_allocate_rings()
690 pvscsi_setup_rings(struct pvscsi_softc *sc) in pvscsi_setup_rings() argument
697 cmd.rings_state_ppn = sc->rings_state_ppn; in pvscsi_setup_rings()
699 cmd.req_ring_num_pages = sc->req_ring_num_pages; in pvscsi_setup_rings()
700 for (i = 0; i < sc->req_ring_num_pages; ++i) { in pvscsi_setup_rings()
701 cmd.req_ring_ppns[i] = sc->req_ring_ppn[i]; in pvscsi_setup_rings()
704 cmd.cmp_ring_num_pages = sc->cmp_ring_num_pages; in pvscsi_setup_rings()
705 for (i = 0; i < sc->cmp_ring_num_pages; ++i) { in pvscsi_setup_rings()
706 cmd.cmp_ring_ppns[i] = sc->cmp_ring_ppn[i]; in pvscsi_setup_rings()
709 pvscsi_write_cmd(sc, PVSCSI_CMD_SETUP_RINGS, &cmd, sizeof(cmd)); in pvscsi_setup_rings()
713 pvscsi_hw_supports_msg(struct pvscsi_softc *sc) in pvscsi_hw_supports_msg() argument
717 pvscsi_reg_write(sc, PVSCSI_REG_OFFSET_COMMAND, in pvscsi_hw_supports_msg()
719 status = pvscsi_reg_read(sc, PVSCSI_REG_OFFSET_COMMAND_STATUS); in pvscsi_hw_supports_msg()
725 pvscsi_setup_msg_ring(struct pvscsi_softc *sc) in pvscsi_setup_msg_ring() argument
730 KASSERT(sc->use_msg, ("msg is not being used")); in pvscsi_setup_msg_ring()
734 cmd.num_pages = sc->msg_ring_num_pages; in pvscsi_setup_msg_ring()
735 for (i = 0; i < sc->msg_ring_num_pages; ++i) { in pvscsi_setup_msg_ring()
736 cmd.ring_ppns[i] = sc->msg_ring_ppn[i]; in pvscsi_setup_msg_ring()
739 pvscsi_write_cmd(sc, PVSCSI_CMD_SETUP_MSG_RING, &cmd, sizeof(cmd)); in pvscsi_setup_msg_ring()
743 pvscsi_adapter_reset(struct pvscsi_softc *sc) in pvscsi_adapter_reset() argument
747 device_printf(sc->dev, "Adapter Reset\n"); in pvscsi_adapter_reset()
749 pvscsi_write_cmd(sc, PVSCSI_CMD_ADAPTER_RESET, NULL, 0); in pvscsi_adapter_reset()
750 val = pvscsi_read_intr_status(sc); in pvscsi_adapter_reset()
752 DEBUG_PRINTF(2, sc->dev, "adapter reset done: %u\n", val); in pvscsi_adapter_reset()
756 pvscsi_bus_reset(struct pvscsi_softc *sc) in pvscsi_bus_reset() argument
759 device_printf(sc->dev, "Bus Reset\n"); in pvscsi_bus_reset()
761 pvscsi_write_cmd(sc, PVSCSI_CMD_RESET_BUS, NULL, 0); in pvscsi_bus_reset()
762 pvscsi_process_cmp_ring(sc); in pvscsi_bus_reset()
764 DEBUG_PRINTF(2, sc->dev, "bus reset done\n"); in pvscsi_bus_reset()
768 pvscsi_device_reset(struct pvscsi_softc *sc, uint32_t target) in pvscsi_device_reset() argument
776 device_printf(sc->dev, "Device reset for target %u\n", target); in pvscsi_device_reset()
778 pvscsi_write_cmd(sc, PVSCSI_CMD_RESET_DEVICE, &cmd, sizeof cmd); in pvscsi_device_reset()
779 pvscsi_process_cmp_ring(sc); in pvscsi_device_reset()
781 DEBUG_PRINTF(2, sc->dev, "device reset done\n"); in pvscsi_device_reset()
785 pvscsi_abort(struct pvscsi_softc *sc, uint32_t target, union ccb *ccb) in pvscsi_abort() argument
791 pvscsi_process_cmp_ring(sc); in pvscsi_abort()
796 context = pvscsi_hcb_to_context(sc, hcb); in pvscsi_abort()
802 device_printf(sc->dev, "Abort for target %u context %llx\n", in pvscsi_abort()
805 pvscsi_write_cmd(sc, PVSCSI_CMD_ABORT_CMD, &cmd, sizeof(cmd)); in pvscsi_abort()
806 pvscsi_process_cmp_ring(sc); in pvscsi_abort()
808 DEBUG_PRINTF(2, sc->dev, "abort done\n"); in pvscsi_abort()
810 DEBUG_PRINTF(1, sc->dev, in pvscsi_abort()
838 struct pvscsi_softc *sc; in pvscsi_timeout() local
849 sc = ccb->ccb_h.ccb_pvscsi_sc; in pvscsi_timeout()
850 mtx_assert(&sc->lock, MA_OWNED); in pvscsi_timeout()
852 device_printf(sc->dev, "Command timed out hcb=%p ccb=%p.\n", hcb, ccb); in pvscsi_timeout()
857 pvscsi_abort(sc, ccb->ccb_h.target_id, ccb); in pvscsi_timeout()
863 pvscsi_freeze(sc); in pvscsi_timeout()
864 pvscsi_device_reset(sc, ccb->ccb_h.target_id); in pvscsi_timeout()
870 pvscsi_freeze(sc); in pvscsi_timeout()
871 pvscsi_bus_reset(sc); in pvscsi_timeout()
876 pvscsi_freeze(sc); in pvscsi_timeout()
877 pvscsi_adapter_reset(sc); in pvscsi_timeout()
883 pvscsi_process_completion(struct pvscsi_softc *sc, in pvscsi_process_completion() argument
893 hcb = pvscsi_context_to_hcb(sc, e->context); in pvscsi_process_completion()
911 bus_dmamap_sync(sc->buffer_dmat, hcb->dma_map, op); in pvscsi_process_completion()
912 bus_dmamap_unload(sc->buffer_dmat, hcb->dma_map); in pvscsi_process_completion()
916 DEBUG_PRINTF(3, sc->dev, in pvscsi_process_completion()
954 DEBUG_PRINTF(1, sc->dev, in pvscsi_process_completion()
1001 device_printf(sc->dev, "unknown hba status: 0x%x\n", in pvscsi_process_completion()
1007 DEBUG_PRINTF(3, sc->dev, in pvscsi_process_completion()
1014 pvscsi_hcb_put(sc, hcb); in pvscsi_process_completion()
1019 if (sc->frozen) { in pvscsi_process_completion()
1021 sc->frozen = 0; in pvscsi_process_completion()
1032 pvscsi_process_cmp_ring(struct pvscsi_softc *sc) in pvscsi_process_cmp_ring() argument
1039 mtx_assert(&sc->lock, MA_OWNED); in pvscsi_process_cmp_ring()
1041 s = sc->rings_state; in pvscsi_process_cmp_ring()
1042 ring = sc->cmp_ring; in pvscsi_process_cmp_ring()
1048 pvscsi_process_completion(sc, e); in pvscsi_process_cmp_ring()
1056 pvscsi_process_msg(struct pvscsi_softc *sc, struct pvscsi_ring_msg_desc *e) in pvscsi_process_msg() argument
1066 device_printf(sc->dev, "MSG: device %s at scsi%u:%u:%u\n", in pvscsi_process_msg()
1072 device_printf(sc->dev, in pvscsi_process_msg()
1078 cam_sim_path(sc->sim), desc->target, desc->lun[1]) in pvscsi_process_msg()
1080 device_printf(sc->dev, in pvscsi_process_msg()
1089 device_printf(sc->dev, "Unknown msg type 0x%x\n", e->type); in pvscsi_process_msg()
1094 pvscsi_process_msg_ring(struct pvscsi_softc *sc) in pvscsi_process_msg_ring() argument
1101 mtx_assert(&sc->lock, MA_OWNED); in pvscsi_process_msg_ring()
1103 s = sc->rings_state; in pvscsi_process_msg_ring()
1104 ring = sc->msg_ring; in pvscsi_process_msg_ring()
1110 pvscsi_process_msg(sc, e); in pvscsi_process_msg_ring()
1118 pvscsi_intr_locked(struct pvscsi_softc *sc) in pvscsi_intr_locked() argument
1122 mtx_assert(&sc->lock, MA_OWNED); in pvscsi_intr_locked()
1124 val = pvscsi_read_intr_status(sc); in pvscsi_intr_locked()
1127 pvscsi_write_intr_status(sc, val & PVSCSI_INTR_ALL_SUPPORTED); in pvscsi_intr_locked()
1128 pvscsi_process_cmp_ring(sc); in pvscsi_intr_locked()
1129 if (sc->use_msg) { in pvscsi_intr_locked()
1130 pvscsi_process_msg_ring(sc); in pvscsi_intr_locked()
1138 struct pvscsi_softc *sc; in pvscsi_intr() local
1140 sc = xsc; in pvscsi_intr()
1142 mtx_assert(&sc->lock, MA_NOTOWNED); in pvscsi_intr()
1144 mtx_lock(&sc->lock); in pvscsi_intr()
1146 mtx_unlock(&sc->lock); in pvscsi_intr()
1152 struct pvscsi_softc *sc; in pvscsi_poll() local
1154 sc = cam_sim_softc(sim); in pvscsi_poll()
1156 mtx_assert(&sc->lock, MA_OWNED); in pvscsi_poll()
1157 pvscsi_intr_locked(sc); in pvscsi_poll()
1166 struct pvscsi_softc *sc; in pvscsi_execute_ccb() local
1174 sc = ccb->ccb_h.ccb_pvscsi_sc; in pvscsi_execute_ccb()
1175 s = sc->rings_state; in pvscsi_execute_ccb()
1177 mtx_assert(&sc->lock, MA_OWNED); in pvscsi_execute_ccb()
1180 device_printf(sc->dev, "pvscsi_execute_ccb error %d\n", error); in pvscsi_execute_ccb()
1188 pvscsi_hcb_put(sc, hcb); in pvscsi_execute_ccb()
1234 bus_dmamap_sync(sc->buffer_dmat, hcb->dma_map, op); in pvscsi_execute_ccb()
1249 pvscsi_kick_io(sc, cdb0); in pvscsi_execute_ccb()
1255 struct pvscsi_softc *sc; in pvscsi_action() local
1258 sc = cam_sim_softc(sim); in pvscsi_action()
1261 mtx_assert(&sc->lock, MA_OWNED); in pvscsi_action()
1274 ring = sc->req_ring; in pvscsi_action()
1275 s = sc->rings_state; in pvscsi_action()
1292 device_printf(sc->dev, in pvscsi_action()
1294 pvscsi_freeze(sc); in pvscsi_action()
1299 hcb = pvscsi_hcb_get(sc); in pvscsi_action()
1301 device_printf(sc->dev, "No free hcbs.\n"); in pvscsi_action()
1302 pvscsi_freeze(sc); in pvscsi_action()
1309 ccb_h->ccb_pvscsi_sc = sc; in pvscsi_action()
1312 DEBUG_PRINTF(2, sc->dev, "cdb length %u too large\n", in pvscsi_action()
1319 DEBUG_PRINTF(2, sc->dev, in pvscsi_action()
1349 e->context = pvscsi_hcb_to_context(sc, hcb); in pvscsi_action()
1352 DEBUG_PRINTF(3, sc->dev, in pvscsi_action()
1355 bus_dmamap_load_ccb(sc->buffer_dmat, hcb->dma_map, ccb, in pvscsi_action()
1361 pvscsi_hcb_put(sc, hcb); in pvscsi_action()
1375 pvscsi_abort(sc, ccb_h->target_id, abort_ccb); in pvscsi_action()
1381 device_printf(sc->dev, in pvscsi_action()
1390 pvscsi_device_reset(sc, ccb_h->target_id); in pvscsi_action()
1396 pvscsi_bus_reset(sc); in pvscsi_action()
1412 cpi->max_target = sc->max_targets - 1; in pvscsi_action()
1467 pvscsi_free_interrupts(struct pvscsi_softc *sc) in pvscsi_free_interrupts() argument
1470 if (sc->irq_handler != NULL) { in pvscsi_free_interrupts()
1471 bus_teardown_intr(sc->dev, sc->irq_res, sc->irq_handler); in pvscsi_free_interrupts()
1473 if (sc->irq_res != NULL) { in pvscsi_free_interrupts()
1474 bus_release_resource(sc->dev, SYS_RES_IRQ, sc->irq_id, in pvscsi_free_interrupts()
1475 sc->irq_res); in pvscsi_free_interrupts()
1477 if (sc->use_msi_or_msix) { in pvscsi_free_interrupts()
1478 pci_release_msi(sc->dev); in pvscsi_free_interrupts()
1483 pvscsi_setup_interrupts(struct pvscsi_softc *sc) in pvscsi_setup_interrupts() argument
1491 sc->use_msi_or_msix = 0; in pvscsi_setup_interrupts()
1493 use_msix = pvscsi_get_tunable(sc, "use_msix", pvscsi_use_msix); in pvscsi_setup_interrupts()
1494 use_msi = pvscsi_get_tunable(sc, "use_msi", pvscsi_use_msi); in pvscsi_setup_interrupts()
1496 if (use_msix && pci_msix_count(sc->dev) > 0) { in pvscsi_setup_interrupts()
1498 if (pci_alloc_msix(sc->dev, &count) == 0 && count == 1) { in pvscsi_setup_interrupts()
1499 sc->use_msi_or_msix = 1; in pvscsi_setup_interrupts()
1500 device_printf(sc->dev, "Interrupt: MSI-X\n"); in pvscsi_setup_interrupts()
1502 pci_release_msi(sc->dev); in pvscsi_setup_interrupts()
1506 if (sc->use_msi_or_msix == 0 && use_msi && pci_msi_count(sc->dev) > 0) { in pvscsi_setup_interrupts()
1508 if (pci_alloc_msi(sc->dev, &count) == 0 && count == 1) { in pvscsi_setup_interrupts()
1509 sc->use_msi_or_msix = 1; in pvscsi_setup_interrupts()
1510 device_printf(sc->dev, "Interrupt: MSI\n"); in pvscsi_setup_interrupts()
1512 pci_release_msi(sc->dev); in pvscsi_setup_interrupts()
1517 if (sc->use_msi_or_msix) { in pvscsi_setup_interrupts()
1518 sc->irq_id = 1; in pvscsi_setup_interrupts()
1520 device_printf(sc->dev, "Interrupt: INT\n"); in pvscsi_setup_interrupts()
1521 sc->irq_id = 0; in pvscsi_setup_interrupts()
1525 sc->irq_res = bus_alloc_resource_any(sc->dev, SYS_RES_IRQ, &sc->irq_id, in pvscsi_setup_interrupts()
1527 if (sc->irq_res == NULL) { in pvscsi_setup_interrupts()
1528 device_printf(sc->dev, "IRQ allocation failed\n"); in pvscsi_setup_interrupts()
1529 if (sc->use_msi_or_msix) { in pvscsi_setup_interrupts()
1530 pci_release_msi(sc->dev); in pvscsi_setup_interrupts()
1535 error = bus_setup_intr(sc->dev, sc->irq_res, in pvscsi_setup_interrupts()
1536 INTR_TYPE_CAM | INTR_MPSAFE, NULL, pvscsi_intr, sc, in pvscsi_setup_interrupts()
1537 &sc->irq_handler); in pvscsi_setup_interrupts()
1539 device_printf(sc->dev, "IRQ handler setup failed\n"); in pvscsi_setup_interrupts()
1540 pvscsi_free_interrupts(sc); in pvscsi_setup_interrupts()
1548 pvscsi_free_all(struct pvscsi_softc *sc) in pvscsi_free_all() argument
1551 if (sc->sim) { in pvscsi_free_all()
1554 if (sc->bus_path) { in pvscsi_free_all()
1555 xpt_free_path(sc->bus_path); in pvscsi_free_all()
1558 error = xpt_bus_deregister(cam_sim_path(sc->sim)); in pvscsi_free_all()
1560 device_printf(sc->dev, in pvscsi_free_all()
1564 cam_sim_free(sc->sim, TRUE); in pvscsi_free_all()
1567 pvscsi_dma_free_per_hcb(sc, sc->hcb_cnt); in pvscsi_free_all()
1569 if (sc->hcbs) { in pvscsi_free_all()
1570 free(sc->hcbs, M_PVSCSI); in pvscsi_free_all()
1573 pvscsi_free_rings(sc); in pvscsi_free_all()
1575 pvscsi_free_interrupts(sc); in pvscsi_free_all()
1577 if (sc->buffer_dmat != NULL) { in pvscsi_free_all()
1578 bus_dma_tag_destroy(sc->buffer_dmat); in pvscsi_free_all()
1581 if (sc->parent_dmat != NULL) { in pvscsi_free_all()
1582 bus_dma_tag_destroy(sc->parent_dmat); in pvscsi_free_all()
1585 if (sc->mm_res != NULL) { in pvscsi_free_all()
1586 bus_release_resource(sc->dev, SYS_RES_MEMORY, sc->mm_rid, in pvscsi_free_all()
1587 sc->mm_res); in pvscsi_free_all()
1594 struct pvscsi_softc *sc; in pvscsi_attach() local
1602 sc = device_get_softc(dev); in pvscsi_attach()
1603 sc->dev = dev; in pvscsi_attach()
1605 mtx_init(&sc->lock, "pvscsi", NULL, MTX_DEF); in pvscsi_attach()
1609 sc->mm_rid = -1; in pvscsi_attach()
1613 sc->mm_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, in pvscsi_attach()
1615 if (sc->mm_res != NULL) { in pvscsi_attach()
1616 sc->mm_rid = rid; in pvscsi_attach()
1621 if (sc->mm_res == NULL) { in pvscsi_attach()
1629 &sc->parent_dmat); in pvscsi_attach()
1633 pvscsi_free_all(sc); in pvscsi_attach()
1637 error = bus_dma_tag_create(sc->parent_dmat, 1, 0, in pvscsi_attach()
1641 NULL, NULL, &sc->buffer_dmat); in pvscsi_attach()
1645 pvscsi_free_all(sc); in pvscsi_attach()
1649 error = pvscsi_setup_interrupts(sc); in pvscsi_attach()
1652 pvscsi_free_all(sc); in pvscsi_attach()
1656 sc->max_targets = pvscsi_get_max_targets(sc); in pvscsi_attach()
1658 sc->use_msg = pvscsi_get_tunable(sc, "use_msg", pvscsi_use_msg) && in pvscsi_attach()
1659 pvscsi_hw_supports_msg(sc); in pvscsi_attach()
1660 sc->msg_ring_num_pages = sc->use_msg ? 1 : 0; in pvscsi_attach()
1662 sc->req_ring_num_pages = pvscsi_get_tunable(sc, "request_ring_pages", in pvscsi_attach()
1664 if (sc->req_ring_num_pages <= 0) { in pvscsi_attach()
1665 if (sc->max_targets <= 16) { in pvscsi_attach()
1666 sc->req_ring_num_pages = in pvscsi_attach()
1669 sc->req_ring_num_pages = PVSCSI_MAX_NUM_PAGES_REQ_RING; in pvscsi_attach()
1671 } else if (sc->req_ring_num_pages > PVSCSI_MAX_NUM_PAGES_REQ_RING) { in pvscsi_attach()
1672 sc->req_ring_num_pages = PVSCSI_MAX_NUM_PAGES_REQ_RING; in pvscsi_attach()
1674 sc->cmp_ring_num_pages = sc->req_ring_num_pages; in pvscsi_attach()
1676 max_queue_depth = pvscsi_get_tunable(sc, "max_queue_depth", in pvscsi_attach()
1679 adapter_queue_size = (sc->req_ring_num_pages * PAGE_SIZE) / in pvscsi_attach()
1687 device_printf(sc->dev, "Use Msg: %d\n", sc->use_msg); in pvscsi_attach()
1688 device_printf(sc->dev, "Max targets: %d\n", sc->max_targets); in pvscsi_attach()
1689 device_printf(sc->dev, "REQ num pages: %d\n", sc->req_ring_num_pages); in pvscsi_attach()
1690 device_printf(sc->dev, "CMP num pages: %d\n", sc->cmp_ring_num_pages); in pvscsi_attach()
1691 device_printf(sc->dev, "MSG num pages: %d\n", sc->msg_ring_num_pages); in pvscsi_attach()
1692 device_printf(sc->dev, "Queue size: %d\n", adapter_queue_size); in pvscsi_attach()
1694 if (pvscsi_allocate_rings(sc)) { in pvscsi_attach()
1696 pvscsi_free_all(sc); in pvscsi_attach()
1700 sc->hcb_cnt = adapter_queue_size; in pvscsi_attach()
1701 sc->hcbs = malloc(sc->hcb_cnt * sizeof(*sc->hcbs), M_PVSCSI, in pvscsi_attach()
1703 if (sc->hcbs == NULL) { in pvscsi_attach()
1705 pvscsi_free_all(sc); in pvscsi_attach()
1709 if (pvscsi_dma_alloc_per_hcb(sc)) { in pvscsi_attach()
1711 pvscsi_free_all(sc); in pvscsi_attach()
1715 pvscsi_adapter_reset(sc); in pvscsi_attach()
1720 pvscsi_free_all(sc); in pvscsi_attach()
1724 sc->sim = cam_sim_alloc(pvscsi_action, pvscsi_poll, "pvscsi", sc, in pvscsi_attach()
1725 device_get_unit(dev), &sc->lock, 1, adapter_queue_size, devq); in pvscsi_attach()
1726 if (sc->sim == NULL) { in pvscsi_attach()
1729 pvscsi_free_all(sc); in pvscsi_attach()
1733 mtx_lock(&sc->lock); in pvscsi_attach()
1735 if (xpt_bus_register(sc->sim, dev, 0) != CAM_SUCCESS) { in pvscsi_attach()
1737 pvscsi_free_all(sc); in pvscsi_attach()
1738 mtx_unlock(&sc->lock); in pvscsi_attach()
1742 if (xpt_create_path(&sc->bus_path, NULL, cam_sim_path(sc->sim), in pvscsi_attach()
1745 pvscsi_free_all(sc); in pvscsi_attach()
1746 mtx_unlock(&sc->lock); in pvscsi_attach()
1750 pvscsi_setup_rings(sc); in pvscsi_attach()
1751 if (sc->use_msg) { in pvscsi_attach()
1752 pvscsi_setup_msg_ring(sc); in pvscsi_attach()
1755 sc->use_req_call_threshold = pvscsi_setup_req_call(sc, 1); in pvscsi_attach()
1757 pvscsi_intr_enable(sc); in pvscsi_attach()
1759 mtx_unlock(&sc->lock); in pvscsi_attach()
1767 struct pvscsi_softc *sc; in pvscsi_detach() local
1769 sc = device_get_softc(dev); in pvscsi_detach()
1771 pvscsi_intr_disable(sc); in pvscsi_detach()
1772 pvscsi_adapter_reset(sc); in pvscsi_detach()
1774 if (sc->irq_handler != NULL) { in pvscsi_detach()
1775 bus_teardown_intr(dev, sc->irq_res, sc->irq_handler); in pvscsi_detach()
1778 mtx_lock(&sc->lock); in pvscsi_detach()
1779 pvscsi_free_all(sc); in pvscsi_detach()
1780 mtx_unlock(&sc->lock); in pvscsi_detach()
1782 mtx_destroy(&sc->lock); in pvscsi_detach()