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

📄 cciss.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 5 页
字号:
static int cpq_front_merge_fn(request_queue_t *q, struct request *rq,                             struct buffer_head *bh, int max_segments){        if (bh->b_data + bh->b_size == rq->bh->b_data)                return 1;        return cpq_new_segment(q, rq, max_segments);}static int cpq_merge_requests_fn(request_queue_t *q, struct request *rq,                                 struct request *nxt, int max_segments){        int total_segments = rq->nr_segments + nxt->nr_segments;        if (rq->bhtail->b_data + rq->bhtail->b_size == nxt->bh->b_data)                total_segments--;        if (total_segments > MAXSGENTRIES)                return 0;        rq->nr_segments = total_segments;        return 1;}/*  * Get a request and submit it to the controller.  * Currently we do one request at a time.  Ideally we would like to send * everything to the controller on the first call, but there is a danger * of holding the io_request_lock for to long.   */static void do_cciss_request(request_queue_t *q){	ctlr_info_t *h= q->queuedata; 	CommandList_struct *c;	int log_unit, start_blk, seg;	char *lastdataend;	struct buffer_head *bh;	struct list_head *queue_head = &q->queue_head;	struct request *creq;	u64bit temp64;	struct my_sg tmp_sg[MAXSGENTRIES];	int i;	if (q->plugged)		goto startio;queue_next:	if (list_empty(queue_head))		goto startio;	creq =	blkdev_entry_next_request(queue_head); 	if (creq->nr_segments > MAXSGENTRIES)                BUG();        if (h->ctlr != MAJOR(creq->rq_dev)-MAJOR_NR )        {                printk(KERN_WARNING "doreq cmd for %d, %x at %p\n",                                h->ctlr, creq->rq_dev, creq);                blkdev_dequeue_request(creq);                complete_buffers(creq->bh, 0);		end_that_request_last(creq);		goto startio;        }	if (( c = cmd_alloc(h, 1)) == NULL)		goto startio;	blkdev_dequeue_request(creq);	spin_unlock_irq(&io_request_lock);	c->cmd_type = CMD_RWREQ;      	bh = creq->bh;	c->rq = creq;		/* fill in the request */ 	log_unit = MINOR(creq->rq_dev) >> NWD_SHIFT; 	c->Header.ReplyQueue = 0;  // unused in simple mode	c->Header.Tag.lower = c->busaddr;  // use the physical address the cmd block for tag	c->Header.LUN.LogDev.VolId= hba[h->ctlr]->drv[log_unit].LunID;	c->Header.LUN.LogDev.Mode = 1;	c->Request.CDBLen = 10; // 12 byte commands not in FW yet;	c->Request.Type.Type =  TYPE_CMD; // It is a command. 	c->Request.Type.Attribute = ATTR_SIMPLE; 	c->Request.Type.Direction = 		(creq->cmd == READ) ? XFER_READ: XFER_WRITE; 	c->Request.Timeout = 0; // Don't time out		c->Request.CDB[0] = (creq->cmd == READ) ? CCISS_READ : CCISS_WRITE;	start_blk = hba[h->ctlr]->hd[MINOR(creq->rq_dev)].start_sect + creq->sector;#ifdef CCISS_DEBUG	if (bh == NULL)		panic("cciss: bh== NULL?");	printk(KERN_DEBUG "ciss: sector =%d nr_sectors=%d\n",(int) creq->sector,		(int) creq->nr_sectors);	#endif /* CCISS_DEBUG */	seg = 0; 	lastdataend = NULL;	while(bh)	{		if (bh->b_data == lastdataend)		{  // tack it on to the last segment 			tmp_sg[seg-1].len +=bh->b_size;			lastdataend += bh->b_size;		} else		{			if (seg == MAXSGENTRIES)				BUG();			tmp_sg[seg].len = bh->b_size;			tmp_sg[seg].start_addr = bh->b_data;			lastdataend = bh->b_data + bh->b_size;			seg++;		}		bh = bh->b_reqnext;	}	/* get the DMA records for the setup */ 	for (i=0; i<seg; i++)	{		c->SG[i].Len = tmp_sg[i].len;		temp64.val = (__u64) pci_map_single( h->pdev,			tmp_sg[i].start_addr,			tmp_sg[i].len,			(c->Request.Type.Direction == XFER_READ) ?                                 PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE);		c->SG[i].Addr.lower = temp64.val32.lower;                c->SG[i].Addr.upper = temp64.val32.upper;                c->SG[i].Ext = 0;  // we are not chaining	}	/* track how many SG entries we are using */ 	if( seg > h->maxSG)		h->maxSG = seg; #ifdef CCISS_DEBUG	printk(KERN_DEBUG "cciss: Submitting %d sectors in %d segments\n", creq->nr_sectors, seg);#endif /* CCISS_DEBUG */	c->Header.SGList = c->Header.SGTotal = seg;	c->Request.CDB[1]= 0;	c->Request.CDB[2]= (start_blk >> 24) & 0xff;	//MSB	c->Request.CDB[3]= (start_blk >> 16) & 0xff;	c->Request.CDB[4]= (start_blk >>  8) & 0xff;	c->Request.CDB[5]= start_blk & 0xff;	c->Request.CDB[6]= 0; // (sect >> 24) & 0xff; MSB	c->Request.CDB[7]= (creq->nr_sectors >>  8) & 0xff; 	c->Request.CDB[8]= creq->nr_sectors & 0xff; 	c->Request.CDB[9] = c->Request.CDB[11] = c->Request.CDB[12] = 0;	spin_lock_irq(&io_request_lock);	addQ(&(h->reqQ),c);	h->Qdepth++;	if(h->Qdepth > h->maxQsinceinit)		h->maxQsinceinit = h->Qdepth; 	goto queue_next;startio:	start_io(h);}static void do_cciss_intr(int irq, void *dev_id, struct pt_regs *regs){	ctlr_info_t *h = dev_id;	CommandList_struct *c;	unsigned long flags;	__u32 a, a1;	/* Is this interrupt for us? */	if ( h->access.intr_pending(h) == 0)		return;	/*	 * If there are completed commands in the completion queue,	 * we had better do something about it.	 */	spin_lock_irqsave(&io_request_lock, flags);	while( h->access.intr_pending(h))	{		while((a = h->access.command_completed(h)) != FIFO_EMPTY) 		{			a1 = a;			a &= ~3;			if ((c = h->cmpQ) == NULL)			{  				printk(KERN_WARNING "cciss: Completion of %08lx ignored\n", (unsigned long)a1);				continue;				} 			while(c->busaddr != a) {				c = c->next;				if (c == h->cmpQ) 					break;			}			/*			 * If we've found the command, take it off the			 * completion Q and free it			 */			 if (c->busaddr == a) {				removeQ(&h->cmpQ, c);				if (c->cmd_type == CMD_RWREQ) {					complete_command(c, 0);					cmd_free(h, c, 1);				} else if (c->cmd_type == CMD_IOCTL_PEND) {					c->cmd_type = CMD_IOCTL_DONE;				}				continue;			}		}	}	/*	 * See if we can queue up some more IO	 */	do_cciss_request(BLK_DEFAULT_QUEUE(MAJOR_NR + h->ctlr));	spin_unlock_irqrestore(&io_request_lock, flags);}/*  *  We cannot read the structure directly, for portablity we must use  *   the io functions. *   This is for debug only.  */#ifdef CCISS_DEBUGstatic void print_cfg_table( CfgTable_struct *tb){	int i;	char temp_name[17];	printk("Controller Configuration information\n");	printk("------------------------------------\n");	for(i=0;i<4;i++)		temp_name[i] = readb(&(tb->Signature[i]));	temp_name[4]='\0';	printk("   Signature = %s\n", temp_name); 	printk("   Spec Number = %d\n", readl(&(tb->SpecValence)));	printk("   Transport methods supported = 0x%x\n", 				readl(&(tb-> TransportSupport)));	printk("   Transport methods active = 0x%x\n", 				readl(&(tb->TransportActive)));	printk("   Requested transport Method = 0x%x\n", 			readl(&(tb->HostWrite.TransportRequest)));	printk("   Coalese Interrupt Delay = 0x%x\n", 			readl(&(tb->HostWrite.CoalIntDelay)));	printk("   Coalese Interrupt Count = 0x%x\n", 			readl(&(tb->HostWrite.CoalIntCount)));	printk("   Max outstanding commands = 0x%d\n", 			readl(&(tb->CmdsOutMax)));	printk("   Bus Types = 0x%x\n", readl(&(tb-> BusTypes)));	for(i=0;i<16;i++)		temp_name[i] = readb(&(tb->ServerName[i]));	temp_name[16] = '\0';	printk("   Server Name = %s\n", temp_name);	printk("   Heartbeat Counter = 0x%x\n\n\n", 			readl(&(tb->HeartBeat)));}#endif /* CCISS_DEBUG */ static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev){	ushort vendor_id, device_id, command;	unchar cache_line_size, latency_timer;	unchar irq, revision;	uint addr[6];	__u32 board_id;	int cfg_offset;	int cfg_base_addr;	int cfg_base_addr_index;	int i;	vendor_id = pdev->vendor;	device_id = pdev->device;	irq = pdev->irq;	for(i=0; i<6; i++)		addr[i] = pdev->resource[i].start;	if (pci_enable_device(pdev))	{		printk(KERN_ERR "cciss: Unable to Enable PCI device\n");		return( -1);	}	if (pci_set_dma_mask(pdev, CCISS_DMA_MASK ) != 0)	{		printk(KERN_ERR "cciss:  Unable to set DMA mask\n");		return(-1);	}		(void) pci_read_config_word(pdev, PCI_COMMAND,&command);	(void) pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);	(void) pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE,						&cache_line_size);	(void) pci_read_config_byte(pdev, PCI_LATENCY_TIMER,						&latency_timer);	(void) pci_read_config_dword(pdev, PCI_SUBSYSTEM_VENDOR_ID, 						&board_id);#ifdef CCISS_DEBUG	printk("vendor_id = %x\n", vendor_id);	printk("device_id = %x\n", device_id);	printk("command = %x\n", command);	for(i=0; i<6; i++)		printk("addr[%d] = %x\n", i, addr[i]);	printk("revision = %x\n", revision);	printk("irq = %x\n", irq);	printk("cache_line_size = %x\n", cache_line_size);	printk("latency_timer = %x\n", latency_timer);	printk("board_id = %x\n", board_id);#endif /* CCISS_DEBUG */ 	c->intr = irq;	/*	 * Memory base addr is first addr , the second points to the config         *   table	 */	c->paddr = addr[0] & 0xfffffff0; /* remove the addressing mode bits */#ifdef CCISS_DEBUG	printk("address 0 = %x\n", c->paddr);#endif /* CCISS_DEBUG */ 	c->vaddr = remap_pci_mem(c->paddr, 200);	/* get the address index number */	cfg_base_addr = readl(c->vaddr + SA5_CTCFG_OFFSET);	/* I am not prepared to deal with a 64 bit address value */	cfg_base_addr &= 0xffff;#ifdef CCISS_DEBUG	printk("cfg base address = %x\n", cfg_base_addr);#endif /* CCISS_DEBUG */	cfg_base_addr_index = (cfg_base_addr  - PCI_BASE_ADDRESS_0)/4;#ifdef CCISS_DEBUG	printk("cfg base address index = %x\n", cfg_base_addr_index);#endif /* CCISS_DEBUG */	cfg_offset = readl(c->vaddr + SA5_CTMEM_OFFSET);#ifdef CCISS_DEBUG	printk("cfg offset = %x\n", cfg_offset);#endif /* CCISS_DEBUG */	c->cfgtable = (CfgTable_struct *) 		remap_pci_mem((addr[cfg_base_addr_index] & 0xfffffff0)				+ cfg_offset, sizeof(CfgTable_struct));	c->board_id = board_id;#ifdef CCISS_DEBUG	print_cfg_table(c->cfgtable); #endif /* CCISS_DEBUG */	for(i=0; i<NR_PRODUCTS; i++) {		if (board_id == products[i].board_id) {			c->product_name = products[i].product_name;			c->access = *(products[i].access);			break;		}	}	if (i == NR_PRODUCTS) {		printk(KERN_WARNING "cciss: Sorry, I don't know how"			" to access the Smart Array controller %08lx\n", 				(unsigned long)board_id);		return -1;	}	if (  (readb(&c->cfgtable->Signature[0]) != 'C') ||	      (readb(&c->cfgtable->Signature[1]) != 'I') ||	      (readb(&c->cfgtable->Signature[2]) != 'S') ||	      (readb(&c->cfgtable->Signature[3]) != 'S') )	{		printk("Does not appear to be a valid CISS config table\n");		return -1;	}#ifdef CCISS_DEBUG	printk("Trying to put board into Simple mode\n");#endif /* CCISS_DEBUG */ 	c->max_commands = readl(&(c->cfgtable->CmdsOutMax));	/* Update the field, and then ring the doorbell */ 	writel( CFGTBL_Trans_Simple, 		&(c->cfgtable->HostWrite.TransportRequest));	writel( CFGTBL_ChangeReq, c->vaddr + SA5_DOORBELL);	for(i=0;i<MAX_CONFIG_WAIT;i++)	{		if (!(readl(c->vaddr + SA5_DOORBELL) & CFGTBL_ChangeReq))			break;		/* delay and try again */		udelay(1000);	}	#ifdef CCISS_DEBUG	printk(KERN_DEBUG "I counter got to %d %x\n", i, readl(c->vaddr + SA5_DOORBELL));#endif /* CCISS_DEBUG */#ifdef CCISS_DEBUG	print_cfg_table(c->cfgtable);	#endif /* CCISS_DEBUG */ 	if (!(readl(&(c->cfgtable->TransportActive)) & CFGTBL_Trans_Simple))	{		printk(KERN_WARNING "cciss: unable to get board into"					" simple mode\n");		return -1;	}	return 0;}/*  * Gets information about the local volumes attached to the controller.  */ static void cciss_getgeometry(int cntl_num){	ReportLunData_struct *ld_buff;	ReadCapdata_struct *size_buff;	InquiryData_struct *inq_buff;	int return_code;	int i;	int listlength = 0;	int lunid = 0;	int block_size;	int total_size; 

⌨️ 快捷键说明

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