*/
                        if ((fcport->flags & FCF_FABRIC_DEVICE) == 0) {
                                fcport->d_id.b24 = new_fcport->d_id.b24;
-                               fcport->loop_id = FC_NO_LOOP_ID;
+                               qla2x00_clear_loop_id(fcport);
                                fcport->flags |= (FCF_FABRIC_DEVICE |
                                    FCF_LOGIN_NEEDED);
                                break;
                                ha->isp_ops->fabric_logout(vha, fcport->loop_id,
                                    fcport->d_id.b.domain, fcport->d_id.b.area,
                                    fcport->d_id.b.al_pa);
-                               fcport->loop_id = FC_NO_LOOP_ID;
+                               qla2x00_clear_loop_id(fcport);
                        }
 
                        break;
 qla2x00_find_new_loop_id(scsi_qla_host_t *vha, fc_port_t *dev)
 {
        int     rval;
-       int     found;
-       fc_port_t *fcport;
-       uint16_t first_loop_id;
        struct qla_hw_data *ha = vha->hw;
-       struct scsi_qla_host *vp;
-       struct scsi_qla_host *tvp;
        unsigned long flags = 0;
 
        rval = QLA_SUCCESS;
 
-       /* Save starting loop ID. */
-       first_loop_id = dev->loop_id;
-
-       for (;;) {
-               /* Skip loop ID if already used by adapter. */
-               if (dev->loop_id == vha->loop_id)
-                       dev->loop_id++;
-
-               /* Skip reserved loop IDs. */
-               while (qla2x00_is_reserved_id(vha, dev->loop_id))
-                       dev->loop_id++;
-
-               /* Reset loop ID if passed the end. */
-               if (dev->loop_id > ha->max_loop_id) {
-                       /* first loop ID. */
-                       dev->loop_id = ha->min_external_loopid;
-               }
-
-               /* Check for loop ID being already in use. */
-               found = 0;
-               fcport = NULL;
-
-               spin_lock_irqsave(&ha->vport_slock, flags);
-               list_for_each_entry_safe(vp, tvp, &ha->vp_list, list) {
-                       list_for_each_entry(fcport, &vp->vp_fcports, list) {
-                               if (fcport->loop_id == dev->loop_id &&
-                                                               fcport != dev) {
-                                       /* ID possibly in use */
-                                       found++;
-                                       break;
-                               }
-                       }
-                       if (found)
-                               break;
-               }
-               spin_unlock_irqrestore(&ha->vport_slock, flags);
+       spin_lock_irqsave(&ha->vport_slock, flags);
 
-               /* If not in use then it is free to use. */
-               if (!found) {
-                       ql_dbg(ql_dbg_disc, dev->vha, 0x2086,
-                           "Assigning new loopid=%x, portid=%x.\n",
-                           dev->loop_id, dev->d_id.b24);
-                       break;
-               }
+       dev->loop_id = find_first_zero_bit(ha->loop_id_map,
+           LOOPID_MAP_SIZE);
+       if (dev->loop_id >= LOOPID_MAP_SIZE ||
+           qla2x00_is_reserved_id(vha, dev->loop_id)) {
+               dev->loop_id = FC_NO_LOOP_ID;
+               rval = QLA_FUNCTION_FAILED;
+       } else
+               set_bit(dev->loop_id, ha->loop_id_map);
 
-               /* ID in use. Try next value. */
-               dev->loop_id++;
+       spin_unlock_irqrestore(&ha->vport_slock, flags);
 
-               /* If wrap around. No free ID to use. */
-               if (dev->loop_id == first_loop_id) {
-                       dev->loop_id = FC_NO_LOOP_ID;
-                       rval = QLA_FUNCTION_FAILED;
-                       break;
-               }
-       }
+       if (rval == QLA_SUCCESS)
+               ql_dbg(ql_dbg_disc, dev->vha, 0x2086,
+                   "Assigning new loopid=%x, portid=%x.\n",
+                   dev->loop_id, dev->d_id.b24);
+       else
+               ql_log(ql_log_warn, dev->vha, 0x2087,
+                   "No loop_id's available, portid=%x.\n",
+                   dev->d_id.b24);
 
        return (rval);
 }
                        ha->isp_ops->fabric_logout(vha, fcport->loop_id,
                            fcport->d_id.b.domain, fcport->d_id.b.area,
                            fcport->d_id.b.al_pa);
-                       fcport->loop_id = FC_NO_LOOP_ID;
+                       qla2x00_clear_loop_id(fcport);
                        fcport->login_retry = 0;
 
                        rval = 3;
 
        return fcp;
 }
 
+static inline void
+qla2x00_set_reserved_loop_ids(struct qla_hw_data *ha)
+{
+       int i;
+
+       if (IS_FWI2_CAPABLE(ha))
+               return;
+
+       for (i = 0; i < SNS_FIRST_LOOP_ID; i++)
+               set_bit(i, ha->loop_id_map);
+       set_bit(MANAGEMENT_SERVER, ha->loop_id_map);
+       set_bit(BROADCAST, ha->loop_id_map);
+}
+
 static inline int
 qla2x00_is_reserved_id(scsi_qla_host_t *vha, uint16_t loop_id)
 {
            loop_id == MANAGEMENT_SERVER || loop_id == BROADCAST);
 }
 
+static inline void
+qla2x00_clear_loop_id(fc_port_t *fcport) {
+       struct qla_hw_data *ha = fcport->vha->hw;
+
+       if (fcport->loop_id == FC_NO_LOOP_ID ||
+           qla2x00_is_reserved_id(fcport->vha, fcport->loop_id))
+               return;
+
+       clear_bit(fcport->loop_id, ha->loop_id_map);
+       fcport->loop_id = FC_NO_LOOP_ID;
+}
+
 static inline void
 qla2x00_clean_dsd_pool(struct qla_hw_data *ha, srb_t *sp)
 {
 
 
        list_for_each_entry_safe(fcport, tfcport, &vha->vp_fcports, list) {
                list_del(&fcport->list);
+               qla2x00_clear_loop_id(fcport);
                kfree(fcport);
                fcport = NULL;
        }
        }
 
        INIT_LIST_HEAD(&ha->vp_list);
+
+       /* Allocate memory for our loop_id bitmap */
+       ha->loop_id_map = kzalloc(BITS_TO_LONGS(LOOPID_MAP_SIZE) * sizeof(long),
+           GFP_KERNEL);
+       if (!ha->loop_id_map)
+               goto fail_async_pd;
+       else {
+               qla2x00_set_reserved_loop_ids(ha);
+               ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0123,
+                   "loop_id_map=%p. \n", ha->loop_id_map);
+       }
+
        return 1;
 
 fail_async_pd:
        kfree(ha->nvram);
        kfree(ha->npiv_info);
        kfree(ha->swl);
+       kfree(ha->loop_id_map);
 
        ha->srb_mempool = NULL;
        ha->ctx_mempool = NULL;
                        }
 
                        if (fcport->login_retry == 0 && status != QLA_SUCCESS)
-                               fcport->loop_id = FC_NO_LOOP_ID;
+                               qla2x00_clear_loop_id(fcport);
                }
                if (test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags))
                        break;