📄 qla_cfg.c
字号:
node_found = qla2x00_is_nodename_equal( temp_dp->nodename, port->node_name); port_found = qla2x00_is_portname_in_device( temp_dp, port->port_name); if (node_found || port_found) { DEBUG3(printk("Matching device found " "at %p @ %d\n", temp_dp, j);) /* * If the node name matches but * the port name was not found, * add the port name to the list * of port names. */ if (!port_found) { qla2x00_add_portname_to_mp_dev( temp_dp, port->port_name); } /* * Set the flag that we have * found the device. */ dp = temp_dp; host->mp_devs[j] = dp; dp->use_cnt++; /* Fixme(dg) * Copy the LUN info into * the mp_device_t */ break; } } /* Break outer loop if inner loop succeeded. */ if (dp != NULL) break; } } /* If we couldn't find one, allocate one. */ if (dp == NULL && ((port->flags & FC_CONFIG) || !mp_config_required ) ) { dp = qla2x00_allocate_mp_dev(port->node_name, port->port_name); host->mp_devs[dev_id] = dp; dp->dev_id = dev_id; dp->use_cnt++; } LEAVE("qla2x00_allocate_mp_dev"); return dp;}/* * qla2x00_find_or_allocate_path * Look through the path list for the supplied device, and either * find the supplied adapter (path) for the adapter, or create * a new one and add it to the path list. * * Input: * host Adapter (path) for the device. * dp Device and path list for the device. * dev_id Index of device on adapter. * port Device data from port database. * * Returns: * Pointer to new PATH, or NULL if the allocation fails. * * Side Effects: * 1. If the PATH_LIST does not already point to the PATH, * a new PATH is added to the PATH_LIST. * 2. If the new path is found to be a second visible path, it is * marked as hidden, and the device database is updated to be * hidden as well, to keep the miniport synchronized. * * Context: * Kernel context. *//* ARGSUSED */static mp_path_t *qla2x00_find_or_allocate_path(mp_host_t *host, mp_device_t *dp, uint16_t dev_id, fc_port_t *port){ mp_path_list_t *path_list = dp->path_list; mp_path_t *path; uint8_t id; ENTER("qla2x00_find_or_allocate_path"); DEBUG4(printk("(find_or_allocate_path): host =%p, " "port =%p, dp=%p, dev id = %d\n", host, port, dp, dev_id);) /* * Loop through each known path in the path list. Look for * a PATH that matches both the adapter and the port name. */ path = qla2x00_find_path_by_name(host, path_list, port->port_name); if (path != NULL ) { DEBUG3(printk("(find_or_allocate_path): Found an existing " "path - host =%p, port =%p, path id = %d\n", host, path->port, path->id);) DEBUG3(printk("qla2x00_find_or_allocate_path: Luns " "for path_id %d, instance %d\n", path->id, host->instance);) DEBUG3(qla2x00_dump_buffer( (char *)&path->lun_data.data[0], 64);) /* If we found an existing path, look for any changes to it. */ if (path->port == NULL) { DEBUG3(printk("update path %p, path id= %d, " "mp_byte=0x%x port=%p\n", path, path->id, path->mp_byte, path->port);) path->port = port; port->mp_byte = path->mp_byte; } else { if ((path->mp_byte & MP_MASK_HIDDEN) && !(port->mp_byte & MP_MASK_HIDDEN)) { DEBUG3(printk("qla2x00_find_or_allocate_path: " "Adapter(%p) " "Device (%p) Path (%d) " "has become visible.\n", host, dp, path->id);) path->mp_byte &= ~MP_MASK_HIDDEN; } if (!(path->mp_byte & MP_MASK_HIDDEN) && (port->mp_byte & MP_MASK_HIDDEN)) { DEBUG3(printk("qla2x00_find_or_allocate_path: " "Adapter(%p) " "Device (%p) Path (%d) " "has become hidden.\n", host, dp, path->id);) path->mp_byte |= MP_MASK_HIDDEN; } } } else { /* * If we couldn't find an existing path, and there is still * room to add one, allocate one and put it in the list. */ if (path_list->path_cnt < MAX_PATHS_PER_DEVICE && path_list->path_cnt < qla_fo_params.MaxPathsPerDevice) { id = path_list->path_cnt; /* Update port with bitmask info */ path = qla2x00_allocate_path(host, id, port, dev_id); DEBUG3(printk("new path %p, path id= %d, " "mp_byte=0x%x port=%p\n", path, id, path->mp_byte, path->port);) qla2x00_add_path(path_list, path); /* Reconcile the new path against the existing ones. */ qla2x00_setup_new_path(dp, path); } else { /* EMPTY */ DEBUG4(printk("qla2x00_find_or_allocate_path: " "Err exit, no space to add path.\n");) } } LEAVE("qla2x00_find_or_allocate_path"); return path;}static uint32_tqla2x00_cfg_register_failover_lun(mp_device_t *dp, srb_t *sp, fc_lun_t *new_lp){ uint32_t status = QLA2X00_SUCCESS; os_tgt_t *tq; os_lun_t *lq; fc_lun_t *old_lp; DEBUG2(printk("qla2x00_send_failover_notify: " "NEW fclun = %p, sp = %p\n", new_lp, sp);) /* * Fix lun descriptors to point to new fclun which is a new fcport. */ if (new_lp == NULL) { DEBUG2(printk("qla2x00_send_failover_notify: " "Failed new lun %p\n", new_lp);) return QLA2X00_FUNCTION_FAILED; } tq = sp->tgt_queue; lq = sp->lun_queue; if (tq == NULL) { DEBUG2(printk("qla2x00_send_failover_notify: " "Failed to get old tq %p\n", tq);) return QLA2X00_FUNCTION_FAILED; } if (lq == NULL) { DEBUG2(printk("qla2x00_send_failover_notify: " "Failed to get old lq %p\n", lq);) return QLA2X00_FUNCTION_FAILED; } old_lp = lq->fclun; lq->fclun = new_lp; /* Log the failover to console */ printk(KERN_INFO "qla2x00: FAILOVER device %d from " "%02x%02x%02x%02x%02x%02x%02x%02x -> " "%02x%02x%02x%02x%02x%02x%02x%02x - " "LUN %02x, reason=0x%x\n", dp->dev_id, old_lp->fcport->port_name[0], old_lp->fcport->port_name[1], old_lp->fcport->port_name[2], old_lp->fcport->port_name[3], old_lp->fcport->port_name[4], old_lp->fcport->port_name[5], old_lp->fcport->port_name[6], old_lp->fcport->port_name[7], new_lp->fcport->port_name[0], new_lp->fcport->port_name[1], new_lp->fcport->port_name[2], new_lp->fcport->port_name[3], new_lp->fcport->port_name[4], new_lp->fcport->port_name[5], new_lp->fcport->port_name[6], new_lp->fcport->port_name[7], new_lp->lun, sp->err_id); printk(KERN_INFO "qla2x00: FROM HBA %d to HBA %d\n", (int)old_lp->fcport->ha->instance, (int)new_lp->fcport->ha->instance); DEBUG3(printk("qla2x00_send_failover_notify: " "NEW fclun = %p , port =%p, " "loop_id =0x%x, instance %ld\n", new_lp, new_lp->fcport, new_lp->fcport->loop_id, new_lp->fcport->ha->instance);) return status;}/* * qla2x00_send_failover_notify * A failover operation has just been done from an old path * index to a new index. Call lower level driver * to perform the failover notification. * * Inputs: * device Device being failed over. * lun LUN being failed over. * newpath path that was failed over too. * oldpath path that was failed over from. * * Return: * Local function status code. * * Context: * Kernel context. *//* ARGSUSED */static uint32_tqla2x00_send_failover_notify(mp_device_t *dp, uint8_t lun, mp_path_t *newpath, mp_path_t *oldpath){ fc_lun_t *old_lp, *new_lp; uint32_t status = QLA2X00_SUCCESS; ENTER("qla2x00_send_failover_notify"); old_lp = qla2x00_find_matching_lun(lun, oldpath); new_lp = qla2x00_find_matching_lun(lun, newpath); /* * If the target is the same target, but a new HBA has been selected, * send a third party logout if required. */ if ((qla_fo_params.FailoverNotifyType & FO_NOTIFY_TYPE_LOGOUT_OR_LUN_RESET || qla_fo_params.FailoverNotifyType & FO_NOTIFY_TYPE_LOGOUT_OR_CDB) && qla2x00_is_portname_equal( oldpath->portname, newpath->portname)) { status = qla2x00_send_fo_notification(old_lp, new_lp); if (status == QLA2X00_SUCCESS) { /* EMPTY */ DEBUG4(printk("qla2x00_send_failover_notify: " "Logout succeded\n");) } else { /* EMPTY */ DEBUG4(printk("qla2x00_send_failover_notify: " "Logout Failed\n");) } } else if ((qla_fo_params.FailoverNotifyType & FO_NOTIFY_TYPE_LUN_RESET) || (qla_fo_params.FailoverNotifyType & FO_NOTIFY_TYPE_LOGOUT_OR_LUN_RESET)) { /* * If desired, send a LUN reset as the * failover notification type. */ if (newpath->lun_data.data[lun] & LUN_DATA_ENABLED) { status = qla2x00_send_fo_notification(old_lp, new_lp); if (status == QLA2X00_SUCCESS) { /* EMPTY */ DEBUG4(printk("QLCallFailoverNotify: " "LUN reset succeeded.\n");) } else { /* EMPTY */ DEBUG4(printk("QLCallFailoverNotify: " "Failed reset LUN.\n");) } } } else if (qla_fo_params.FailoverNotifyType == FO_NOTIFY_TYPE_CDB || qla_fo_params.FailoverNotifyType == FO_NOTIFY_TYPE_LOGOUT_OR_CDB) { if (newpath->lun_data.data[lun] & LUN_DATA_ENABLED) { status = qla2x00_send_fo_notification(old_lp, new_lp); if (status == QLA2X00_SUCCESS) { /* EMPTY */ DEBUG4(printk("QLCallFailoverNotify: " "Send CDB succeeded.\n");) } else { /* EMPTY */ DEBUG4(printk("QLCallFailoverNotify: " "Send CDB Error " "lun=(%d).\n", lun);) } } } else { /* EMPTY */ DEBUG4(printk("QLCallFailoverNotify: failover " "disabled or no notify routine defined.\n");) } return status;}/* * qla2x00_select_next_path * A problem has been detected with the current path for this * device. Try to select the next available path as the current * path for this device. If there are no more paths, the same * path will still be selected. * * Inputs: * dp pointer of device structure. * lun LUN to failover. * * Return Value: * new path or same path * * Context: * Kernel context. */static mp_path_t *qla2x00_select_next_path(mp_host_t *host, mp_device_t *dp, uint8_t lun){ mp_path_t *path = NULL; mp_path_list_t *path_list; mp_path_t *orig_path; int id; uint32_t status; mp_host_t *new_host; ENTER("qla2x00_select_next_path:"); path_list = dp->path_list; if (path_list == NULL) return NULL; /* Get current path */ id = path_list->current_path[lun]; /* Get path for current path id */ if ((orig_path = qla2x00_find_path_by_id(dp, id)) != NULL) { /* select next path */ path = orig_path->next; new_host = path->host; /* FIXME may need to check for HBA being reset */ DEBUG3(printk("qla2x00_select_next_path: " "orig path = %p new path = %p " "curr idx = %d, new idx = %d\n", orig_path, path, orig_path->id, path->id);) DEBUG3(printk(" FAILOVER: device nodename: " "%02x%02x%02x%02x%02x%02x%02x%02x\n", dp->nodename[0], dp->nodename[1], dp->nodename[2], dp->nodename[3], dp->nodename[4], dp->nodename[5], dp->nodename[6], dp->nodename[7]);) DEBUG3(printk(" Original - host nodename: " "%02x%02x%02x%02x%02x%02x%02x%02x\n", orig_path->host->nodename[0], orig_path->host->nodename[1], orig_path->host->nodename[2], orig_path->host->nodename[3], orig_path->host->nodename[4], orig_path->host->nodename[5], orig_path->host->nodename[6], orig_path->host->nodename[7]);) DEBUG3(printk(" portname: " "%02x%02x%02x%02x%02x%02x%02x%02x\n", orig_path->port->port_name[0], orig_path->port->port_name[1], orig_path->port->port_name[2], orig_path->port->port_name[3], orig_path->port->port_name[4], orig_path->port->port_name[5], orig_path->port->port_name[6], orig_path->port->port_name[7]);) DEBUG3(printk(" New - host nodename: " "%02x%02x%02x%02x%02x%02x%02x%02x\n", new_host->nodename[0], new_host->nodename[1], new_host->nodename[2], new_host->nodename[3], new_host->nodename[4], new_host->nodename[5], new_host->nodename[6], new_host->nodename[7]);) DEBUG3(printk(" portname: " "%02x%02x%02x%02x%02x%02x%02x%02x\n", path->port->port_name[0], path->port->port_name[1], path->port->port_name[2], path->port->port_name[3], path->port->port_name[4], path->port->port_name[5], path->port->port_name[5], path->port->port_name[7]);) path_list->current_path[lun] = path->id; /* If we selected a new path, do failover notification. */ if (path != orig_path) { status = qla2x00_send_failover_notify( dp, lun, path, orig_path); /* * Currently we ignore the returned status from * the notify. however, if failover notify fails */ } } LEAVE("qla2x00_select_next_path:"); return path ;}/* * qla2x00_update_mp_host * Update the multipath control information from the port * database for that adapter. * * Input: * host Adapter to update. Devices that are new are * known to be attached to this adapter. * * Returns: * TRUE if updated successfully; FALSE if error. * */static BOOLqla2x00_update_mp_host( mp_host_t *host ){ BOOL success = TRUE; uint16_t dev_id; fc_port_t *port; scsi_qla_host_t *ha = host->ha; ENTER("qla2x00_update_mp_host"); /* * We make sure each port is attached to some virtual device. */ for (dev_id = 0, port = ha->fcport; (port); port = port->next, dev_id++) { success |= qla2x00_update_mp_device(host, port, dev_id); } if (success) { DEBUG2(printk("qla2x00_update_mp_host: Exit OK\n");) qla2x00_map_os_targets(host); } else { /* EMPTY */ DEBUG2(printk("qla2x00_update_mp_host: Exit FAILED\n");) } LEAVE("qla2x00_update_mp_host");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -