Print this page
XXXX introduce drv_sectohz


 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