750
751 FCSM_DEBUG(SMDL_TRACE, (CE_CONT, SM_LOG, NULL, NULL,
752 "detach: start. cmd <DETACH>", cmd));
753
754 mutex_enter(&fcsm_global_mutex);
755
756 /*
757 * If port attach/detach in progress, then wait for 5 seconds
758 * for them to complete.
759 */
760 if (fcsm_num_attaching || fcsm_num_detaching) {
761 int count;
762
763 FCSM_DEBUG(SMDL_TRACE, (CE_WARN, SM_LOG, NULL, NULL,
764 "detach: wait for port attach/detach to complete"));
765
766 count = 0;
767 while ((count++ <= 30) &&
768 (fcsm_num_attaching || fcsm_num_detaching)) {
769 mutex_exit(&fcsm_global_mutex);
770 delay(drv_usectohz(1000000));
771 mutex_enter(&fcsm_global_mutex);
772 }
773
774 /* Port attach/detach still in prog, so fail detach */
775 if (fcsm_num_attaching || fcsm_num_detaching) {
776 mutex_exit(&fcsm_global_mutex);
777 FCSM_DEBUG(SMDL_ERR, (CE_WARN, SM_LOG, NULL,
778 NULL, "detach: Failing detach. port "
779 "attach/detach in progress"));
780 rval = DDI_FAILURE;
781 break;
782 }
783 }
784
785 if (fcsm_port_head == NULL) {
786 /* Not much do, Succeed to detach. */
787 ddi_remove_minor_node(fcsm_dip, NULL);
788 fcsm_dip = NULL;
789 fcsm_detached = 0;
790 mutex_exit(&fcsm_global_mutex);
1038 return (DDI_SUCCESS);
1039 }
1040 break;
1041
1042 default:
1043 mutex_exit(&fcsm->sm_mutex);
1044 return (DDI_FAILURE);
1045 };
1046
1047 fcsm->sm_flags |= flag;
1048
1049 /*
1050 * If some commands are pending OR callback in progress, then
1051 * wait for some finite amount of time for their completion.
1052 * TODO: add more checks here to check for cmd timeout, offline
1053 * timeout and other (??) threads.
1054 */
1055 count = 0;
1056 while ((count++ <= 30) && (fcsm->sm_ncmds || fcsm->sm_cb_count)) {
1057 mutex_exit(&fcsm->sm_mutex);
1058 delay(drv_usectohz(1000000));
1059 mutex_enter(&fcsm->sm_mutex);
1060 }
1061 if (fcsm->sm_ncmds || fcsm->sm_cb_count) {
1062 fcsm->sm_flags &= ~flag;
1063 mutex_exit(&fcsm->sm_mutex);
1064 fcsm_display(CE_WARN, SM_LOG, fcsm, NULL,
1065 "port_detach: Failing suspend, port is busy");
1066 return (DDI_FAILURE);
1067 }
1068 if (flag == FCSM_DETACHING) {
1069 fcsm->sm_flags &= ~FCSM_DETACHING;
1070 fcsm->sm_flags |= FCSM_DETACHED;
1071 }
1072
1073 mutex_exit(&fcsm->sm_mutex);
1074
1075 FCSM_DEBUG(SMDL_INFO, (CE_CONT, SM_LOG, fcsm, NULL,
1076 "port_detach: cmd 0x%x pathname <%s>",
1077 cmd, ddi_pathname(pinfo->port_dip, pathname)));
1078
1551 * If this port instance is not yet attached, then wait
1552 * for a finite time for attach to complete
1553 */
1554 fcsm = ddi_get_soft_state(fcsm_state, instance);
1555 count = 0;
1556 while (count++ <= 30) {
1557 if (fcsm != NULL) {
1558 mutex_enter(&fcsm->sm_mutex);
1559 if (fcsm->sm_flags & FCSM_ATTACHED) {
1560 mutex_exit(&fcsm->sm_mutex);
1561 break;
1562 }
1563 mutex_exit(&fcsm->sm_mutex);
1564 }
1565 if (count == 1) {
1566 FCSM_DEBUG(SMDL_TRACE,
1567 (CE_WARN, SM_LOG, NULL, NULL,
1568 "fciocmd: instance 0x%x, "
1569 "wait for port attach", instance));
1570 }
1571 delay(drv_usectohz(1000000));
1572 fcsm = ddi_get_soft_state(fcsm_state, instance);
1573 }
1574 if (count > 30) {
1575 FCSM_DEBUG(SMDL_TRACE, (CE_WARN, SM_LOG, NULL, NULL,
1576 "fciocmd: instance 0x%x, port not attached",
1577 instance));
1578 retval = ENXIO;
1579 break;
1580 }
1581
1582 req_iu = kmem_zalloc(fcio->fcio_ilen, KM_SLEEP);
1583 rsp_iu = kmem_zalloc(fcio->fcio_olen, KM_SLEEP);
1584 ASSERT((req_iu != NULL) && (rsp_iu != NULL));
1585
1586 if (ddi_copyin(fcio->fcio_ibuf, req_iu,
1587 fcio->fcio_ilen, mode)) {
1588 retval = EFAULT;
1589 kmem_free(req_iu, fcio->fcio_ilen);
1590 kmem_free(rsp_iu, fcio->fcio_olen);
1591 break;
|
750
751 FCSM_DEBUG(SMDL_TRACE, (CE_CONT, SM_LOG, NULL, NULL,
752 "detach: start. cmd <DETACH>", cmd));
753
754 mutex_enter(&fcsm_global_mutex);
755
756 /*
757 * If port attach/detach in progress, then wait for 5 seconds
758 * for them to complete.
759 */
760 if (fcsm_num_attaching || fcsm_num_detaching) {
761 int count;
762
763 FCSM_DEBUG(SMDL_TRACE, (CE_WARN, SM_LOG, NULL, NULL,
764 "detach: wait for port attach/detach to complete"));
765
766 count = 0;
767 while ((count++ <= 30) &&
768 (fcsm_num_attaching || fcsm_num_detaching)) {
769 mutex_exit(&fcsm_global_mutex);
770 delay(drv_sectohz(1));
771 mutex_enter(&fcsm_global_mutex);
772 }
773
774 /* Port attach/detach still in prog, so fail detach */
775 if (fcsm_num_attaching || fcsm_num_detaching) {
776 mutex_exit(&fcsm_global_mutex);
777 FCSM_DEBUG(SMDL_ERR, (CE_WARN, SM_LOG, NULL,
778 NULL, "detach: Failing detach. port "
779 "attach/detach in progress"));
780 rval = DDI_FAILURE;
781 break;
782 }
783 }
784
785 if (fcsm_port_head == NULL) {
786 /* Not much do, Succeed to detach. */
787 ddi_remove_minor_node(fcsm_dip, NULL);
788 fcsm_dip = NULL;
789 fcsm_detached = 0;
790 mutex_exit(&fcsm_global_mutex);
1038 return (DDI_SUCCESS);
1039 }
1040 break;
1041
1042 default:
1043 mutex_exit(&fcsm->sm_mutex);
1044 return (DDI_FAILURE);
1045 };
1046
1047 fcsm->sm_flags |= flag;
1048
1049 /*
1050 * If some commands are pending OR callback in progress, then
1051 * wait for some finite amount of time for their completion.
1052 * TODO: add more checks here to check for cmd timeout, offline
1053 * timeout and other (??) threads.
1054 */
1055 count = 0;
1056 while ((count++ <= 30) && (fcsm->sm_ncmds || fcsm->sm_cb_count)) {
1057 mutex_exit(&fcsm->sm_mutex);
1058 delay(drv_sectohz(1));
1059 mutex_enter(&fcsm->sm_mutex);
1060 }
1061 if (fcsm->sm_ncmds || fcsm->sm_cb_count) {
1062 fcsm->sm_flags &= ~flag;
1063 mutex_exit(&fcsm->sm_mutex);
1064 fcsm_display(CE_WARN, SM_LOG, fcsm, NULL,
1065 "port_detach: Failing suspend, port is busy");
1066 return (DDI_FAILURE);
1067 }
1068 if (flag == FCSM_DETACHING) {
1069 fcsm->sm_flags &= ~FCSM_DETACHING;
1070 fcsm->sm_flags |= FCSM_DETACHED;
1071 }
1072
1073 mutex_exit(&fcsm->sm_mutex);
1074
1075 FCSM_DEBUG(SMDL_INFO, (CE_CONT, SM_LOG, fcsm, NULL,
1076 "port_detach: cmd 0x%x pathname <%s>",
1077 cmd, ddi_pathname(pinfo->port_dip, pathname)));
1078
1551 * If this port instance is not yet attached, then wait
1552 * for a finite time for attach to complete
1553 */
1554 fcsm = ddi_get_soft_state(fcsm_state, instance);
1555 count = 0;
1556 while (count++ <= 30) {
1557 if (fcsm != NULL) {
1558 mutex_enter(&fcsm->sm_mutex);
1559 if (fcsm->sm_flags & FCSM_ATTACHED) {
1560 mutex_exit(&fcsm->sm_mutex);
1561 break;
1562 }
1563 mutex_exit(&fcsm->sm_mutex);
1564 }
1565 if (count == 1) {
1566 FCSM_DEBUG(SMDL_TRACE,
1567 (CE_WARN, SM_LOG, NULL, NULL,
1568 "fciocmd: instance 0x%x, "
1569 "wait for port attach", instance));
1570 }
1571 delay(drv_sectohz(1));
1572 fcsm = ddi_get_soft_state(fcsm_state, instance);
1573 }
1574 if (count > 30) {
1575 FCSM_DEBUG(SMDL_TRACE, (CE_WARN, SM_LOG, NULL, NULL,
1576 "fciocmd: instance 0x%x, port not attached",
1577 instance));
1578 retval = ENXIO;
1579 break;
1580 }
1581
1582 req_iu = kmem_zalloc(fcio->fcio_ilen, KM_SLEEP);
1583 rsp_iu = kmem_zalloc(fcio->fcio_olen, KM_SLEEP);
1584 ASSERT((req_iu != NULL) && (rsp_iu != NULL));
1585
1586 if (ddi_copyin(fcio->fcio_ibuf, req_iu,
1587 fcio->fcio_ilen, mode)) {
1588 retval = EFAULT;
1589 kmem_free(req_iu, fcio->fcio_ilen);
1590 kmem_free(rsp_iu, fcio->fcio_olen);
1591 break;
|