908 AACDB_PRINT(softs, CE_WARN, "failed to create aac node");
909 goto error;
910 }
911
912 /* Common attach is OK, so we are attached! */
913 softs->state |= AAC_STATE_RUN;
914
915 /* Create event thread */
916 softs->fibctx_p = &softs->aifctx;
917 if ((softs->event_thread = thread_create(NULL, 0, aac_event_thread,
918 softs, 0, &p0, TS_RUN, minclsyspri)) == NULL) {
919 AACDB_PRINT(softs, CE_WARN, "aif thread create failed");
920 softs->state &= ~AAC_STATE_RUN;
921 goto error;
922 }
923
924 aac_unhold_bus(softs, AAC_IOCMD_SYNC | AAC_IOCMD_ASYNC);
925
926 /* Create a thread for command timeout */
927 softs->timeout_id = timeout(aac_timer, (void *)softs,
928 (aac_tick * drv_usectohz(1000000)));
929
930 /* Common attach is OK, so we are attached! */
931 ddi_report_dev(dip);
932 AACDB_PRINT(softs, CE_NOTE, "aac attached ok");
933 return (DDI_SUCCESS);
934
935 error:
936 if (attach_state & AAC_ATTACH_CREATE_SCSI)
937 ddi_remove_minor_node(dip, "scsi");
938 if (attach_state & AAC_ATTACH_CREATE_DEVCTL)
939 ddi_remove_minor_node(dip, "devctl");
940 if (attach_state & AAC_ATTACH_COMM_SPACE_SETUP)
941 aac_common_detach(softs);
942 if (attach_state & AAC_ATTACH_SCSI_TRAN_SETUP) {
943 (void) scsi_hba_detach(dip);
944 scsi_hba_tran_free(AAC_DIP2TRAN(dip));
945 }
946 if (attach_state & AAC_ATTACH_KMUTEX_INITED) {
947 mutex_destroy(&softs->io_lock);
948 mutex_destroy(&softs->q_comp_mutex);
4363 */
4364 static void
4365 aac_check_drain(void *arg)
4366 {
4367 struct aac_softstate *softs = arg;
4368
4369 mutex_enter(&softs->io_lock);
4370 if (softs->ndrains) {
4371 softs->drain_timeid = 0;
4372 /*
4373 * If both ASYNC and SYNC bus throttle are held,
4374 * wake up threads only when both are drained out.
4375 */
4376 if ((softs->bus_throttle[AAC_CMDQ_ASYNC] > 0 ||
4377 softs->bus_ncmds[AAC_CMDQ_ASYNC] == 0) &&
4378 (softs->bus_throttle[AAC_CMDQ_SYNC] > 0 ||
4379 softs->bus_ncmds[AAC_CMDQ_SYNC] == 0))
4380 cv_broadcast(&softs->drain_cv);
4381 else
4382 softs->drain_timeid = timeout(aac_check_drain, softs,
4383 AAC_QUIESCE_TICK * drv_usectohz(1000000));
4384 }
4385 mutex_exit(&softs->io_lock);
4386 }
4387
4388 /*
4389 * If not draining the outstanding cmds, drain them. Otherwise,
4390 * only update ndrains.
4391 */
4392 static void
4393 aac_start_drain(struct aac_softstate *softs)
4394 {
4395 if (softs->ndrains == 0) {
4396 ASSERT(softs->drain_timeid == 0);
4397 softs->drain_timeid = timeout(aac_check_drain, softs,
4398 AAC_QUIESCE_TICK * drv_usectohz(1000000));
4399 }
4400 softs->ndrains++;
4401 }
4402
4403 /*
4404 * Stop the draining thread when no other threads use it any longer.
4405 * Side effect: io_lock may be released in the middle.
4406 */
4407 static void
4408 aac_stop_drain(struct aac_softstate *softs)
4409 {
4410 softs->ndrains--;
4411 if (softs->ndrains == 0) {
4412 if (softs->drain_timeid != 0) {
4413 timeout_id_t tid = softs->drain_timeid;
4414
4415 softs->drain_timeid = 0;
4416 mutex_exit(&softs->io_lock);
4417 (void) untimeout(tid);
4418 mutex_enter(&softs->io_lock);
6668 do {
6669 struct aac_cmd *acp;
6670
6671 time_out = 0;
6672 for (acp = softs->q_busy.q_head; acp; acp = acp->next) {
6673 if (acp->timeout == 0)
6674 continue;
6675
6676 /*
6677 * If timeout happened, update outstanding cmds
6678 * to be checked later again.
6679 */
6680 if (time_adjust) {
6681 acp->timeout += time_adjust;
6682 continue;
6683 }
6684
6685 if (acp->timeout <= softs_timebase) {
6686 aac_cmd_timeout(softs, acp);
6687 time_out = 1;
6688 time_adjust = aac_tick * drv_usectohz(1000000);
6689 break; /* timeout happened */
6690 } else {
6691 break; /* no timeout */
6692 }
6693 }
6694 } while (time_out);
6695
6696 mutex_enter(&softs->time_mutex);
6697 softs->time_out = softs->timebase + aac_tick;
6698 mutex_exit(&softs->time_mutex);
6699 }
6700
6701 /*
6702 * The event thread handles various tasks serially for the other parts of
6703 * the driver, so that they can run fast.
6704 */
6705 static void
6706 aac_event_thread(struct aac_softstate *softs)
6707 {
6708 int run = 1;
6740 cv_signal(&softs->event_wait_cv);
6741 mutex_exit(&softs->ev_lock);
6742 }
6743
6744 /*
6745 * Internal timer. It is only responsbile for time counting and report time
6746 * related events. Events handling is done by aac_event_thread(), so that
6747 * the timer itself could be as precise as possible.
6748 */
6749 static void
6750 aac_timer(void *arg)
6751 {
6752 struct aac_softstate *softs = arg;
6753 int events = 0;
6754
6755 mutex_enter(&softs->time_mutex);
6756
6757 /* If timer is being stopped, exit */
6758 if (softs->timeout_id) {
6759 softs->timeout_id = timeout(aac_timer, (void *)softs,
6760 (aac_tick * drv_usectohz(1000000)));
6761 } else {
6762 mutex_exit(&softs->time_mutex);
6763 return;
6764 }
6765
6766 /* Time counting */
6767 softs->timebase += aac_tick;
6768
6769 /* Check time related events */
6770 if (softs->time_out && softs->time_out <= softs->timebase)
6771 events |= AAC_EVENT_TIMEOUT;
6772 if (softs->time_sync && softs->time_sync <= softs->timebase)
6773 events |= AAC_EVENT_SYNCTICK;
6774
6775 mutex_exit(&softs->time_mutex);
6776
6777 if (events)
6778 aac_event_disp(softs, events);
6779 }
6780
|
908 AACDB_PRINT(softs, CE_WARN, "failed to create aac node");
909 goto error;
910 }
911
912 /* Common attach is OK, so we are attached! */
913 softs->state |= AAC_STATE_RUN;
914
915 /* Create event thread */
916 softs->fibctx_p = &softs->aifctx;
917 if ((softs->event_thread = thread_create(NULL, 0, aac_event_thread,
918 softs, 0, &p0, TS_RUN, minclsyspri)) == NULL) {
919 AACDB_PRINT(softs, CE_WARN, "aif thread create failed");
920 softs->state &= ~AAC_STATE_RUN;
921 goto error;
922 }
923
924 aac_unhold_bus(softs, AAC_IOCMD_SYNC | AAC_IOCMD_ASYNC);
925
926 /* Create a thread for command timeout */
927 softs->timeout_id = timeout(aac_timer, (void *)softs,
928 drv_sectohz(aac_tick));
929
930 /* Common attach is OK, so we are attached! */
931 ddi_report_dev(dip);
932 AACDB_PRINT(softs, CE_NOTE, "aac attached ok");
933 return (DDI_SUCCESS);
934
935 error:
936 if (attach_state & AAC_ATTACH_CREATE_SCSI)
937 ddi_remove_minor_node(dip, "scsi");
938 if (attach_state & AAC_ATTACH_CREATE_DEVCTL)
939 ddi_remove_minor_node(dip, "devctl");
940 if (attach_state & AAC_ATTACH_COMM_SPACE_SETUP)
941 aac_common_detach(softs);
942 if (attach_state & AAC_ATTACH_SCSI_TRAN_SETUP) {
943 (void) scsi_hba_detach(dip);
944 scsi_hba_tran_free(AAC_DIP2TRAN(dip));
945 }
946 if (attach_state & AAC_ATTACH_KMUTEX_INITED) {
947 mutex_destroy(&softs->io_lock);
948 mutex_destroy(&softs->q_comp_mutex);
4363 */
4364 static void
4365 aac_check_drain(void *arg)
4366 {
4367 struct aac_softstate *softs = arg;
4368
4369 mutex_enter(&softs->io_lock);
4370 if (softs->ndrains) {
4371 softs->drain_timeid = 0;
4372 /*
4373 * If both ASYNC and SYNC bus throttle are held,
4374 * wake up threads only when both are drained out.
4375 */
4376 if ((softs->bus_throttle[AAC_CMDQ_ASYNC] > 0 ||
4377 softs->bus_ncmds[AAC_CMDQ_ASYNC] == 0) &&
4378 (softs->bus_throttle[AAC_CMDQ_SYNC] > 0 ||
4379 softs->bus_ncmds[AAC_CMDQ_SYNC] == 0))
4380 cv_broadcast(&softs->drain_cv);
4381 else
4382 softs->drain_timeid = timeout(aac_check_drain, softs,
4383 drv_sectohz(AAC_QUIESCE_TICK));
4384 }
4385 mutex_exit(&softs->io_lock);
4386 }
4387
4388 /*
4389 * If not draining the outstanding cmds, drain them. Otherwise,
4390 * only update ndrains.
4391 */
4392 static void
4393 aac_start_drain(struct aac_softstate *softs)
4394 {
4395 if (softs->ndrains == 0) {
4396 ASSERT(softs->drain_timeid == 0);
4397 softs->drain_timeid = timeout(aac_check_drain, softs,
4398 drv_sectohz(AAC_QUIESCE_TICK));
4399 }
4400 softs->ndrains++;
4401 }
4402
4403 /*
4404 * Stop the draining thread when no other threads use it any longer.
4405 * Side effect: io_lock may be released in the middle.
4406 */
4407 static void
4408 aac_stop_drain(struct aac_softstate *softs)
4409 {
4410 softs->ndrains--;
4411 if (softs->ndrains == 0) {
4412 if (softs->drain_timeid != 0) {
4413 timeout_id_t tid = softs->drain_timeid;
4414
4415 softs->drain_timeid = 0;
4416 mutex_exit(&softs->io_lock);
4417 (void) untimeout(tid);
4418 mutex_enter(&softs->io_lock);
6668 do {
6669 struct aac_cmd *acp;
6670
6671 time_out = 0;
6672 for (acp = softs->q_busy.q_head; acp; acp = acp->next) {
6673 if (acp->timeout == 0)
6674 continue;
6675
6676 /*
6677 * If timeout happened, update outstanding cmds
6678 * to be checked later again.
6679 */
6680 if (time_adjust) {
6681 acp->timeout += time_adjust;
6682 continue;
6683 }
6684
6685 if (acp->timeout <= softs_timebase) {
6686 aac_cmd_timeout(softs, acp);
6687 time_out = 1;
6688 time_adjust = drv_sectohz(aac_tick);
6689 break; /* timeout happened */
6690 } else {
6691 break; /* no timeout */
6692 }
6693 }
6694 } while (time_out);
6695
6696 mutex_enter(&softs->time_mutex);
6697 softs->time_out = softs->timebase + aac_tick;
6698 mutex_exit(&softs->time_mutex);
6699 }
6700
6701 /*
6702 * The event thread handles various tasks serially for the other parts of
6703 * the driver, so that they can run fast.
6704 */
6705 static void
6706 aac_event_thread(struct aac_softstate *softs)
6707 {
6708 int run = 1;
6740 cv_signal(&softs->event_wait_cv);
6741 mutex_exit(&softs->ev_lock);
6742 }
6743
6744 /*
6745 * Internal timer. It is only responsbile for time counting and report time
6746 * related events. Events handling is done by aac_event_thread(), so that
6747 * the timer itself could be as precise as possible.
6748 */
6749 static void
6750 aac_timer(void *arg)
6751 {
6752 struct aac_softstate *softs = arg;
6753 int events = 0;
6754
6755 mutex_enter(&softs->time_mutex);
6756
6757 /* If timer is being stopped, exit */
6758 if (softs->timeout_id) {
6759 softs->timeout_id = timeout(aac_timer, (void *)softs,
6760 drv_sectohz(aac_tick));
6761 } else {
6762 mutex_exit(&softs->time_mutex);
6763 return;
6764 }
6765
6766 /* Time counting */
6767 softs->timebase += aac_tick;
6768
6769 /* Check time related events */
6770 if (softs->time_out && softs->time_out <= softs->timebase)
6771 events |= AAC_EVENT_TIMEOUT;
6772 if (softs->time_sync && softs->time_sync <= softs->timebase)
6773 events |= AAC_EVENT_SYNCTICK;
6774
6775 mutex_exit(&softs->time_mutex);
6776
6777 if (events)
6778 aac_event_disp(softs, events);
6779 }
6780
|