Print this page
XXXX introduce drv_sectohz


  85 extern uint32_t fct_rscn_options;
  86 
  87 /*
  88  * NOTE: if anybody drops the iport_worker_lock then they should not return
  89  * DISC_ACTION_NO_WORK. Which also means, dont drop the lock if you have
  90  * nothing to do. Or else return DISC_ACTION_RESCAN or DISC_ACTION_DELAY_RESCAN.
  91  * But you cannot be infinitly returning those so have some logic to
  92  * determine that there is nothing to do without dropping the lock.
  93  */
  94 void
  95 fct_port_worker(void *arg)
  96 {
  97         fct_local_port_t        *port = (fct_local_port_t *)arg;
  98         fct_i_local_port_t      *iport = (fct_i_local_port_t *)
  99             port->port_fct_private;
 100         disc_action_t           suggested_action;
 101         clock_t                 dl, short_delay, long_delay;
 102         int64_t                 tmp_delay;
 103 
 104         iport->iport_cmdcheck_clock = ddi_get_lbolt() +
 105             drv_usectohz(FCT_CMDLIST_CHECK_SECONDS * 1000000);
 106         short_delay = drv_usectohz(10000);
 107         long_delay = drv_usectohz(1000000);
 108 
 109         stmf_trace(iport->iport_alias, "iport is %p", iport);
 110         /* Discovery loop */
 111         mutex_enter(&iport->iport_worker_lock);
 112         atomic_or_32(&iport->iport_flags, IPORT_WORKER_RUNNING);
 113         while ((iport->iport_flags & IPORT_TERMINATE_WORKER) == 0) {
 114                 suggested_action = DISC_ACTION_NO_WORK;
 115                 /*
 116                  * Local port events are of the highest prioriy
 117                  */
 118                 if (iport->iport_event_head) {
 119                         suggested_action |= fct_handle_local_port_event(iport);
 120                 }
 121 
 122                 /*
 123                  * We could post solicited ELSes to discovery queue.
 124                  * solicited CT will be processed inside fct_check_solcmd_queue
 125                  */
 126                 if (iport->iport_solcmd_queue) {
 127                         suggested_action |= fct_check_solcmd_queue(iport);


 139                  */
 140                 if ((iport->iport_link_state ==      PORT_STATE_LINK_INIT_START) &&
 141                     !(iport->iport_li_state & (LI_STATE_FLAG_CMD_WAITING |
 142                     LI_STATE_FLAG_NO_LI_YET))) {
 143                         suggested_action |= fct_process_link_init(iport);
 144                 }
 145 
 146                 /*
 147                  * We process cmd aborting in the end
 148                  */
 149                 if (iport->iport_abort_queue) {
 150                         suggested_action |= fct_cmd_terminator(iport);
 151                 }
 152 
 153                 /*
 154                  * Check cmd max/free
 155                  */
 156                 if (iport->iport_cmdcheck_clock <= ddi_get_lbolt()) {
 157                         suggested_action |= fct_check_cmdlist(iport);
 158                         iport->iport_cmdcheck_clock = ddi_get_lbolt() +
 159                             drv_usectohz(FCT_CMDLIST_CHECK_SECONDS * 1000000);
 160                         iport->iport_max_active_ncmds = 0;
 161                 }
 162 
 163                 if (iport->iport_offline_prstate != FCT_OPR_DONE) {
 164                         suggested_action |= fct_handle_port_offline(iport);
 165                 }
 166 
 167                 if (suggested_action & DISC_ACTION_RESCAN) {
 168                         continue;
 169                 } else if (suggested_action & DISC_ACTION_DELAY_RESCAN) {
 170                         /*
 171                          * This is not very optimum as whoever returned
 172                          * DISC_ACTION_DELAY_RESCAN must have dropped the lock
 173                          * and more things might have queued up. But since
 174                          * we are only doing small delays, it only delays
 175                          * things by a few ms, which is okey.
 176                          */
 177                         if (suggested_action & DISC_ACTION_USE_SHORT_DELAY) {
 178                                 dl = short_delay;
 179                         } else {


 579                                  */
 580                                 if ((li->port_topology ^
 581                                     iport->iport_link_old_topology) &
 582                                     PORT_TOPOLOGY_FABRIC_BIT) {
 583                                         mutex_exit(&iport->iport_worker_lock);
 584                                         fct_rehash(iport);
 585                                         mutex_enter(&iport->iport_worker_lock);
 586                                 }
 587                         }
 588                         iport->iport_link_old_topology = li->port_topology;
 589                 }
 590                 /* Skip next level if topo is not N2N */
 591                 if (li->port_topology != PORT_TOPOLOGY_PT_TO_PT) {
 592                         iport->iport_li_state += 2;
 593                         atomic_and_32(&iport->iport_flags,
 594                             ~IPORT_ALLOW_UNSOL_FLOGI);
 595                 } else {
 596                         iport->iport_li_state++;
 597                         iport->iport_login_retry = 0;
 598                         iport->iport_li_cmd_timeout = ddi_get_lbolt() +
 599                             drv_usectohz(25 * 1000000);
 600                 }
 601                 goto check_state_again;
 602 
 603         case LI_STATE_N2N_PLOGI:
 604                 ASSERT(IPORT_FLOGI_DONE(iport));
 605                 ASSERT(iport->iport_link_info.port_topology ==
 606                     PORT_TOPOLOGY_PT_TO_PT);
 607                 if (iport->iport_li_state & LI_STATE_FLAG_CMD_RETCHECK) {
 608                         iport->iport_li_state &= ~LI_STATE_FLAG_CMD_RETCHECK;
 609                         if (iport->iport_li_comp_status != FCT_SUCCESS) {
 610                                 iport->iport_login_retry++;
 611                                 if (iport->iport_login_retry >= 3) {
 612                                         stmf_trace(iport->iport_alias, "Failing"
 613                                             " to PLOGI to remote port in N2N "
 614                                             " ret=%llx, forcing link down",
 615                                             iport->iport_li_comp_status);
 616                                         mutex_exit(&iport->iport_worker_lock);
 617                                         fct_handle_event(iport->iport_port,
 618                                             FCT_EVENT_LINK_DOWN, 0, 0);
 619                                         mutex_enter(&iport->iport_worker_lock);




  85 extern uint32_t fct_rscn_options;
  86 
  87 /*
  88  * NOTE: if anybody drops the iport_worker_lock then they should not return
  89  * DISC_ACTION_NO_WORK. Which also means, dont drop the lock if you have
  90  * nothing to do. Or else return DISC_ACTION_RESCAN or DISC_ACTION_DELAY_RESCAN.
  91  * But you cannot be infinitly returning those so have some logic to
  92  * determine that there is nothing to do without dropping the lock.
  93  */
  94 void
  95 fct_port_worker(void *arg)
  96 {
  97         fct_local_port_t        *port = (fct_local_port_t *)arg;
  98         fct_i_local_port_t      *iport = (fct_i_local_port_t *)
  99             port->port_fct_private;
 100         disc_action_t           suggested_action;
 101         clock_t                 dl, short_delay, long_delay;
 102         int64_t                 tmp_delay;
 103 
 104         iport->iport_cmdcheck_clock = ddi_get_lbolt() +
 105             drv_sectohz(FCT_CMDLIST_CHECK_SECONDS);
 106         short_delay = drv_usectohz(10000);
 107         long_delay = drv_sectohz(1);
 108 
 109         stmf_trace(iport->iport_alias, "iport is %p", iport);
 110         /* Discovery loop */
 111         mutex_enter(&iport->iport_worker_lock);
 112         atomic_or_32(&iport->iport_flags, IPORT_WORKER_RUNNING);
 113         while ((iport->iport_flags & IPORT_TERMINATE_WORKER) == 0) {
 114                 suggested_action = DISC_ACTION_NO_WORK;
 115                 /*
 116                  * Local port events are of the highest prioriy
 117                  */
 118                 if (iport->iport_event_head) {
 119                         suggested_action |= fct_handle_local_port_event(iport);
 120                 }
 121 
 122                 /*
 123                  * We could post solicited ELSes to discovery queue.
 124                  * solicited CT will be processed inside fct_check_solcmd_queue
 125                  */
 126                 if (iport->iport_solcmd_queue) {
 127                         suggested_action |= fct_check_solcmd_queue(iport);


 139                  */
 140                 if ((iport->iport_link_state ==      PORT_STATE_LINK_INIT_START) &&
 141                     !(iport->iport_li_state & (LI_STATE_FLAG_CMD_WAITING |
 142                     LI_STATE_FLAG_NO_LI_YET))) {
 143                         suggested_action |= fct_process_link_init(iport);
 144                 }
 145 
 146                 /*
 147                  * We process cmd aborting in the end
 148                  */
 149                 if (iport->iport_abort_queue) {
 150                         suggested_action |= fct_cmd_terminator(iport);
 151                 }
 152 
 153                 /*
 154                  * Check cmd max/free
 155                  */
 156                 if (iport->iport_cmdcheck_clock <= ddi_get_lbolt()) {
 157                         suggested_action |= fct_check_cmdlist(iport);
 158                         iport->iport_cmdcheck_clock = ddi_get_lbolt() +
 159                             drv_sectohz(FCT_CMDLIST_CHECK_SECONDS);
 160                         iport->iport_max_active_ncmds = 0;
 161                 }
 162 
 163                 if (iport->iport_offline_prstate != FCT_OPR_DONE) {
 164                         suggested_action |= fct_handle_port_offline(iport);
 165                 }
 166 
 167                 if (suggested_action & DISC_ACTION_RESCAN) {
 168                         continue;
 169                 } else if (suggested_action & DISC_ACTION_DELAY_RESCAN) {
 170                         /*
 171                          * This is not very optimum as whoever returned
 172                          * DISC_ACTION_DELAY_RESCAN must have dropped the lock
 173                          * and more things might have queued up. But since
 174                          * we are only doing small delays, it only delays
 175                          * things by a few ms, which is okey.
 176                          */
 177                         if (suggested_action & DISC_ACTION_USE_SHORT_DELAY) {
 178                                 dl = short_delay;
 179                         } else {


 579                                  */
 580                                 if ((li->port_topology ^
 581                                     iport->iport_link_old_topology) &
 582                                     PORT_TOPOLOGY_FABRIC_BIT) {
 583                                         mutex_exit(&iport->iport_worker_lock);
 584                                         fct_rehash(iport);
 585                                         mutex_enter(&iport->iport_worker_lock);
 586                                 }
 587                         }
 588                         iport->iport_link_old_topology = li->port_topology;
 589                 }
 590                 /* Skip next level if topo is not N2N */
 591                 if (li->port_topology != PORT_TOPOLOGY_PT_TO_PT) {
 592                         iport->iport_li_state += 2;
 593                         atomic_and_32(&iport->iport_flags,
 594                             ~IPORT_ALLOW_UNSOL_FLOGI);
 595                 } else {
 596                         iport->iport_li_state++;
 597                         iport->iport_login_retry = 0;
 598                         iport->iport_li_cmd_timeout = ddi_get_lbolt() +
 599                             drv_sectohz(25);
 600                 }
 601                 goto check_state_again;
 602 
 603         case LI_STATE_N2N_PLOGI:
 604                 ASSERT(IPORT_FLOGI_DONE(iport));
 605                 ASSERT(iport->iport_link_info.port_topology ==
 606                     PORT_TOPOLOGY_PT_TO_PT);
 607                 if (iport->iport_li_state & LI_STATE_FLAG_CMD_RETCHECK) {
 608                         iport->iport_li_state &= ~LI_STATE_FLAG_CMD_RETCHECK;
 609                         if (iport->iport_li_comp_status != FCT_SUCCESS) {
 610                                 iport->iport_login_retry++;
 611                                 if (iport->iport_login_retry >= 3) {
 612                                         stmf_trace(iport->iport_alias, "Failing"
 613                                             " to PLOGI to remote port in N2N "
 614                                             " ret=%llx, forcing link down",
 615                                             iport->iport_li_comp_status);
 616                                         mutex_exit(&iport->iport_worker_lock);
 617                                         fct_handle_event(iport->iport_port,
 618                                             FCT_EVENT_LINK_DOWN, 0, 0);
 619                                         mutex_enter(&iport->iport_worker_lock);