Lines Matching refs:sc
163 static int vioblk_get_id(struct vioblk_softc *sc);
261 vioblk_rw(struct vioblk_softc *sc, bd_xfer_t *xfer, int type, in vioblk_rw() argument
272 if ((xfer->x_blkno + xfer->x_nblks) > sc->sc_nblks) { in vioblk_rw()
273 sc->ks_data->sts_rw_badoffset.value.ui64++; in vioblk_rw()
278 ve_hdr = vq_alloc_entry(sc->sc_vq); in vioblk_rw()
280 sc->ks_data->sts_rw_outofmemory.value.ui64++; in vioblk_rw()
285 req = &sc->sc_reqs[ve_hdr->qe_index]; in vioblk_rw()
310 if (sc->sc_stats.rw_cookiesmax < total_cookies) in vioblk_rw()
311 sc->sc_stats.rw_cookiesmax = total_cookies; in vioblk_rw()
323 vioblk_rw_poll(struct vioblk_softc *sc, bd_xfer_t *xfer, in vioblk_rw_poll() argument
335 while (vq_num_used(sc->sc_vq)) { in vioblk_rw_poll()
337 ret = vioblk_int_handler((caddr_t)&sc->sc_virtio, NULL); in vioblk_rw_poll()
345 ret = vioblk_rw(sc, xfer, type, len); in vioblk_rw_poll()
351 while (vq_num_used(sc->sc_vq)) { in vioblk_rw_poll()
353 ret = vioblk_int_handler((caddr_t)&sc->sc_virtio, NULL); in vioblk_rw_poll()
368 struct vioblk_softc *sc = (void *)arg; in vioblk_read() local
371 if (!sc->sc_in_poll_mode) { in vioblk_read()
372 virtio_stop_vq_intr(sc->sc_vq); in vioblk_read()
373 sc->sc_in_poll_mode = 1; in vioblk_read()
376 ret = vioblk_rw_poll(sc, xfer, VIRTIO_BLK_T_IN, in vioblk_read()
379 if (sc->sc_in_poll_mode) { in vioblk_read()
380 virtio_start_vq_intr(sc->sc_vq); in vioblk_read()
381 sc->sc_in_poll_mode = 0; in vioblk_read()
384 ret = vioblk_rw(sc, xfer, VIRTIO_BLK_T_IN, in vioblk_read()
395 struct vioblk_softc *sc = (void *)arg; in vioblk_write() local
398 if (!sc->sc_in_poll_mode) { in vioblk_write()
399 virtio_stop_vq_intr(sc->sc_vq); in vioblk_write()
400 sc->sc_in_poll_mode = 1; in vioblk_write()
403 ret = vioblk_rw_poll(sc, xfer, VIRTIO_BLK_T_OUT, in vioblk_write()
406 if (sc->sc_in_poll_mode) { in vioblk_write()
407 virtio_start_vq_intr(sc->sc_vq); in vioblk_write()
408 sc->sc_in_poll_mode = 0; in vioblk_write()
411 ret = vioblk_rw(sc, xfer, VIRTIO_BLK_T_OUT, in vioblk_write()
421 struct vioblk_softc *sc = (void *)arg; in vioblk_flush() local
425 ret = vioblk_rw(sc, xfer, VIRTIO_BLK_T_FLUSH_OUT, in vioblk_flush()
429 sc->sc_stats.rw_cacheflush++; in vioblk_flush()
438 struct vioblk_softc *sc = (void *)arg; in vioblk_driveinfo() local
440 drive->d_qsize = sc->sc_vq->vq_num; in vioblk_driveinfo()
452 (void) vioblk_get_id(sc); in vioblk_driveinfo()
453 drive->d_serial = sc->devid; in vioblk_driveinfo()
463 struct vioblk_softc *sc = (void *)arg; in vioblk_mediainfo() local
465 media->m_nblks = sc->sc_nblks; in vioblk_mediainfo()
466 media->m_blksize = sc->sc_blk_size; in vioblk_mediainfo()
467 media->m_readonly = sc->sc_readonly; in vioblk_mediainfo()
468 media->m_pblksize = sc->sc_pblk_size; in vioblk_mediainfo()
473 vioblk_get_id(struct vioblk_softc *sc) in vioblk_get_id() argument
483 ret = ddi_dma_alloc_handle(sc->sc_dev, &vioblk_bd_dma_attr, in vioblk_get_id()
488 ret = ddi_dma_addr_bind_handle(xfer.x_dmah, NULL, (caddr_t)&sc->devid, in vioblk_get_id()
496 mutex_enter(&sc->lock_devid); in vioblk_get_id()
498 ret = vioblk_rw(sc, &xfer, VIRTIO_BLK_T_GET_ID, in vioblk_get_id()
501 mutex_exit(&sc->lock_devid); in vioblk_get_id()
506 ret = cv_timedwait(&sc->cv_devid, &sc->lock_devid, deadline); in vioblk_get_id()
507 mutex_exit(&sc->lock_devid); in vioblk_get_id()
514 dev_err(sc->sc_dev, CE_WARN, in vioblk_get_id()
532 struct vioblk_softc *sc = (void *)arg; in vioblk_devid_init() local
535 ret = vioblk_get_id(sc); in vioblk_devid_init()
540 VIRTIO_BLK_ID_BYTES, sc->devid, devid); in vioblk_devid_init()
546 dev_debug(sc->sc_dev, CE_NOTE, in vioblk_devid_init()
548 sc->devid[0], sc->devid[1], sc->devid[2], sc->devid[3], in vioblk_devid_init()
549 sc->devid[4], sc->devid[5], sc->devid[6], sc->devid[7], in vioblk_devid_init()
550 sc->devid[8], sc->devid[9], sc->devid[10], sc->devid[11], in vioblk_devid_init()
551 sc->devid[12], sc->devid[13], sc->devid[14], sc->devid[15], in vioblk_devid_init()
552 sc->devid[16], sc->devid[17], sc->devid[18], sc->devid[19]); in vioblk_devid_init()
558 vioblk_show_features(struct vioblk_softc *sc, const char *prefix, in vioblk_show_features() argument
607 dev_debug(sc->sc_dev, CE_NOTE, "%s", buf); in vioblk_show_features()
611 vioblk_dev_features(struct vioblk_softc *sc) in vioblk_dev_features() argument
615 host_features = virtio_negotiate_features(&sc->sc_virtio, in vioblk_dev_features()
625 vioblk_show_features(sc, "Host features: ", host_features); in vioblk_dev_features()
626 vioblk_show_features(sc, "Negotiated features: ", in vioblk_dev_features()
627 sc->sc_virtio.sc_features); in vioblk_dev_features()
629 if (!(sc->sc_virtio.sc_features & VIRTIO_F_RING_INDIRECT_DESC)) { in vioblk_dev_features()
630 dev_err(sc->sc_dev, CE_NOTE, in vioblk_dev_features()
643 struct vioblk_softc *sc = container_of(vsc, in vioblk_int_handler() local
649 while ((ve = virtio_pull_chain(sc->sc_vq, &len))) { in vioblk_int_handler()
650 struct vioblk_req *req = &sc->sc_reqs[ve->qe_index]; in vioblk_int_handler()
656 dev_err(sc->sc_dev, CE_WARN, "Poisoned descriptor!"); in vioblk_int_handler()
673 sc->sc_stats.io_errors++; in vioblk_int_handler()
676 sc->sc_stats.unsupp_errors++; in vioblk_int_handler()
680 sc->sc_stats.nxio_errors++; in vioblk_int_handler()
687 mutex_enter(&sc->lock_devid); in vioblk_int_handler()
688 cv_broadcast(&sc->cv_devid); in vioblk_int_handler()
689 mutex_exit(&sc->lock_devid); in vioblk_int_handler()
697 if (sc->sc_stats.intr_queuemax < i) in vioblk_int_handler()
698 sc->sc_stats.intr_queuemax = i; in vioblk_int_handler()
699 sc->sc_stats.intr_total++; in vioblk_int_handler()
712 vioblk_register_ints(struct vioblk_softc *sc) in vioblk_register_ints() argument
725 ret = virtio_register_ints(&sc->sc_virtio, in vioblk_register_ints()
732 vioblk_free_reqs(struct vioblk_softc *sc) in vioblk_free_reqs() argument
736 qsize = sc->sc_vq->vq_num; in vioblk_free_reqs()
739 struct vioblk_req *req = &sc->sc_reqs[i]; in vioblk_free_reqs()
748 kmem_free(sc->sc_reqs, sizeof (struct vioblk_req) * qsize); in vioblk_free_reqs()
752 vioblk_alloc_reqs(struct vioblk_softc *sc) in vioblk_alloc_reqs() argument
757 qsize = sc->sc_vq->vq_num; in vioblk_alloc_reqs()
759 sc->sc_reqs = kmem_zalloc(sizeof (struct vioblk_req) * qsize, KM_SLEEP); in vioblk_alloc_reqs()
762 struct vioblk_req *req = &sc->sc_reqs[i]; in vioblk_alloc_reqs()
764 ret = ddi_dma_alloc_handle(sc->sc_dev, &vioblk_req_dma_attr, in vioblk_alloc_reqs()
768 dev_err(sc->sc_dev, CE_WARN, in vioblk_alloc_reqs()
780 dev_err(sc->sc_dev, CE_WARN, in vioblk_alloc_reqs()
789 vioblk_free_reqs(sc); in vioblk_alloc_reqs()
797 struct vioblk_softc *sc = ksp->ks_private; in vioblk_ksupdate() local
802 sc->ks_data->sts_rw_cookiesmax.value.ui32 = sc->sc_stats.rw_cookiesmax; in vioblk_ksupdate()
803 sc->ks_data->sts_intr_queuemax.value.ui32 = sc->sc_stats.intr_queuemax; in vioblk_ksupdate()
804 sc->ks_data->sts_unsupp_errors.value.ui32 = sc->sc_stats.unsupp_errors; in vioblk_ksupdate()
805 sc->ks_data->sts_nxio_errors.value.ui32 = sc->sc_stats.nxio_errors; in vioblk_ksupdate()
806 sc->ks_data->sts_io_errors.value.ui32 = sc->sc_stats.io_errors; in vioblk_ksupdate()
807 sc->ks_data->sts_rw_cacheflush.value.ui64 = sc->sc_stats.rw_cacheflush; in vioblk_ksupdate()
808 sc->ks_data->sts_intr_total.value.ui64 = sc->sc_stats.intr_total; in vioblk_ksupdate()
819 struct vioblk_softc *sc; in vioblk_attach() local
841 sc = kmem_zalloc(sizeof (struct vioblk_softc), KM_SLEEP); in vioblk_attach()
842 ddi_set_driver_private(devinfo, sc); in vioblk_attach()
844 vsc = &sc->sc_virtio; in vioblk_attach()
847 sc->sc_dev = devinfo; in vioblk_attach()
850 cv_init(&sc->cv_devid, NULL, CV_DRIVER, NULL); in vioblk_attach()
851 mutex_init(&sc->lock_devid, NULL, MUTEX_DRIVER, NULL); in vioblk_attach()
858 sc->sc_intrstat = kstat_create("vioblk", instance, in vioblk_attach()
862 if (sc->sc_intrstat == NULL) { in vioblk_attach()
866 ks_data = (struct vioblk_stats *)sc->sc_intrstat->ks_data; in vioblk_attach()
885 sc->ks_data = ks_data; in vioblk_attach()
886 sc->sc_intrstat->ks_private = sc; in vioblk_attach()
887 sc->sc_intrstat->ks_update = vioblk_ksupdate; in vioblk_attach()
888 kstat_install(sc->sc_intrstat); in vioblk_attach()
892 (caddr_t *)&sc->sc_virtio.sc_io_addr, in vioblk_attach()
893 0, 0, &vioblk_attr, &sc->sc_virtio.sc_ioh); in vioblk_attach()
899 virtio_device_reset(&sc->sc_virtio); in vioblk_attach()
900 virtio_set_status(&sc->sc_virtio, VIRTIO_CONFIG_DEVICE_STATUS_ACK); in vioblk_attach()
901 virtio_set_status(&sc->sc_virtio, VIRTIO_CONFIG_DEVICE_STATUS_DRIVER); in vioblk_attach()
903 if (vioblk_register_ints(sc)) { in vioblk_attach()
908 ret = vioblk_dev_features(sc); in vioblk_attach()
912 if (sc->sc_virtio.sc_features & VIRTIO_BLK_F_RO) in vioblk_attach()
913 sc->sc_readonly = B_TRUE; in vioblk_attach()
915 sc->sc_readonly = B_FALSE; in vioblk_attach()
917 sc->sc_capacity = virtio_read_device_config_8(&sc->sc_virtio, in vioblk_attach()
919 sc->sc_nblks = sc->sc_capacity; in vioblk_attach()
921 sc->sc_blk_size = DEV_BSIZE; in vioblk_attach()
922 if (sc->sc_virtio.sc_features & VIRTIO_BLK_F_BLK_SIZE) { in vioblk_attach()
923 sc->sc_blk_size = virtio_read_device_config_4(&sc->sc_virtio, in vioblk_attach()
927 sc->sc_pblk_size = sc->sc_blk_size; in vioblk_attach()
928 if (sc->sc_virtio.sc_features & VIRTIO_BLK_F_TOPOLOGY) { in vioblk_attach()
929 sc->sc_pblk_size <<= virtio_read_device_config_1(&sc->sc_virtio, in vioblk_attach()
934 if (!(sc->sc_virtio.sc_features & VIRTIO_BLK_F_FLUSH)) { in vioblk_attach()
938 sc->sc_seg_max = DEF_MAXINDIRECT; in vioblk_attach()
940 if (sc->sc_virtio.sc_features & VIRTIO_BLK_F_SEG_MAX) { in vioblk_attach()
941 sc->sc_seg_max = virtio_read_device_config_4(&sc->sc_virtio, in vioblk_attach()
945 if (!sc->sc_seg_max) in vioblk_attach()
946 sc->sc_seg_max = 1; in vioblk_attach()
952 sc->sc_seg_max += 2; in vioblk_attach()
955 vioblk_bd_dma_attr.dma_attr_sgllen = sc->sc_seg_max - 2; in vioblk_attach()
959 sc->sc_seg_size_max = DEF_MAXSECTOR; in vioblk_attach()
960 if (sc->sc_virtio.sc_features & VIRTIO_BLK_F_SIZE_MAX) { in vioblk_attach()
961 sc->sc_seg_size_max = virtio_read_device_config_4( in vioblk_attach()
962 &sc->sc_virtio, VIRTIO_BLK_CONFIG_SIZE_MAX); in vioblk_attach()
967 vioblk_bd_dma_attr.dma_attr_sgllen * sc->sc_seg_size_max; in vioblk_attach()
972 sc->sc_nblks, sc->sc_blk_size, sc->sc_pblk_size, in vioblk_attach()
974 sc->sc_seg_size_max, in vioblk_attach()
978 sc->sc_vq = virtio_alloc_vq(&sc->sc_virtio, 0, 0, in vioblk_attach()
979 sc->sc_seg_max, "I/O request"); in vioblk_attach()
980 if (sc->sc_vq == NULL) { in vioblk_attach()
984 ret = vioblk_alloc_reqs(sc); in vioblk_attach()
989 sc->bd_h = bd_alloc_handle(sc, &vioblk_ops, &vioblk_bd_dma_attr, in vioblk_attach()
993 virtio_set_status(&sc->sc_virtio, in vioblk_attach()
995 virtio_start_vq_intr(sc->sc_vq); in vioblk_attach()
997 ret = virtio_enable_ints(&sc->sc_virtio); in vioblk_attach()
1001 ret = bd_attach_handle(devinfo, sc->bd_h); in vioblk_attach()
1015 virtio_stop_vq_intr(sc->sc_vq); in vioblk_attach()
1016 bd_free_handle(sc->bd_h); in vioblk_attach()
1017 vioblk_free_reqs(sc); in vioblk_attach()
1019 virtio_free_vq(sc->sc_vq); in vioblk_attach()
1022 virtio_release_ints(&sc->sc_virtio); in vioblk_attach()
1024 virtio_set_status(&sc->sc_virtio, VIRTIO_CONFIG_DEVICE_STATUS_FAILED); in vioblk_attach()
1025 ddi_regs_map_free(&sc->sc_virtio.sc_ioh); in vioblk_attach()
1027 kstat_delete(sc->sc_intrstat); in vioblk_attach()
1029 mutex_destroy(&sc->lock_devid); in vioblk_attach()
1030 cv_destroy(&sc->cv_devid); in vioblk_attach()
1031 kmem_free(sc, sizeof (struct vioblk_softc)); in vioblk_attach()
1039 struct vioblk_softc *sc = ddi_get_driver_private(devinfo); in vioblk_detach() local
1054 (void) bd_detach_handle(sc->bd_h); in vioblk_detach()
1055 virtio_stop_vq_intr(sc->sc_vq); in vioblk_detach()
1056 virtio_release_ints(&sc->sc_virtio); in vioblk_detach()
1057 vioblk_free_reqs(sc); in vioblk_detach()
1058 virtio_free_vq(sc->sc_vq); in vioblk_detach()
1059 virtio_device_reset(&sc->sc_virtio); in vioblk_detach()
1060 ddi_regs_map_free(&sc->sc_virtio.sc_ioh); in vioblk_detach()
1061 kstat_delete(sc->sc_intrstat); in vioblk_detach()
1062 kmem_free(sc, sizeof (struct vioblk_softc)); in vioblk_detach()
1070 struct vioblk_softc *sc = ddi_get_driver_private(devinfo); in vioblk_quiesce() local
1072 virtio_stop_vq_intr(sc->sc_vq); in vioblk_quiesce()
1073 virtio_device_reset(&sc->sc_virtio); in vioblk_quiesce()