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

📄 cciss.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 5 页
字号:
	ld_buff = kmalloc(sizeof(ReportLunData_struct), GFP_KERNEL);	if (ld_buff == NULL)	{		printk(KERN_ERR "cciss: out of memory\n");		return;	}	memset(ld_buff, 0, sizeof(ReportLunData_struct));	size_buff = kmalloc(sizeof( ReadCapdata_struct), GFP_KERNEL);        if (size_buff == NULL)        {                printk(KERN_ERR "cciss: out of memory\n");		kfree(ld_buff);                return;        }	inq_buff = kmalloc(sizeof( InquiryData_struct), GFP_KERNEL);        if (inq_buff == NULL)        {                printk(KERN_ERR "cciss: out of memory\n");                kfree(ld_buff);		kfree(size_buff);                return;        }	/* Get the firmware version */ 	return_code = sendcmd(CISS_INQUIRY, cntl_num, inq_buff, 		sizeof(InquiryData_struct), 0, 0 ,0 );	if (return_code == IO_OK)	{		hba[cntl_num]->firm_ver[0] = inq_buff->data_byte[32];		hba[cntl_num]->firm_ver[1] = inq_buff->data_byte[33];		hba[cntl_num]->firm_ver[2] = inq_buff->data_byte[34];		hba[cntl_num]->firm_ver[3] = inq_buff->data_byte[35];	} else /* send command failed */	{		printk(KERN_WARNING "cciss: unable to determine firmware"			" version of controller\n");	}	/* Get the number of logical volumes */ 	return_code = sendcmd(CISS_REPORT_LOG, cntl_num, ld_buff, 			sizeof(ReportLunData_struct), 0, 0, 0 );	if( return_code == IO_OK)	{#ifdef CCISS_DEBUG		printk("LUN Data\n--------------------------\n");#endif /* CCISS_DEBUG */ 		listlength |= (0xff & (unsigned int)(ld_buff->LUNListLength[0])) << 24;		listlength |= (0xff & (unsigned int)(ld_buff->LUNListLength[1])) << 16;		listlength |= (0xff & (unsigned int)(ld_buff->LUNListLength[2])) << 8;			listlength |= 0xff & (unsigned int)(ld_buff->LUNListLength[3]);	} else /* reading number of logical volumes failed */	{		printk(KERN_WARNING "cciss: report logical volume"			" command failed\n");		listlength = 0;	}	hba[cntl_num]->num_luns = listlength / 8; // 8 bytes pre entry	if (hba[cntl_num]->num_luns > CISS_MAX_LUN)	{		printk(KERN_ERR "ciss:  only %d number of logical volumes supported\n",			CISS_MAX_LUN);		hba[cntl_num]->num_luns = CISS_MAX_LUN;	}#ifdef CCISS_DEBUG	printk(KERN_DEBUG "Length = %x %x %x %x = %d\n", ld_buff->LUNListLength[0],		ld_buff->LUNListLength[1], ld_buff->LUNListLength[2],		ld_buff->LUNListLength[3],  hba[cntl_num]->num_luns);#endif /* CCISS_DEBUG */	for(i=0; i<  hba[cntl_num]->num_luns ; i++)	{	  	lunid = (0xff & (unsigned int)(ld_buff->LUN[i][3])) << 24;        	lunid |= (0xff & (unsigned int)(ld_buff->LUN[i][2])) << 16;        	lunid |= (0xff & (unsigned int)(ld_buff->LUN[i][1])) << 8;        	lunid |= 0xff & (unsigned int)(ld_buff->LUN[i][0]);		hba[cntl_num]->drv[i].LunID = lunid;#ifdef CCISS_DEBUG	  	printk(KERN_DEBUG "LUN[%d]:  %x %x %x %x = %x\n", i, 		ld_buff->LUN[i][0], ld_buff->LUN[i][1],ld_buff->LUN[i][2], 		ld_buff->LUN[i][3], hba[cntl_num]->drv[i].LunID);#endif /* CCISS_DEBUG */	  	memset(size_buff, 0, sizeof(ReadCapdata_struct));	  	return_code = sendcmd(CCISS_READ_CAPACITY, cntl_num, size_buff, 				sizeof( ReadCapdata_struct), 1, i, 0 );	  	if (return_code == IO_OK)		{			total_size = (0xff & 				(unsigned int)(size_buff->total_size[0])) << 24;			total_size |= (0xff & 				(unsigned int)(size_buff->total_size[1])) << 16;			total_size |= (0xff & 				(unsigned int)(size_buff->total_size[2])) << 8;			total_size |= (0xff & (unsigned int)				(size_buff->total_size[3])); 			total_size++; // command returns highest block address			block_size = (0xff & 				(unsigned int)(size_buff->block_size[0])) << 24;                	block_size |= (0xff & 				(unsigned int)(size_buff->block_size[1])) << 16;                	block_size |= (0xff & 				(unsigned int)(size_buff->block_size[2])) << 8;                	block_size |= (0xff & 				(unsigned int)(size_buff->block_size[3]));		} else /* read capacity command failed */ 		{			printk(KERN_WARNING "cciss: read capacity failed\n");			total_size = block_size = 0; 		}			printk(KERN_INFO "      blocks= %d block_size= %d\n", 					total_size, block_size);		/* Execute the command to read the disk geometry */		memset(inq_buff, 0, sizeof(InquiryData_struct));		return_code = sendcmd(CISS_INQUIRY, cntl_num, inq_buff,                	sizeof(InquiryData_struct), 1, i ,0xC1 );	  	if (return_code == IO_OK)		{			if(inq_buff->data_byte[8] == 0xFF)			{			   printk(KERN_WARNING "cciss: reading geometry failed, volume does not support reading geometry\n");                           hba[cntl_num]->drv[i].block_size = block_size;                           hba[cntl_num]->drv[i].nr_blocks = total_size;                           hba[cntl_num]->drv[i].heads = 255;                           hba[cntl_num]->drv[i].sectors = 32; // Sectors per track                           hba[cntl_num]->drv[i].cylinders = total_size / 255 / 32;                	} else			{		 	   hba[cntl_num]->drv[i].block_size = block_size;                           hba[cntl_num]->drv[i].nr_blocks = total_size;                           hba[cntl_num]->drv[i].heads = 					inq_buff->data_byte[6];                            hba[cntl_num]->drv[i].sectors = 					inq_buff->data_byte[7]; 			   hba[cntl_num]->drv[i].cylinders = 					(inq_buff->data_byte[4] & 0xff) << 8;			   hba[cntl_num]->drv[i].cylinders +=                                         inq_buff->data_byte[5];			}		}		else /* Get geometry failed */		{			printk(KERN_WARNING "cciss: reading geometry failed, continuing with default geometry\n"); 			hba[cntl_num]->drv[i].block_size = block_size;			hba[cntl_num]->drv[i].nr_blocks = total_size;			hba[cntl_num]->drv[i].heads = 255;			hba[cntl_num]->drv[i].sectors = 32; // Sectors per track 			hba[cntl_num]->drv[i].cylinders = total_size / 255 / 32;		}		printk(KERN_INFO "      heads= %d, sectors= %d, cylinders= %d\n\n",			hba[cntl_num]->drv[i].heads, 			hba[cntl_num]->drv[i].sectors,			hba[cntl_num]->drv[i].cylinders);	}	kfree(ld_buff);	kfree(size_buff);}	/* Function to find the first free pointer into our hba[] array *//* Returns -1 if no free entries are left.  */static int alloc_cciss_hba(void){	int i;	for(i=0; i< MAX_CTLR; i++)	{		if (hba[i] == NULL)		{			hba[i] = kmalloc(sizeof(ctlr_info_t), GFP_KERNEL);			if(hba[i]==NULL)			{				printk(KERN_ERR "cciss: out of memory.\n");				return (-1);			}			return (i);		}	}	printk(KERN_WARNING "cciss: This driver supports a maximum"		" of 8 controllers.\n");	return(-1);}static void free_hba(int i){	kfree(hba[i]);	hba[i]=NULL;}/* *  This is it.  Find all the controllers and register them.  I really hate *  stealing all these major device numbers. *  returns the number of block devices registered. */static int __init cciss_init_one(struct pci_dev *pdev,	const struct pci_device_id *ent){	request_queue_t *q;	int i;	int j;	printk(KERN_DEBUG "cciss: Device 0x%x has been found at"			" bus %d dev %d func %d\n",		pdev->device, pdev->bus->number, PCI_SLOT(pdev->devfn),			PCI_FUNC(pdev->devfn));	i = alloc_cciss_hba();	if( i < 0 ) 		return (-1);	memset(hba[i], 0, sizeof(ctlr_info_t));	if (cciss_pci_init(hba[i], pdev) != 0)	{		free_hba(i);		return (-1);	}	sprintf(hba[i]->devname, "cciss%d", i);	hba[i]->ctlr = i;	hba[i]->pdev = pdev;				if( register_blkdev(MAJOR_NR+i, hba[i]->devname, &cciss_fops))	{		printk(KERN_ERR "cciss:  Unable to get major number "			"%d for %s\n", MAJOR_NR+i, hba[i]->devname);		free_hba(i);		return(-1);	}	/* make sure the board interrupts are off */	hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_OFF);	if( request_irq(hba[i]->intr, do_cciss_intr, 		SA_INTERRUPT|SA_SHIRQ, hba[i]->devname, hba[i]))	{		printk(KERN_ERR "ciss: Unable to get irq %d for %s\n",			hba[i]->intr, hba[i]->devname);		unregister_blkdev( MAJOR_NR+i, hba[i]->devname);		free_hba(i);		return(-1);	}	hba[i]->cmd_pool_bits = (__u32*)kmalloc(        	((NR_CMDS+31)/32)*sizeof(__u32), GFP_KERNEL);	hba[i]->cmd_pool = (CommandList_struct *)pci_alloc_consistent(		hba[i]->pdev, NR_CMDS * sizeof(CommandList_struct), 		&(hba[i]->cmd_pool_dhandle));	hba[i]->errinfo_pool = (ErrorInfo_struct *)pci_alloc_consistent(		hba[i]->pdev, NR_CMDS * sizeof( ErrorInfo_struct), 		&(hba[i]->errinfo_pool_dhandle));	if((hba[i]->cmd_pool_bits == NULL) 		|| (hba[i]->cmd_pool == NULL)		|| (hba[i]->errinfo_pool == NULL))        {		if(hba[i]->cmd_pool_bits)                	kfree(hba[i]->cmd_pool_bits);                if(hba[i]->cmd_pool)                	pci_free_consistent(hba[i]->pdev,  				NR_CMDS * sizeof(CommandList_struct), 				hba[i]->cmd_pool, hba[i]->cmd_pool_dhandle);			if(hba[i]->errinfo_pool)			pci_free_consistent(hba[i]->pdev,				NR_CMDS * sizeof( ErrorInfo_struct),				hba[i]->errinfo_pool, 				hba[i]->errinfo_pool_dhandle);                free_irq(hba[i]->intr, hba[i]);                unregister_blkdev(MAJOR_NR+i, hba[i]->devname);		free_hba(i);                printk( KERN_ERR "cciss: out of memory");		return(-1);	}	/* Initialize the pdev driver private data. 		have it point to hba[i].  */	pci_set_drvdata(pdev, hba[i]);	/* command and error info recs zeroed out before 			they are used */        memset(hba[i]->cmd_pool_bits, 0, ((NR_CMDS+31)/32)*sizeof(__u32));#ifdef CCISS_DEBUG		printk(KERN_DEBUG "Scanning for drives on controller cciss%d\n",i);#endif /* CCISS_DEBUG */	cciss_getgeometry(i);	/* Turn the interrupts on so we can service requests */	hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_ON);	cciss_procinit(i);	q = BLK_DEFAULT_QUEUE(MAJOR_NR + i);        q->queuedata = hba[i];        blk_init_queue(q, do_cciss_request);        blk_queue_headactive(q, 0);			/* fill in the other Kernel structs */	blksize_size[MAJOR_NR+i] = hba[i]->blocksizes;        hardsect_size[MAJOR_NR+i] = hba[i]->hardsizes;        read_ahead[MAJOR_NR+i] = READ_AHEAD;	/* Set the pointers to queue functions */ 	q->back_merge_fn = cpq_back_merge_fn;        q->front_merge_fn = cpq_front_merge_fn;        q->merge_requests_fn = cpq_merge_requests_fn;	/* Fill in the gendisk data */ 		hba[i]->gendisk.major = MAJOR_NR + i;	hba[i]->gendisk.major_name = "cciss";	hba[i]->gendisk.minor_shift = NWD_SHIFT;	hba[i]->gendisk.max_p = MAX_PART;	hba[i]->gendisk.part = hba[i]->hd;	hba[i]->gendisk.sizes = hba[i]->sizes;	hba[i]->gendisk.nr_real = hba[i]->num_luns;	/* Get on the disk list */ 	add_gendisk(&(hba[i]->gendisk));	cciss_geninit(i);	for(j=0; j<NWD; j++)		register_disk(&(hba[i]->gendisk),			MKDEV(MAJOR_NR+i, j <<4), 			MAX_PART, &cciss_fops, 			hba[i]->drv[j].nr_blocks);	return(1);}static void __devexit cciss_remove_one (struct pci_dev *pdev){	ctlr_info_t *tmp_ptr;	int i;	if (pci_get_drvdata(pdev) == NULL)	{		printk( KERN_ERR "cciss: Unable to remove device \n");		return;	}	tmp_ptr = pci_get_drvdata(pdev);	i = tmp_ptr->ctlr;	if (hba[i] == NULL) 	{		printk(KERN_ERR "cciss: device appears to "			"already be removed \n");		return;	}	/* Turn board interrupts off */	hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_OFF);	free_irq(hba[i]->intr, hba[i]);	pci_set_drvdata(pdev, NULL);	iounmap((void*)hba[i]->vaddr);	unregister_blkdev(MAJOR_NR+i, hba[i]->devname);	remove_proc_entry(hba[i]->devname, proc_cciss);			/* remove it from the disk list */	del_gendisk(&(hba[i]->gendisk));	pci_free_consistent(hba[i]->pdev, NR_CMDS * sizeof(CommandList_struct), 		hba[i]->cmd_pool, hba[i]->cmd_pool_dhandle);	pci_free_consistent(hba[i]->pdev, NR_CMDS * sizeof( ErrorInfo_struct),		hba[i]->errinfo_pool, hba[i]->errinfo_pool_dhandle);	kfree(hba[i]->cmd_pool_bits);	free_hba(i);}	static struct pci_driver cciss_pci_driver = {	 name:   "cciss",	probe:  cciss_init_one,	remove:  __devexit_p(cciss_remove_one),	id_table:  cciss_pci_device_id, /* id_table */};/**  This is it.  Register the PCI driver information for the cards we control*  the OS will call our registered routines when it finds one of our cards. */int __init cciss_init(void){	printk(KERN_INFO DRIVER_NAME "\n");	/* Register for out PCI devices */	if (pci_register_driver(&cciss_pci_driver) > 0 )		return 0;	else 		return -ENODEV; }EXPORT_NO_SYMBOLS;static int __init init_cciss_module(void){	return ( cciss_init());}static void __exit cleanup_cciss_module(void){	int i;	pci_unregister_driver(&cciss_pci_driver);	/* double check that all controller entrys have been removed */	for (i=0; i< MAX_CTLR; i++) 	{		if (hba[i] != NULL)		{			printk(KERN_WARNING "cciss: had to remove"					" controller %d\n", i);			cciss_remove_one(hba[i]->pdev);		}	}	remove_proc_entry("cciss", proc_root_driver);}module_init(init_cciss_module);module_exit(cleanup_cciss_module);

⌨️ 快捷键说明

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