977 if (fas_head == NULL) {
978 fas_head = fas;
979 } else {
980 fas_tail->f_next = fas;
981 }
982 fas_tail = fas; /* point to last fas in list */
983 rw_exit(&fas_global_rwlock);
984
985 /*
986 * there is one watchdog handler for all driver instances.
987 * start the watchdog if it hasn't been done yet
988 */
989 mutex_enter(&fas_global_mutex);
990 if (fas_scsi_watchdog_tick == 0) {
991 fas_scsi_watchdog_tick = ddi_prop_get_int(DDI_DEV_T_ANY,
992 dip, 0, "scsi-watchdog-tick", DEFAULT_WD_TICK);
993 if (fas_scsi_watchdog_tick != DEFAULT_WD_TICK) {
994 fas_log(fas, CE_NOTE, "?scsi-watchdog-tick=%d\n",
995 fas_scsi_watchdog_tick);
996 }
997 fas_tick = drv_usectohz((clock_t)
998 fas_scsi_watchdog_tick * 1000000);
999 IPRINTF2("fas scsi watchdog tick=%x, fas_tick=%lx\n",
1000 fas_scsi_watchdog_tick, fas_tick);
1001 if (fas_timeout_id == 0) {
1002 fas_timeout_id = timeout(fas_watch, NULL, fas_tick);
1003 fas_timeout_initted = 1;
1004 }
1005 }
1006 mutex_exit(&fas_global_mutex);
1007
1008 ddi_report_dev(dip);
1009
1010 return (DDI_SUCCESS);
1011
1012 fail:
1013 cmn_err(CE_WARN, "fas%d: cannot attach", instance);
1014 if (fas) {
1015 for (slot = 0; slot < N_SLOTS; slot++) {
1016 struct f_slots *active = fas->f_active[slot];
1017 if (active) {
1018 kmem_free(active, active->f_size);
1348 * Free the scsi_transport structure for this device.
1349 */
1350 scsi_hba_tran_free(tran);
1351
1352 ddi_soft_state_free(fas_state, ddi_get_instance(dip));
1353
1354 return (DDI_SUCCESS);
1355 }
1356
1357 static int
1358 fas_quiesce_bus(struct fas *fas)
1359 {
1360 mutex_enter(FAS_MUTEX(fas));
1361 IPRINTF("fas_quiesce: QUIESCEing\n");
1362 IPRINTF3("fas_quiesce: ncmds (%d) ndisc (%d) state (%d)\n",
1363 fas->f_ncmds, fas->f_ndisc, fas->f_softstate);
1364 fas_set_throttles(fas, 0, N_SLOTS, HOLD_THROTTLE);
1365 if (fas_check_outstanding(fas)) {
1366 fas->f_softstate |= FAS_SS_DRAINING;
1367 fas->f_quiesce_timeid = timeout(fas_ncmds_checkdrain,
1368 fas, (FAS_QUIESCE_TIMEOUT * drv_usectohz(1000000)));
1369 if (cv_wait_sig(FAS_CV(fas), FAS_MUTEX(fas)) == 0) {
1370 /*
1371 * quiesce has been interrupted.
1372 */
1373 IPRINTF("fas_quiesce: abort QUIESCE\n");
1374 fas->f_softstate &= ~FAS_SS_DRAINING;
1375 fas_set_throttles(fas, 0, N_SLOTS, MAX_THROTTLE);
1376 (void) fas_istart(fas);
1377 if (fas->f_quiesce_timeid != 0) {
1378 mutex_exit(FAS_MUTEX(fas));
1379 #ifndef __lock_lint /* warlock complains but there is a NOTE on this */
1380 (void) untimeout(fas->f_quiesce_timeid);
1381 fas->f_quiesce_timeid = 0;
1382 #endif
1383 return (-1);
1384 }
1385 mutex_exit(FAS_MUTEX(fas));
1386 return (-1);
1387 } else {
1388 IPRINTF("fas_quiesce: bus is QUIESCED\n");
1419 {
1420 struct fas *fas = arg;
1421
1422 mutex_enter(FAS_MUTEX(fas));
1423 IPRINTF3("fas_checkdrain: ncmds (%d) ndisc (%d) state (%d)\n",
1424 fas->f_ncmds, fas->f_ndisc, fas->f_softstate);
1425 if (fas->f_softstate & FAS_SS_DRAINING) {
1426 fas->f_quiesce_timeid = 0;
1427 if (fas_check_outstanding(fas) == 0) {
1428 IPRINTF("fas_drain: bus has drained\n");
1429 cv_signal(FAS_CV(fas));
1430 } else {
1431 /*
1432 * throttle may have been reset by a bus reset
1433 * or fas_runpoll()
1434 * XXX shouldn't be necessary
1435 */
1436 fas_set_throttles(fas, 0, N_SLOTS, HOLD_THROTTLE);
1437 IPRINTF("fas_drain: rescheduling timeout\n");
1438 fas->f_quiesce_timeid = timeout(fas_ncmds_checkdrain,
1439 fas, (FAS_QUIESCE_TIMEOUT * drv_usectohz(1000000)));
1440 }
1441 }
1442 mutex_exit(FAS_MUTEX(fas));
1443 }
1444
1445 static int
1446 fas_check_outstanding(struct fas *fas)
1447 {
1448 uint_t slot;
1449 uint_t d = ((fas->f_dslot == 0)? 1 : fas->f_dslot);
1450 int ncmds = 0;
1451
1452 ASSERT(mutex_owned(FAS_MUTEX(fas)));
1453
1454 for (slot = 0; slot < N_SLOTS; slot += d)
1455 ncmds += fas->f_tcmds[slot];
1456
1457 return (ncmds);
1458 }
1459
|
977 if (fas_head == NULL) {
978 fas_head = fas;
979 } else {
980 fas_tail->f_next = fas;
981 }
982 fas_tail = fas; /* point to last fas in list */
983 rw_exit(&fas_global_rwlock);
984
985 /*
986 * there is one watchdog handler for all driver instances.
987 * start the watchdog if it hasn't been done yet
988 */
989 mutex_enter(&fas_global_mutex);
990 if (fas_scsi_watchdog_tick == 0) {
991 fas_scsi_watchdog_tick = ddi_prop_get_int(DDI_DEV_T_ANY,
992 dip, 0, "scsi-watchdog-tick", DEFAULT_WD_TICK);
993 if (fas_scsi_watchdog_tick != DEFAULT_WD_TICK) {
994 fas_log(fas, CE_NOTE, "?scsi-watchdog-tick=%d\n",
995 fas_scsi_watchdog_tick);
996 }
997 fas_tick = drv_sectohz((clock_t)fas_scsi_watchdog_tick);
998 IPRINTF2("fas scsi watchdog tick=%x, fas_tick=%lx\n",
999 fas_scsi_watchdog_tick, fas_tick);
1000 if (fas_timeout_id == 0) {
1001 fas_timeout_id = timeout(fas_watch, NULL, fas_tick);
1002 fas_timeout_initted = 1;
1003 }
1004 }
1005 mutex_exit(&fas_global_mutex);
1006
1007 ddi_report_dev(dip);
1008
1009 return (DDI_SUCCESS);
1010
1011 fail:
1012 cmn_err(CE_WARN, "fas%d: cannot attach", instance);
1013 if (fas) {
1014 for (slot = 0; slot < N_SLOTS; slot++) {
1015 struct f_slots *active = fas->f_active[slot];
1016 if (active) {
1017 kmem_free(active, active->f_size);
1347 * Free the scsi_transport structure for this device.
1348 */
1349 scsi_hba_tran_free(tran);
1350
1351 ddi_soft_state_free(fas_state, ddi_get_instance(dip));
1352
1353 return (DDI_SUCCESS);
1354 }
1355
1356 static int
1357 fas_quiesce_bus(struct fas *fas)
1358 {
1359 mutex_enter(FAS_MUTEX(fas));
1360 IPRINTF("fas_quiesce: QUIESCEing\n");
1361 IPRINTF3("fas_quiesce: ncmds (%d) ndisc (%d) state (%d)\n",
1362 fas->f_ncmds, fas->f_ndisc, fas->f_softstate);
1363 fas_set_throttles(fas, 0, N_SLOTS, HOLD_THROTTLE);
1364 if (fas_check_outstanding(fas)) {
1365 fas->f_softstate |= FAS_SS_DRAINING;
1366 fas->f_quiesce_timeid = timeout(fas_ncmds_checkdrain,
1367 fas, drv_sectohz(FAS_QUIESCE_TIMEOUT));
1368 if (cv_wait_sig(FAS_CV(fas), FAS_MUTEX(fas)) == 0) {
1369 /*
1370 * quiesce has been interrupted.
1371 */
1372 IPRINTF("fas_quiesce: abort QUIESCE\n");
1373 fas->f_softstate &= ~FAS_SS_DRAINING;
1374 fas_set_throttles(fas, 0, N_SLOTS, MAX_THROTTLE);
1375 (void) fas_istart(fas);
1376 if (fas->f_quiesce_timeid != 0) {
1377 mutex_exit(FAS_MUTEX(fas));
1378 #ifndef __lock_lint /* warlock complains but there is a NOTE on this */
1379 (void) untimeout(fas->f_quiesce_timeid);
1380 fas->f_quiesce_timeid = 0;
1381 #endif
1382 return (-1);
1383 }
1384 mutex_exit(FAS_MUTEX(fas));
1385 return (-1);
1386 } else {
1387 IPRINTF("fas_quiesce: bus is QUIESCED\n");
1418 {
1419 struct fas *fas = arg;
1420
1421 mutex_enter(FAS_MUTEX(fas));
1422 IPRINTF3("fas_checkdrain: ncmds (%d) ndisc (%d) state (%d)\n",
1423 fas->f_ncmds, fas->f_ndisc, fas->f_softstate);
1424 if (fas->f_softstate & FAS_SS_DRAINING) {
1425 fas->f_quiesce_timeid = 0;
1426 if (fas_check_outstanding(fas) == 0) {
1427 IPRINTF("fas_drain: bus has drained\n");
1428 cv_signal(FAS_CV(fas));
1429 } else {
1430 /*
1431 * throttle may have been reset by a bus reset
1432 * or fas_runpoll()
1433 * XXX shouldn't be necessary
1434 */
1435 fas_set_throttles(fas, 0, N_SLOTS, HOLD_THROTTLE);
1436 IPRINTF("fas_drain: rescheduling timeout\n");
1437 fas->f_quiesce_timeid = timeout(fas_ncmds_checkdrain,
1438 fas, drv_sectohz(FAS_QUIESCE_TIMEOUT));
1439 }
1440 }
1441 mutex_exit(FAS_MUTEX(fas));
1442 }
1443
1444 static int
1445 fas_check_outstanding(struct fas *fas)
1446 {
1447 uint_t slot;
1448 uint_t d = ((fas->f_dslot == 0)? 1 : fas->f_dslot);
1449 int ncmds = 0;
1450
1451 ASSERT(mutex_owned(FAS_MUTEX(fas)));
1452
1453 for (slot = 0; slot < N_SLOTS; slot += d)
1454 ncmds += fas->f_tcmds[slot];
1455
1456 return (ncmds);
1457 }
1458
|