📄 qla_cfg.c
字号:
current_path[sap->Lun] = bp->NewCurrentPathIndex; /* Release the update spinlock. */ old_path = qla2x00_find_path_by_id( dp, orig_id); new_path = qla2x00_find_path_by_id(dp, new_id); new_host = new_path->host; /* remap the lun */ qla2x00_map_a_oslun(new_host, dp, dp->dev_id, sap->Lun); qla2x00_send_failover_notify(dp, sap->Lun, old_path, new_path); } else { /* EMPTY */ DEBUG4(printk( "qla2x00_set_current_path: " "path index not changed.\n");) } } else { cmd->Status = EXT_STATUS_INVALID_PARAM; cmd->DetailStatus = EXT_DSTATUS_PATH_INDEX; rval = EINVAL; DEBUG4(printk("qla2x00_set_current_path: " "invalid index for device.\n");) } } else { cmd->Status = EXT_STATUS_DEV_NOT_FOUND; cmd->DetailStatus = EXT_DSTATUS_TARGET; rval = ENODEV; DEBUG4(printk("qla2x00_set_current_path: " "cannot find device.\n");) } clear_bit(CFG_ACTIVE, &ha->cfg_flags); } else { cmd->Status = EXT_STATUS_DEV_NOT_FOUND; cmd->DetailStatus = EXT_DSTATUS_HBA_INST; rval = ENODEV; DEBUG4(printk("qla2x00_set_current_path: " "cannot find adapter.\n");) } return rval;}#endif/* * MP SUPPORT ROUTINES *//* * qla2x00_add_mp_host * Add the specified host the host list. * * Input: * node_name = pointer to node name * * Returns: * * Context: * Kernel context. */mp_host_t *qla2x00_add_mp_host(uint8_t *node_name){ mp_host_t *host, *temp; host = (mp_host_t *) KMEM_ZALLOC(sizeof(mp_host_t), 1); if (host != NULL) { memcpy(host->nodename, node_name, WWN_SIZE); host->next = NULL; /* add to list */ if (mp_hosts_base == NULL) { mp_hosts_base = host; } else { temp = mp_hosts_base; while (temp->next != NULL) temp = temp->next; temp->next = host; } mp_num_hosts++; } return host;}/* * qla2x00_alloc_host * Allocate and initialize an mp host structure. * * Input: * ha = pointer to base driver's adapter structure. * * Returns: * Pointer to host structure or null on error. * * Context: * Kernel context. */mp_host_t *qla2x00_alloc_host(scsi_qla_host_t *ha){ mp_host_t *host, *temp; uint8_t *name, *portname; name = &ha->init_cb->node_name[0]; portname = &ha->init_cb->port_name[0]; ENTER("qla2x00_alloc_host"); host = (mp_host_t *) KMEM_ZALLOC(sizeof(mp_host_t), 2); if (host != NULL) { host->ha = ha; memcpy(host->nodename, name, WWN_SIZE); memcpy(host->portname, portname, WWN_SIZE); host->next = NULL; host->flags = MP_HOST_FLAG_NEEDS_UPDATE; host->instance = ha->instance; /* host->MaxLunsPerTarget = qla_fo_params.MaxLunsPerTarget; */ if (qla2x00_fo_enabled(host->ha, host->instance)) { host->flags |= MP_HOST_FLAG_FO_ENABLED; DEBUG4(printk("qla2x00_alloc_host: " "Failover enabled.\n");) } else { /* EMPTY */ DEBUG4(printk("qla2x00_alloc_host: " "Failover disabled.\n");) } /* add to list */ if (mp_hosts_base == NULL) { mp_hosts_base = host; } else { temp = mp_hosts_base; while (temp->next != NULL) temp = temp->next; temp->next = host; } mp_num_hosts++; DEBUG4(printk("Alloc host @ %p\n", host);) } else { /* EMPTY */ DEBUG4(printk("qla2x00_alloc_host: Failed\n");) } return host;}/* * qla2x00_add_portname_to_mp_dev * Add the specific port name to the list of port names for a * multi-path device. * * Input: * dp = pointer ti virtual device * portname = Port name to add to device * * Returns: * qla2x00 local function return status code. * * Context: * Kernel context. */static uint32_tqla2x00_add_portname_to_mp_dev(mp_device_t *dp, uint8_t *portname){ uint8_t index; uint32_t rval = QLA2X00_SUCCESS; ENTER("qla2x00_add_portname_to_mp_dev"); /* Look for an empty slot and add the specified portname. */ for (index = 0; index < MAX_NUMBER_PATHS; index++) { if (qla2x00_is_ww_name_zero(&dp->portnames[index][0])) { DEBUG4(printk("adding portname to dp = " "%p at index = %d\n", dp, index);) memcpy(&dp->portnames[index][0], portname, WWN_SIZE); break; } } if (index == MAX_NUMBER_PATHS) { rval = QLA2X00_FUNCTION_FAILED; DEBUG4(printk("qla2x00_add_portname_to_mp_dev: " "Fail no room\n");) } else { /* EMPTY */ DEBUG4(printk("qla2x00_add_portname_to_mp_dev: " "Exit OK\n");) } LEAVE("qla2x00_add_portname_to_mp_dev"); return rval;}/* * qla2x00_allocate_mp_dev * Allocate an fc_mp_dev, clear the memory, and log a system * error if the allocation fails. After fc_mp_dev is allocated * * Inputs: * nodename = pointer to nodename of new device * portname = pointer to portname of new device * * Returns: * Pointer to new mp_device_t, or NULL if the allocation fails. * * Context: * Kernel context. */static mp_device_t *qla2x00_allocate_mp_dev(uint8_t *nodename, uint8_t *portname){ mp_device_t *dp; /* Virtual device pointer */ ENTER("qla2x00_allocate_mp_dev"); dp = (mp_device_t *)KMEM_ZALLOC(sizeof(mp_device_t), 3); if (dp != NULL) { DEBUG3(printk("qla2x00_allocate_mp_dev: " "mp_device_t allocated at %p\n", dp);) /* * Copy node name into the mp_device_t. */ if (nodename) memcpy(dp->nodename, nodename, WWN_SIZE); /* * Since this is the first port, it goes at * index zero. */ if (portname) memcpy(&dp->portnames[0][0], portname, PORT_NAME_SIZE); /* Allocate an PATH_LIST for the fc_mp_dev. */ if ((dp->path_list = qla2x00_allocate_path_list()) == NULL) { DEBUG4(printk("qla2x00_allocate_mp_dev: " "allocate path_list Failed.\n");) KMEM_FREE(dp, sizeof(mp_device_t)); dp = NULL; } else { DEBUG4(printk("qla2x00_allocate_mp_dev: " "mp_path_list_t allocated at %p\n", dp->path_list);) /* EMPTY */ DEBUG4(printk("qla2x00_allocate_mp_dev: Exit Okay\n");) } } else { /* EMPTY */ DEBUG4(printk("qla2x00_allocate_mp_dev: Allocate failed.\n");) } LEAVE("qla2x00_allocate_mp_dev"); return dp;}/* * qla2x00_allocate_path * Allocate a PATH. * * Inputs: * host Host adapter for the device. * path_id path number * port port for device. * dev_id device number * * Returns: * Pointer to new PATH, or NULL if the allocation failed. * * Context: * Kernel context. */static mp_path_t *qla2x00_allocate_path(mp_host_t *host, uint16_t path_id, fc_port_t *port, uint16_t dev_id){ mp_path_t *path; uint16_t lun; ENTER("qla2x00_allocate_path"); path = (mp_path_t *) KMEM_ZALLOC(sizeof(mp_path_t), 4); if (path != NULL) { DEBUG3(printk("qla2x00_allocate_path: " "mp_path_t allocated at %p\n", path); ) /* Copy the supplied information into the MP_PATH. */ path->host = host; if (!(port->flags & FC_CONFIG) || port->loop_id != FC_NO_LOOP_ID) { path->port = port; } path->id = path_id; port->cur_path = path->id; path->mp_byte = port->mp_byte; path->next = NULL; memcpy(path->portname, port->port_name, WWN_SIZE); for (lun = 0; lun < MAX_LUNS; lun++) { path->lun_data.data[lun] |= LUN_DATA_ENABLED; } } else { /* EMPTY */ DEBUG4(printk("qla2x00_allocate_path: Failed\n");) } return path;}/* * qla2x00_allocate_path_list * Allocate a PATH_LIST * * Input: * None * * Returns: * Pointer to new PATH_LIST, or NULL if the allocation fails. * * Context: * Kernel context. */static mp_path_list_t *qla2x00_allocate_path_list( void ){ mp_path_list_t *path_list; uint16_t i; uint8_t l; path_list = (mp_path_list_t *) KMEM_ZALLOC(sizeof(mp_path_list_t), 5); if (path_list != NULL) { DEBUG4(printk("qla2x00_allocate_pathlist: " "allocated at %p\n", path_list);) path_list->visible = PATH_INDEX_INVALID; /* Initialized current path */ for (i = 0; i < MAX_LUNS_PER_DEVICE; i++) { l = (uint8_t)(i & 0xFF); path_list->current_path[l] = PATH_INDEX_INVALID; } path_list->last = NULL; } else { /* EMPTY */ DEBUG4(printk("Alloc pool failed for MP_PATH_LIST.\n");) } return path_list;}/* * qla2x00_cfg_find_host * Look through the existing multipath tree, and find * a host adapter to match the specified ha. * * Input: * ha = pointer to host adapter * * Return: * Pointer to new host, or NULL if no match found. * * Context: * Kernel context. */mp_host_t *qla2x00_cfg_find_host(scsi_qla_host_t *ha){ mp_host_t *host = NULL; /* Host found and null if not */ mp_host_t *tmp_host; ENTER("qla2x00_cfg_find_host"); for (tmp_host = mp_hosts_base; (tmp_host); tmp_host = tmp_host->next) { if (tmp_host->ha == ha) { host = tmp_host; DEBUG3(printk("Found host =%p, instance %d\n", host, host->instance);) break; } } LEAVE("qla2x00_cfg_find_host"); return host;}/* * qla2x00_find_host_by_name * Look through the existing multipath tree, and find * a host adapter to match the specified name. * * Input: * name = node name to match. * * Return: * Pointer to new host, or NULL if no match found. * * Context: * Kernel context. */mp_host_t *qla2x00_find_host_by_name(uint8_t *name){ mp_host_t *host; /* Host found and null if not */ for (host = mp_hosts_base; (host); host = host->next) { if (memcmp(host->nodename, name, WWN_SIZE) == 0) break; } return host;}/* * qla2x00_find_or_allocate_mp_dev * Look through the existing multipath control tree, and find * an mp_device_t with the supplied world-wide node name. If * one cannot be found, allocate one. * * Input: * host Adapter to add device to. * dev_id Index of device on adapter. * port port database information. * * Returns: * Pointer to new mp_device_t, or NULL if the allocation fails. * * Side Effects: * If the MP HOST does not already point to the mp_device_t, * a pointer is added at the proper port offset. * * Context: * Kernel context. */static mp_device_t *qla2x00_find_or_allocate_mp_dev(mp_host_t *host, uint16_t dev_id, fc_port_t *port){ mp_device_t *dp = NULL; /* pointer to multi-path device */ BOOL node_found; /* Found matching node name. */ BOOL port_found; /* Found matching port name. */ BOOL names_valid; /* Node name and port name are not zero */ mp_host_t *temp_host; /* pointer to temporary host */ uint16_t j; mp_device_t *temp_dp; ENTER("qla2x00_find_or_allocate_mp_dev"); DEBUG3(printk("(find_or_allocate_mp_dev): host =%p, " "port =%p, id = %d\n", host, port, dev_id);) temp_dp = qla2x00_find_mp_dev_by_id(host,dev_id); DEBUG3(printk("temp dp =%p\n", temp_dp);) /* if Device already known at this port. */ if (temp_dp != NULL) { 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("find_or_alloacte_dev: port " "exists in device %p\n", temp_dp);) dp = temp_dp; /* * Copy the LUN configuration data * into the mp_device_t. */ } } /* Sanity check the port information */ names_valid = (!qla2x00_is_ww_name_zero(port->node_name) && !qla2x00_is_ww_name_zero(port->port_name)); /* * If the optimized check failed, loop through each known * device on each known adapter looking for the node name. */ if (dp == NULL && names_valid) { DEBUG3(printk("Searching each adapter for the device...\n");) for (temp_host = mp_hosts_base; (temp_host); temp_host = temp_host->next) { /* Loop through each potential device on adapter. */ for (j = 0; j < MAX_MP_DEVICES; j++) { temp_dp = temp_host->mp_devs[j]; if (temp_dp == NULL) continue;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -