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

📄 qla_os.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
void qla2x00_remove_one(struct pci_dev *pdev){	scsi_qla_host_t *ha;	ha = pci_get_drvdata(pdev);	qla2x00_free_sysfs_attr(ha);	fc_remove_host(ha->host);	scsi_remove_host(ha->host);	qla2x00_free_device(ha);	scsi_host_put(ha->host);	pci_set_drvdata(pdev, NULL);}EXPORT_SYMBOL_GPL(qla2x00_remove_one);static voidqla2x00_free_device(scsi_qla_host_t *ha){	int ret;	/* Abort any outstanding IO descriptors. */	if (!IS_QLA2100(ha) && !IS_QLA2200(ha))		qla2x00_cancel_io_descriptors(ha);	/* Disable timer */	if (ha->timer_active)		qla2x00_stop_timer(ha);	/* Kill the kernel thread for this host */	if (ha->dpc_pid >= 0) {		ha->dpc_should_die = 1;		wmb();		ret = kill_proc(ha->dpc_pid, SIGHUP, 1);		if (ret) {			qla_printk(KERN_ERR, ha,			    "Unable to signal DPC thread -- (%d)\n", ret);			/* TODO: SOMETHING MORE??? */		} else {			wait_for_completion(&ha->dpc_exited);		}	}	/* Stop currently executing firmware. */	qla2x00_stop_firmware(ha);	/* turn-off interrupts on the card */	if (ha->interrupts_on)		ha->isp_ops.disable_intrs(ha);	qla2x00_mem_free(ha);	ha->flags.online = 0;	/* Detach interrupts */	if (ha->pdev->irq)		free_irq(ha->pdev->irq, ha);	/* release io space registers  */	if (ha->iobase)		iounmap(ha->iobase);	pci_release_regions(ha->pdev);	pci_disable_device(ha->pdev);}/* * qla2x00_mark_device_lost Updates fcport state when device goes offline. * * Input: ha = adapter block pointer.  fcport = port structure pointer. * * Return: None. * * Context: */void qla2x00_mark_device_lost(scsi_qla_host_t *ha, fc_port_t *fcport,    int do_login){	if (atomic_read(&fcport->state) == FCS_ONLINE && fcport->rport)		schedule_work(&fcport->rport_del_work);	/*	 * We may need to retry the login, so don't change the state of the	 * port but do the retries.	 */	if (atomic_read(&fcport->state) != FCS_DEVICE_DEAD)		atomic_set(&fcport->state, FCS_DEVICE_LOST);	if (!do_login)		return;	if (fcport->login_retry == 0) {		fcport->login_retry = ha->login_retry_count;		set_bit(RELOGIN_NEEDED, &ha->dpc_flags);		DEBUG(printk("scsi(%ld): Port login retry: "		    "%02x%02x%02x%02x%02x%02x%02x%02x, "		    "id = 0x%04x retry cnt=%d\n",		    ha->host_no,		    fcport->port_name[0],		    fcport->port_name[1],		    fcport->port_name[2],		    fcport->port_name[3],		    fcport->port_name[4],		    fcport->port_name[5],		    fcport->port_name[6],		    fcport->port_name[7],		    fcport->loop_id,		    fcport->login_retry));	}}/* * qla2x00_mark_all_devices_lost *	Updates fcport state when device goes offline. * * Input: *	ha = adapter block pointer. *	fcport = port structure pointer. * * Return: *	None. * * Context: */voidqla2x00_mark_all_devices_lost(scsi_qla_host_t *ha){	fc_port_t *fcport;	list_for_each_entry(fcport, &ha->fcports, list) {		if (fcport->port_type != FCT_TARGET)			continue;		/*		 * No point in marking the device as lost, if the device is		 * already DEAD.		 */		if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD)			continue;		if (atomic_read(&fcport->state) == FCS_ONLINE && fcport->rport)			schedule_work(&fcport->rport_del_work);		atomic_set(&fcport->state, FCS_DEVICE_LOST);	}}/** qla2x00_mem_alloc*      Allocates adapter memory.** Returns:*      0  = success.*      1  = failure.*/static uint8_tqla2x00_mem_alloc(scsi_qla_host_t *ha){	char	name[16];	uint8_t   status = 1;	int	retry= 10;	do {		/*		 * This will loop only once if everything goes well, else some		 * number of retries will be performed to get around a kernel		 * bug where available mem is not allocated until after a		 * little delay and a retry.		 */		ha->request_ring = dma_alloc_coherent(&ha->pdev->dev,		    (ha->request_q_length + 1) * sizeof(request_t),		    &ha->request_dma, GFP_KERNEL);		if (ha->request_ring == NULL) {			qla_printk(KERN_WARNING, ha,			    "Memory Allocation failed - request_ring\n");			qla2x00_mem_free(ha);			msleep(100);			continue;		}		ha->response_ring = dma_alloc_coherent(&ha->pdev->dev,		    (ha->response_q_length + 1) * sizeof(response_t),		    &ha->response_dma, GFP_KERNEL);		if (ha->response_ring == NULL) {			qla_printk(KERN_WARNING, ha,			    "Memory Allocation failed - response_ring\n");			qla2x00_mem_free(ha);			msleep(100);			continue;		}		ha->gid_list = dma_alloc_coherent(&ha->pdev->dev, GID_LIST_SIZE,		    &ha->gid_list_dma, GFP_KERNEL);		if (ha->gid_list == NULL) {			qla_printk(KERN_WARNING, ha,			    "Memory Allocation failed - gid_list\n");			qla2x00_mem_free(ha);			msleep(100);			continue;		}		ha->rlc_rsp = dma_alloc_coherent(&ha->pdev->dev,		    sizeof(rpt_lun_cmd_rsp_t), &ha->rlc_rsp_dma, GFP_KERNEL);		if (ha->rlc_rsp == NULL) {			qla_printk(KERN_WARNING, ha,				"Memory Allocation failed - rlc");			qla2x00_mem_free(ha);			msleep(100);			continue;		}		snprintf(name, sizeof(name), "qla2xxx_%ld", ha->host_no);		ha->s_dma_pool = dma_pool_create(name, &ha->pdev->dev,		    DMA_POOL_SIZE, 8, 0);		if (ha->s_dma_pool == NULL) {			qla_printk(KERN_WARNING, ha,			    "Memory Allocation failed - s_dma_pool\n");			qla2x00_mem_free(ha);			msleep(100);			continue;		}		/* get consistent memory allocated for init control block */		ha->init_cb = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL,		    &ha->init_cb_dma);		if (ha->init_cb == NULL) {			qla_printk(KERN_WARNING, ha,			    "Memory Allocation failed - init_cb\n");			qla2x00_mem_free(ha);			msleep(100);			continue;		}		memset(ha->init_cb, 0, ha->init_cb_size);		/* Get consistent memory allocated for Get Port Database cmd */		ha->iodesc_pd = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL,		    &ha->iodesc_pd_dma);		if (ha->iodesc_pd == NULL) {			/* error */			qla_printk(KERN_WARNING, ha,			    "Memory Allocation failed - iodesc_pd\n");			qla2x00_mem_free(ha);			msleep(100);			continue;		}		memset(ha->iodesc_pd, 0, PORT_DATABASE_SIZE);		/* Allocate ioctl related memory. */		if (qla2x00_alloc_ioctl_mem(ha)) {			qla_printk(KERN_WARNING, ha,			    "Memory Allocation failed - ioctl_mem\n");			qla2x00_mem_free(ha);			msleep(100);			continue;		}		if (qla2x00_allocate_sp_pool(ha)) {			qla_printk(KERN_WARNING, ha,			    "Memory Allocation failed - "			    "qla2x00_allocate_sp_pool()\n");			qla2x00_mem_free(ha);			msleep(100);			continue;		}		/* Allocate memory for SNS commands */		if (IS_QLA2100(ha) || IS_QLA2200(ha)) {			/* Get consistent memory allocated for SNS commands */			ha->sns_cmd = dma_alloc_coherent(&ha->pdev->dev,			    sizeof(struct sns_cmd_pkt), &ha->sns_cmd_dma,			    GFP_KERNEL);			if (ha->sns_cmd == NULL) {				/* error */				qla_printk(KERN_WARNING, ha,				    "Memory Allocation failed - sns_cmd\n");				qla2x00_mem_free(ha);				msleep(100);				continue;			}			memset(ha->sns_cmd, 0, sizeof(struct sns_cmd_pkt));		} else {			/* Get consistent memory allocated for MS IOCB */			ha->ms_iocb = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL,			    &ha->ms_iocb_dma);			if (ha->ms_iocb == NULL) {				/* error */				qla_printk(KERN_WARNING, ha,				    "Memory Allocation failed - ms_iocb\n");				qla2x00_mem_free(ha);				msleep(100);				continue;			}			memset(ha->ms_iocb, 0, sizeof(ms_iocb_entry_t));			/*			 * Get consistent memory allocated for CT SNS			 * commands			 */			ha->ct_sns = dma_alloc_coherent(&ha->pdev->dev,			    sizeof(struct ct_sns_pkt), &ha->ct_sns_dma,			    GFP_KERNEL);			if (ha->ct_sns == NULL) {				/* error */				qla_printk(KERN_WARNING, ha,				    "Memory Allocation failed - ct_sns\n");				qla2x00_mem_free(ha);				msleep(100);				continue;			}			memset(ha->ct_sns, 0, sizeof(struct ct_sns_pkt));		}		/* Done all allocations without any error. */		status = 0;	} while (retry-- && status != 0);	if (status) {		printk(KERN_WARNING			"%s(): **** FAILED ****\n", __func__);	}	return(status);}/** qla2x00_mem_free*      Frees all adapter allocated memory.** Input:*      ha = adapter block pointer.*/static voidqla2x00_mem_free(scsi_qla_host_t *ha){	struct list_head	*fcpl, *fcptemp;	fc_port_t	*fcport;	unsigned int	wtime;/* max wait time if mbx cmd is busy. */	if (ha == NULL) {		/* error */		DEBUG2(printk("%s(): ERROR invalid ha pointer.\n", __func__));		return;	}	/* Make sure all other threads are stopped. */	wtime = 60 * 1000;	while (ha->dpc_wait && wtime)		wtime = msleep_interruptible(wtime);	/* free ioctl memory */	qla2x00_free_ioctl_mem(ha);	/* free sp pool */	qla2x00_free_sp_pool(ha);	if (ha->sns_cmd)		dma_free_coherent(&ha->pdev->dev, sizeof(struct sns_cmd_pkt),		    ha->sns_cmd, ha->sns_cmd_dma);	if (ha->ct_sns)		dma_free_coherent(&ha->pdev->dev, sizeof(struct ct_sns_pkt),		    ha->ct_sns, ha->ct_sns_dma);	if (ha->ms_iocb)		dma_pool_free(ha->s_dma_pool, ha->ms_iocb, ha->ms_iocb_dma);	if (ha->iodesc_pd)		dma_pool_free(ha->s_dma_pool, ha->iodesc_pd, ha->iodesc_pd_dma);	if (ha->init_cb)		dma_pool_free(ha->s_dma_pool, ha->init_cb, ha->init_cb_dma);	if (ha->s_dma_pool)		dma_pool_destroy(ha->s_dma_pool);	if (ha->rlc_rsp)		dma_free_coherent(&ha->pdev->dev,		    sizeof(rpt_lun_cmd_rsp_t), ha->rlc_rsp,		    ha->rlc_rsp_dma);	if (ha->gid_list)		dma_free_coherent(&ha->pdev->dev, GID_LIST_SIZE, ha->gid_list,		    ha->gid_list_dma);	if (ha->response_ring)		dma_free_coherent(&ha->pdev->dev,		    (ha->response_q_length + 1) * sizeof(response_t),		    ha->response_ring, ha->response_dma);	if (ha->request_ring)		dma_free_coherent(&ha->pdev->dev,		    (ha->request_q_length + 1) * sizeof(request_t),		    ha->request_ring, ha->request_dma);	ha->sns_cmd = NULL;	ha->sns_cmd_dma = 0;	ha->ct_sns = NULL;	ha->ct_sns_dma = 0;	ha->ms_iocb = NULL;	ha->ms_iocb_dma = 0;	ha->iodesc_pd = NULL;	ha->iodesc_pd_dma = 0;	ha->init_cb = NULL;	ha->init_cb_dma = 0;	ha->s_dma_pool = NULL;	ha->rlc_rsp = NULL;	ha->rlc_rsp_dma = 0;	ha->gid_list = NULL;	ha->gid_list_dma = 0;	ha->response_ring = NULL;	ha->response_dma = 0;	ha->request_ring = NULL;	ha->request_dma = 0;	list_for_each_safe(fcpl, fcptemp, &ha->fcports) {		fcport = list_entry(fcpl, fc_port_t, list);		/* fc ports */		list_del_init(&fcport->list);		kfree(fcport);	}	INIT_LIST_HEAD(&ha->fcports);	if (ha->fw_dump)		free_pages((unsigned long)ha->fw_dump, ha->fw_dump_order);	vfree(ha->fw_dump24);	vfree(ha->fw_dump_buffer);	ha->fw_dump = NULL;	ha->fw_dump24 = NULL;	ha->fw_dumped = 0;	ha->fw_dump_reading = 0;	ha->fw_dump_buffer = NULL;}/* * qla2x00_allocate_sp_pool * 	 This routine is called during initialization to allocate *  	 memory for local srb_t. * * Input: *	 ha   = adapter block pointer. * * Context: *      Kernel context. * * Note: Sets the ref_count for non Null sp to one. */static intqla2x00_allocate_sp_pool(scsi_qla_host_t *ha){	int      rval;	rval = QLA_SUCCESS;	ha->srb_mempool = mempool_create(SRB_MIN_REQ, mempool_alloc_slab,	    mempool_free_slab, srb_cachep);	if (ha->srb_mempool == NULL) {		qla_printk(KERN_INFO, ha, "Unable to allocate SRB mempool.\n");		rval = QLA_FUNCTION_FAILED;	}	return (rval);}/* *  This routine frees all adapter allocated memory. * */static voidqla2x00_free_sp_pool( scsi_qla_host_t *ha){	if (ha->srb_mempool) {		mempool_destroy(ha->srb_mempool);		ha->srb_mempool = NULL;	}}/*************************************************************************** qla2x00_do_dpc*   This kernel thread is a task that is schedule by the interrupt handler*   to perform the background processing for interrupts.** Notes:* This task always run in the context of a kernel thread.  It* is kick-off by the driver's detect code and starts up

⌨️ 快捷键说明

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