421 }
422
423 /* Let's attempt to quit the job handler gracefully */
424 port->fp_soft_state |= FP_DETACH_INPROGRESS;
425
426 mutex_exit(&port->fp_mutex);
427 converse = FC_CMD_ATTACH;
428 if (fctl_detach_ulps(port, FC_CMD_DETACH,
429 &modlinkage) != FC_SUCCESS) {
430 mutex_enter(&port->fp_mutex);
431 port->fp_soft_state &= ~FP_DETACH_INPROGRESS;
432 mutex_exit(&port->fp_mutex);
433 rval = DDI_FAILURE;
434 break;
435 }
436
437 mutex_enter(&port->fp_mutex);
438 for (cnt = 0; (port->fp_job_head) && (cnt < fp_cmd_wait_cnt);
439 cnt++) {
440 mutex_exit(&port->fp_mutex);
441 delay(drv_usectohz(1000000));
442 mutex_enter(&port->fp_mutex);
443 }
444
445 if (port->fp_job_head) {
446 mutex_exit(&port->fp_mutex);
447 rval = DDI_FAILURE;
448 break;
449 }
450 mutex_exit(&port->fp_mutex);
451
452 rval = fp_detach_handler(port);
453 break;
454
455 case DDI_SUSPEND:
456 mutex_exit(&port->fp_mutex);
457 converse = FC_CMD_RESUME;
458 if (fctl_detach_ulps(port, FC_CMD_SUSPEND,
459 &modlinkage) != FC_SUCCESS) {
460 rval = DDI_FAILURE;
461 break;
1501 /*
1502 * At this time we can only check fp internal commands, because
1503 * sd/ssd/scsi_vhci should have finsihed all their commands,
1504 * fcp/fcip/fcsm should have finished all their commands.
1505 *
1506 * It seems that all fp internal commands are asynchronous now.
1507 */
1508 port->fp_soft_state &= ~FP_DETACH_INPROGRESS;
1509 mutex_exit(&port->fp_mutex);
1510
1511 cmn_err(CE_WARN, "fp(%d): %d fp_cmd(s) is/are in progress"
1512 " Failing detach", port->fp_instance, port->fp_out_fpcmds);
1513 return (DDI_FAILURE);
1514 }
1515
1516 while ((port->fp_soft_state &
1517 (FP_SOFT_IN_STATEC_CB | FP_SOFT_IN_UNSOL_CB)) &&
1518 (delay_count < 30)) {
1519 mutex_exit(&port->fp_mutex);
1520 delay_count++;
1521 delay(drv_usectohz(1000000));
1522 mutex_enter(&port->fp_mutex);
1523 }
1524
1525 if (port->fp_soft_state &
1526 (FP_SOFT_IN_STATEC_CB | FP_SOFT_IN_UNSOL_CB)) {
1527 port->fp_soft_state &= ~FP_DETACH_INPROGRESS;
1528 mutex_exit(&port->fp_mutex);
1529
1530 cmn_err(CE_WARN, "fp(%d): FCA callback in progress: "
1531 " Failing detach", port->fp_instance);
1532 return (DDI_FAILURE);
1533 }
1534
1535 port->fp_soft_state |= FP_SOFT_IN_DETACH;
1536 port->fp_soft_state &= ~FP_DETACH_INPROGRESS;
1537 mutex_exit(&port->fp_mutex);
1538
1539 /*
1540 * If we're powered down, we need to raise power prior to submitting
1541 * the JOB_PORT_SHUTDOWN job. Otherwise, the job handler will never
1671 }
1672
1673 /*
1674 * Check if an unsolicited callback or state change handling is
1675 * in progress. If true, fail the suspend operation; also throw
1676 * a warning message notifying the failure. Note that Sun PCI
1677 * hotplug spec recommends messages in cases of failure (but
1678 * not flooding the console)
1679 *
1680 * Busy waiting for a short interval (500 millisecond ?) to see
1681 * if the callback processing completes may be another idea. Since
1682 * most of the callback processing involves a lot of work, it
1683 * is safe to just fail the SUSPEND operation. It is definitely
1684 * not bad to fail the SUSPEND operation if the driver is busy.
1685 */
1686 delay_count = 0;
1687 while ((port->fp_soft_state & (FP_SOFT_IN_STATEC_CB |
1688 FP_SOFT_IN_UNSOL_CB)) && (delay_count < 30)) {
1689 mutex_exit(&port->fp_mutex);
1690 delay_count++;
1691 delay(drv_usectohz(1000000));
1692 mutex_enter(&port->fp_mutex);
1693 }
1694
1695 if (port->fp_soft_state & (FP_SOFT_IN_STATEC_CB |
1696 FP_SOFT_IN_UNSOL_CB)) {
1697 mutex_exit(&port->fp_mutex);
1698 cmn_err(CE_WARN, "fp(%d): FCA callback in progress: "
1699 " Failing suspend", port->fp_instance);
1700 return (DDI_FAILURE);
1701 }
1702
1703 /*
1704 * Check of FC port thread is busy
1705 */
1706 if (port->fp_job_head) {
1707 mutex_exit(&port->fp_mutex);
1708 FP_TRACE(FP_NHEAD2(9, 0),
1709 "FC port thread is busy: Failing suspend");
1710 return (DDI_FAILURE);
1711 }
|
421 }
422
423 /* Let's attempt to quit the job handler gracefully */
424 port->fp_soft_state |= FP_DETACH_INPROGRESS;
425
426 mutex_exit(&port->fp_mutex);
427 converse = FC_CMD_ATTACH;
428 if (fctl_detach_ulps(port, FC_CMD_DETACH,
429 &modlinkage) != FC_SUCCESS) {
430 mutex_enter(&port->fp_mutex);
431 port->fp_soft_state &= ~FP_DETACH_INPROGRESS;
432 mutex_exit(&port->fp_mutex);
433 rval = DDI_FAILURE;
434 break;
435 }
436
437 mutex_enter(&port->fp_mutex);
438 for (cnt = 0; (port->fp_job_head) && (cnt < fp_cmd_wait_cnt);
439 cnt++) {
440 mutex_exit(&port->fp_mutex);
441 delay(drv_sectohz(1));
442 mutex_enter(&port->fp_mutex);
443 }
444
445 if (port->fp_job_head) {
446 mutex_exit(&port->fp_mutex);
447 rval = DDI_FAILURE;
448 break;
449 }
450 mutex_exit(&port->fp_mutex);
451
452 rval = fp_detach_handler(port);
453 break;
454
455 case DDI_SUSPEND:
456 mutex_exit(&port->fp_mutex);
457 converse = FC_CMD_RESUME;
458 if (fctl_detach_ulps(port, FC_CMD_SUSPEND,
459 &modlinkage) != FC_SUCCESS) {
460 rval = DDI_FAILURE;
461 break;
1501 /*
1502 * At this time we can only check fp internal commands, because
1503 * sd/ssd/scsi_vhci should have finsihed all their commands,
1504 * fcp/fcip/fcsm should have finished all their commands.
1505 *
1506 * It seems that all fp internal commands are asynchronous now.
1507 */
1508 port->fp_soft_state &= ~FP_DETACH_INPROGRESS;
1509 mutex_exit(&port->fp_mutex);
1510
1511 cmn_err(CE_WARN, "fp(%d): %d fp_cmd(s) is/are in progress"
1512 " Failing detach", port->fp_instance, port->fp_out_fpcmds);
1513 return (DDI_FAILURE);
1514 }
1515
1516 while ((port->fp_soft_state &
1517 (FP_SOFT_IN_STATEC_CB | FP_SOFT_IN_UNSOL_CB)) &&
1518 (delay_count < 30)) {
1519 mutex_exit(&port->fp_mutex);
1520 delay_count++;
1521 delay(drv_sectohz(1));
1522 mutex_enter(&port->fp_mutex);
1523 }
1524
1525 if (port->fp_soft_state &
1526 (FP_SOFT_IN_STATEC_CB | FP_SOFT_IN_UNSOL_CB)) {
1527 port->fp_soft_state &= ~FP_DETACH_INPROGRESS;
1528 mutex_exit(&port->fp_mutex);
1529
1530 cmn_err(CE_WARN, "fp(%d): FCA callback in progress: "
1531 " Failing detach", port->fp_instance);
1532 return (DDI_FAILURE);
1533 }
1534
1535 port->fp_soft_state |= FP_SOFT_IN_DETACH;
1536 port->fp_soft_state &= ~FP_DETACH_INPROGRESS;
1537 mutex_exit(&port->fp_mutex);
1538
1539 /*
1540 * If we're powered down, we need to raise power prior to submitting
1541 * the JOB_PORT_SHUTDOWN job. Otherwise, the job handler will never
1671 }
1672
1673 /*
1674 * Check if an unsolicited callback or state change handling is
1675 * in progress. If true, fail the suspend operation; also throw
1676 * a warning message notifying the failure. Note that Sun PCI
1677 * hotplug spec recommends messages in cases of failure (but
1678 * not flooding the console)
1679 *
1680 * Busy waiting for a short interval (500 millisecond ?) to see
1681 * if the callback processing completes may be another idea. Since
1682 * most of the callback processing involves a lot of work, it
1683 * is safe to just fail the SUSPEND operation. It is definitely
1684 * not bad to fail the SUSPEND operation if the driver is busy.
1685 */
1686 delay_count = 0;
1687 while ((port->fp_soft_state & (FP_SOFT_IN_STATEC_CB |
1688 FP_SOFT_IN_UNSOL_CB)) && (delay_count < 30)) {
1689 mutex_exit(&port->fp_mutex);
1690 delay_count++;
1691 delay(drv_sectohz(1));
1692 mutex_enter(&port->fp_mutex);
1693 }
1694
1695 if (port->fp_soft_state & (FP_SOFT_IN_STATEC_CB |
1696 FP_SOFT_IN_UNSOL_CB)) {
1697 mutex_exit(&port->fp_mutex);
1698 cmn_err(CE_WARN, "fp(%d): FCA callback in progress: "
1699 " Failing suspend", port->fp_instance);
1700 return (DDI_FAILURE);
1701 }
1702
1703 /*
1704 * Check of FC port thread is busy
1705 */
1706 if (port->fp_job_head) {
1707 mutex_exit(&port->fp_mutex);
1708 FP_TRACE(FP_NHEAD2(9, 0),
1709 "FC port thread is busy: Failing suspend");
1710 return (DDI_FAILURE);
1711 }
|