⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mptsas.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
		    "bitmask=0x%016llX\n", ioc->name, __FUNCTION__,		    port_details, i, port_details->num_phys,		    (unsigned long long)port_details->phy_bitmask));		dsaswideprintk(ioc, printk(MYIOC_s_DEBUG_FMT "\t\tport = %p rphy=%p\n",		    ioc->name, port_details->port, port_details->rphy));	}	dsaswideprintk(ioc, printk("\n"));	mutex_unlock(&ioc->sas_topology_mutex);}/** * csmisas_find_vtarget * * @ioc * @volume_id * @volume_bus * **/static VirtTarget *mptsas_find_vtarget(MPT_ADAPTER *ioc, u8 channel, u8 id){	struct scsi_device 		*sdev;	VirtDevice			*vdevice;	VirtTarget 			*vtarget = NULL;	shost_for_each_device(sdev, ioc->sh) {		if ((vdevice = sdev->hostdata) == NULL)			continue;		if (vdevice->vtarget->id == id &&		    vdevice->vtarget->channel == channel)			vtarget = vdevice->vtarget;	}	return vtarget;}/** * mptsas_target_reset * * Issues TARGET_RESET to end device using handshaking method * * @ioc * @channel * @id * * Returns (1) success *         (0) failure * **/static intmptsas_target_reset(MPT_ADAPTER *ioc, u8 channel, u8 id){	MPT_FRAME_HDR	*mf;	SCSITaskMgmt_t	*pScsiTm;	if ((mf = mpt_get_msg_frame(ioc->TaskCtx, ioc)) == NULL) {		dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames @%d!!\n",		    ioc->name,__FUNCTION__, __LINE__));		return 0;	}	/* Format the Request	 */	pScsiTm = (SCSITaskMgmt_t *) mf;	memset (pScsiTm, 0, sizeof(SCSITaskMgmt_t));	pScsiTm->TargetID = id;	pScsiTm->Bus = channel;	pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;	pScsiTm->TaskType = MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET;	pScsiTm->MsgFlags = MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION;	DBG_DUMP_TM_REQUEST_FRAME(ioc, (u32 *)mf);	mpt_put_msg_frame_hi_pri(ioc->TaskCtx, ioc, mf);	return 1;}/** * mptsas_target_reset_queue * * Receive request for TARGET_RESET after recieving an firmware * event NOT_RESPONDING_EVENT, then put command in link list * and queue if task_queue already in use. * * @ioc * @sas_event_data * **/static voidmptsas_target_reset_queue(MPT_ADAPTER *ioc,    EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data){	MPT_SCSI_HOST	*hd = shost_priv(ioc->sh);	VirtTarget *vtarget = NULL;	struct mptsas_target_reset_event *target_reset_list;	u8		id, channel;	id = sas_event_data->TargetID;	channel = sas_event_data->Bus;	if (!(vtarget = mptsas_find_vtarget(ioc, channel, id)))		return;	vtarget->deleted = 1; /* block IO */	target_reset_list = kzalloc(sizeof(*target_reset_list),	    GFP_ATOMIC);	if (!target_reset_list) {		dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, failed to allocate mem @%d..!!\n",		    ioc->name,__FUNCTION__, __LINE__));		return;	}	memcpy(&target_reset_list->sas_event_data, sas_event_data,		sizeof(*sas_event_data));	list_add_tail(&target_reset_list->list, &hd->target_reset_list);	if (hd->resetPending)		return;	if (mptsas_target_reset(ioc, channel, id)) {		target_reset_list->target_reset_issued = 1;		hd->resetPending = 1;	}}/** * mptsas_dev_reset_complete * * Completion for TARGET_RESET after NOT_RESPONDING_EVENT, * enable work queue to finish off removing device from upper layers. * then send next TARGET_RESET in the queue. * * @ioc * **/static voidmptsas_dev_reset_complete(MPT_ADAPTER *ioc){	MPT_SCSI_HOST	*hd = shost_priv(ioc->sh);        struct list_head *head = &hd->target_reset_list;	struct mptsas_target_reset_event *target_reset_list;	struct mptsas_hotplug_event *ev;	EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *sas_event_data;	u8		id, channel;	__le64		sas_address;	if (list_empty(head))		return;	target_reset_list = list_entry(head->next, struct mptsas_target_reset_event, list);	sas_event_data = &target_reset_list->sas_event_data;	id = sas_event_data->TargetID;	channel = sas_event_data->Bus;	hd->resetPending = 0;	/*	 * retry target reset	 */	if (!target_reset_list->target_reset_issued) {		if (mptsas_target_reset(ioc, channel, id)) {			target_reset_list->target_reset_issued = 1;			hd->resetPending = 1;		}		return;	}	/*	 * enable work queue to remove device from upper layers	 */	list_del(&target_reset_list->list);	ev = kzalloc(sizeof(*ev), GFP_ATOMIC);	if (!ev) {		dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, failed to allocate mem @%d..!!\n",		    ioc->name,__FUNCTION__, __LINE__));		return;	}	INIT_WORK(&ev->work, mptsas_hotplug_work);	ev->ioc = ioc;	ev->handle = le16_to_cpu(sas_event_data->DevHandle);	ev->parent_handle =	    le16_to_cpu(sas_event_data->ParentDevHandle);	ev->channel = channel;	ev->id =id;	ev->phy_id = sas_event_data->PhyNum;	memcpy(&sas_address, &sas_event_data->SASAddress,	    sizeof(__le64));	ev->sas_address = le64_to_cpu(sas_address);	ev->device_info = le32_to_cpu(sas_event_data->DeviceInfo);	ev->event_type = MPTSAS_DEL_DEVICE;	schedule_work(&ev->work);	kfree(target_reset_list);	/*	 * issue target reset to next device in the queue	 */	head = &hd->target_reset_list;	if (list_empty(head))		return;	target_reset_list = list_entry(head->next, struct mptsas_target_reset_event,	    list);	sas_event_data = &target_reset_list->sas_event_data;	id = sas_event_data->TargetID;	channel = sas_event_data->Bus;	if (mptsas_target_reset(ioc, channel, id)) {		target_reset_list->target_reset_issued = 1;		hd->resetPending = 1;	}}/** * mptsas_taskmgmt_complete * * @ioc * @mf * @mr * **/static intmptsas_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr){	mptsas_dev_reset_complete(ioc);	return mptscsih_taskmgmt_complete(ioc, mf, mr);}/** * mptscsih_ioc_reset * * @ioc * @reset_phase * **/static intmptsas_ioc_reset(MPT_ADAPTER *ioc, int reset_phase){	MPT_SCSI_HOST	*hd;	struct mptsas_target_reset_event *target_reset_list, *n;	int rc;	rc = mptscsih_ioc_reset(ioc, reset_phase);	if (ioc->bus_type != SAS)		goto out;	if (reset_phase != MPT_IOC_POST_RESET)		goto out;	if (!ioc->sh || !ioc->sh->hostdata)		goto out;	hd = shost_priv(ioc->sh);	if (!hd->ioc)		goto out;	if (list_empty(&hd->target_reset_list))		goto out;	/* flush the target_reset_list */	list_for_each_entry_safe(target_reset_list, n,	    &hd->target_reset_list, list) {		list_del(&target_reset_list->list);		kfree(target_reset_list);	} out:	return rc;}static intmptsas_sas_enclosure_pg0(MPT_ADAPTER *ioc, struct mptsas_enclosure *enclosure,		u32 form, u32 form_specific){	ConfigExtendedPageHeader_t hdr;	CONFIGPARMS cfg;	SasEnclosurePage0_t *buffer;	dma_addr_t dma_handle;	int error;	__le64 le_identifier;	memset(&hdr, 0, sizeof(hdr));	hdr.PageVersion = MPI_SASENCLOSURE0_PAGEVERSION;	hdr.PageNumber = 0;	hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;	hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_ENCLOSURE;	cfg.cfghdr.ehdr = &hdr;	cfg.physAddr = -1;	cfg.pageAddr = form + form_specific;	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;	cfg.dir = 0;	/* read */	cfg.timeout = 10;	error = mpt_config(ioc, &cfg);	if (error)		goto out;	if (!hdr.ExtPageLength) {		error = -ENXIO;		goto out;	}	buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,			&dma_handle);	if (!buffer) {		error = -ENOMEM;		goto out;	}	cfg.physAddr = dma_handle;	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;	error = mpt_config(ioc, &cfg);	if (error)		goto out_free_consistent;	/* save config data */	memcpy(&le_identifier, &buffer->EnclosureLogicalID, sizeof(__le64));	enclosure->enclosure_logical_id = le64_to_cpu(le_identifier);	enclosure->enclosure_handle = le16_to_cpu(buffer->EnclosureHandle);	enclosure->flags = le16_to_cpu(buffer->Flags);	enclosure->num_slot = le16_to_cpu(buffer->NumSlots);	enclosure->start_slot = le16_to_cpu(buffer->StartSlot);	enclosure->start_id = buffer->StartTargetID;	enclosure->start_channel = buffer->StartBus;	enclosure->sep_id = buffer->SEPTargetID;	enclosure->sep_channel = buffer->SEPBus; out_free_consistent:	pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,			    buffer, dma_handle); out:	return error;}static intmptsas_slave_configure(struct scsi_device *sdev){	if (sdev->channel == MPTSAS_RAID_CHANNEL)		goto out;	sas_read_port_mode_page(sdev); out:	return mptscsih_slave_configure(sdev);}static intmptsas_target_alloc(struct scsi_target *starget){	struct Scsi_Host *host = dev_to_shost(&starget->dev);	MPT_SCSI_HOST		*hd = shost_priv(host);	VirtTarget		*vtarget;	u8			id, channel;	struct sas_rphy		*rphy;	struct mptsas_portinfo	*p;	int 			 i;	MPT_ADAPTER		*ioc = hd->ioc;	vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);	if (!vtarget)		return -ENOMEM;	vtarget->starget = starget;	vtarget->ioc_id = ioc->id;	vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;	id = starget->id;	channel = 0;	/*	 * RAID volumes placed beyond the last expected port.	 */	if (starget->channel == MPTSAS_RAID_CHANNEL) {		for (i=0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++)			if (id == ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID)				channel = ioc->raid_data.pIocPg2->RaidVolume[i].VolumeBus;		goto out;	}	rphy = dev_to_rphy(starget->dev.parent);	mutex_lock(&ioc->sas_topology_mutex);	list_for_each_entry(p, &ioc->sas_topology, list) {		for (i = 0; i < p->num_phys; i++) {			if (p->phy_info[i].attached.sas_address !=					rphy->identify.sas_address)				continue;			id = p->phy_info[i].attached.id;			channel = p->phy_info[i].attached.channel;			mptsas_set_starget(&p->phy_info[i], starget);			/*			 * Exposing hidden raid components			 */			if (mptscsih_is_phys_disk(ioc, channel, id)) {				id = mptscsih_raid_id_to_num(ioc,						channel, id);				vtarget->tflags |=				    MPT_TARGET_FLAGS_RAID_COMPONENT;				p->phy_info[i].attached.phys_disk_num = id;			}			mutex_unlock(&ioc->sas_topology_mutex);			goto out;		}	}	mutex_unlock(&ioc->sas_topology_mutex);	kfree(vtarget);	return -ENXIO; out:	vtarget->id = id;	vtarget->channel = channel;	starget->hostdata = vtarget;	return 0;}static voidmptsas_target_destroy(struct scsi_target *starget){	struct Scsi_Host *host = dev_to_shost(&starget->dev);	MPT_SCSI_HOST		*hd = shost_priv(host);	struct sas_rphy		*rphy;	struct mptsas_portinfo	*p;	int 			 i;	MPT_ADAPTER *ioc = hd->ioc;	if (!starget->hostdata)		return;	if (starget->channel == MPTSAS_RAID_CHANNEL)		goto out;	rphy = dev_to_rphy(starget->dev.parent);	list_for_each_entry(p, &ioc->sas_topology, list) {		for (i = 0; i < p->num_phys; i++) {			if (p->phy_info[i].attached.sas_address !=					rphy->identify.sas_address)				continue;			mptsas_set_starget(&p->phy_info[i], NULL);			goto out;		}	} out:	kfree(starget->hostdata);	starget->hostdata = NULL;}static intmptsas_slave_alloc(struct scsi_device *sdev){	struct Scsi_Host	*host = sdev->host;	MPT_SCSI_HOST		*hd = shost_priv(host);	struct sas_rphy		*rphy;	struct mptsas_portinfo	*p;	VirtDevice		*vdevice;	struct scsi_target 	*starget;	int 			i;	MPT_ADAPTER *ioc = hd->ioc;	vdevice = kzalloc(sizeof(VirtDevice), GFP_KERNEL);	if (!vdevice) {		printk(MYIOC_s_ERR_FMT "slave_alloc kzalloc(%zd) FAILED!\n",				ioc->name, sizeof(VirtDevice));		return -ENOMEM;	}	starget = scsi_target(sdev);	vdevice->vtarget = starget->hostdata;	if (sdev->channel == MPTSAS_RAID_CHANNEL)		goto out;	rphy = dev_to_rphy(sdev->sdev_target->dev.parent);	mutex_lock(&ioc->sas_topology_mutex);	list_for_each_entry(p, &ioc->sas_topology, list) {		for (i = 0; i < p->num_phys; i++) {			if (p->phy_info[i].attached.sas_address !=					rphy->identify.sas_address)				continue;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -