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

📄 iph5526.c

📁 h内核
💻 C
📖 第 1 页 / 共 5 页
字号:
		case INBOUND_MFS_COMPLETION:			DPRINTK("INBOUND_MFS_COMPLETION message received");			handle_MFS_interrupt(fi);			break;		case INBOUND_OOO_COMPLETION:			DPRINTK("INBOUND_OOO_COMPLETION message received");			handle_OOO_interrupt(fi);			break;		case INBOUND_SFS_COMPLETION:			DPRINTK("INBOUND_SFS_COMPLETION message received");			handle_SFS_interrupt(fi);			break;		case INBOUND_UNKNOWN_FRAME_I:			DPRINTK("INBOUND_UNKNOWN_FRAME message received");			handle_Unknown_Frame_interrupt(fi);			break;		case INBOUND_BUSIED_FRAME:			DPRINTK("INBOUND_BUSIED_FRAME message received");			handle_Busied_Frame_interrupt(fi);			break;		case FRAME_MGR_INTERRUPT:			DPRINTK("FRAME_MGR_INTERRUPT message received");			handle_FM_interrupt(fi);			break;		case READ_STATUS:			DPRINTK("READ_STATUS message received");			break;		case SFS_BUF_WARN:			DPRINTK("SFS_BUF_WARN message received");			handle_SFS_BUF_WARN_interrupt(fi);			break;		case MFS_BUF_WARN:			DPRINTK("MFS_BUF_WARN message received");			handle_MFS_BUF_WARN_interrupt(fi);			break;		case IMQ_BUF_WARN:			DPRINTK("IMQ_BUF_WARN message received");			handle_IMQ_BUF_WARN_interrupt(fi);			break;		case INBOUND_C1_TIMEOUT:			DPRINTK("INBOUND_C1_TIMEOUT message received");			break;		case BAD_SCSI_FRAME:			DPRINTK("BAD_SCSI_FRAME message received");			handle_Bad_SCSI_Frame_interrupt(fi);			break;		case INB_SCSI_STATUS_COMPLETION:			DPRINTK("INB_SCSI_STATUS_COMPL message received");			handle_Inbound_SCSI_Status_interrupt(fi);			break;		case INBOUND_SCSI_COMMAND:			DPRINTK("INBOUND_SCSI_COMMAND message received");			handle_Inbound_SCSI_Command_interrupt(fi);			break;		case INBOUND_SCSI_DATA_COMPLETION:			DPRINTK("INBOUND_SCSI_DATA message received");			/* Only for targets */			break;		default:					T_MSG("DEFAULT message received, type = %x", imq_int_type);			return;	}	reset_latch(fi);}static void handle_OCI_interrupt(struct fc_info *fi){u_int *ptr_imq_entry;u_long transaction_id = 0;unsigned short status, seq_count, transmitted_ox_id;struct Scsi_Host *host = fi->host;struct iph5526_hostdata *hostdata = (struct iph5526_hostdata *)host->hostdata;Scsi_Cmnd *Cmnd;u_int tag;	ENTER("handle_OCI_interrupt");	ptr_imq_entry = fi->q.ptr_imqe[fi->q.imq_cons_indx];	transaction_id = ntohl(*(ptr_imq_entry + 1));	status = ntohl(*(ptr_imq_entry + 2)) >> 16;	seq_count = ntohl(*(ptr_imq_entry + 3));	DPRINTK("transaction_id= %x", (u_int)transaction_id);	tag = transaction_id & 0xFFFF0000;	transmitted_ox_id = transaction_id;	/* The INT could be either due to TIME_OUT | BAD_ALPA. 	 * But we check only for TimeOuts. Bad AL_PA will 	 * caught by FM_interrupt handler. 	 */	if ((status == OCM_TIMEOUT_OR_BAD_ALPA) && (!fi->g.port_discovery) && (!fi->g.perform_adisc)){		DPRINTK("Frame TimeOut on OX_ID = %x", (u_int)transaction_id);		/* Is it a SCSI frame that is timing out ? Not a very good check... 		 */		if ((transmitted_ox_id <= MAX_SCSI_OXID) && ((tag == FC_SCSI_BAD_TARGET) || (tag < 0x00FF0000))) {			/* If it is a Bad AL_PA, we report it as BAD_TARGET.			 * Else, we allow the command to time-out. A Link			 * re-initialization could be taking place.			 */			if (tag == FC_SCSI_BAD_TARGET) {				Cmnd = hostdata->cmnd_handler[transmitted_ox_id & MAX_SCSI_XID];				hostdata->cmnd_handler[transmitted_ox_id & MAX_SCSI_XID] = NULL;				if (Cmnd != NULL) {					Cmnd->result = DID_BAD_TARGET << 16;					(*Cmnd->scsi_done) (Cmnd);				}				else					T_MSG("NULL Command out of handler!");			} /* if Bad Target */			else {			u_char missing_target = tag >> 16;			struct fc_node_info *q = fi->node_info_list;				/* A Node that we thought was logged in has gone				 * away. We are the optimistic kind and we keep				 * hoping that our dear little Target will come back				 * to us. For now we log him out.				 */				DPRINTK2("Missing Target = %d", missing_target);				while (q != NULL) {					if (q->target_id == missing_target) {						T_MSG("Target %d Logged out", q->target_id);						q->login = LOGIN_ATTEMPTED;						if (fi->num_nodes > 0)							fi->num_nodes--;						tx_logi(fi, ELS_PLOGI, q->d_id);						break;					}					else						q = q->next;				}			}		} /* End of SCSI frame timing out. */		else {			if (seq_count > 1) {				/* An IP frame was transmitted to a Bad AL_PA. Free up			 	 * the skb used.			 	 */				dev_kfree_skb_irq((struct sk_buff *)(bus_to_virt(transaction_id)));				netif_wake_queue(fi->dev);			}		} /* End of IP frame timing out. */	} /* End of frame timing out. */	else {		/* Frame was transmitted successfully. Check if it was an ELS		 * frame or an IP frame or a Bad_Target_Notification frame (in		 * case of a ptp_link). Ugly!		 */		if ((status == 0) && (seq_count == 0)) {		u_int tag = transaction_id & 0xFFFF0000;		/* Continue with port discovery after an ELS is successfully 		 * transmitted. (status == 0). 		 */			DPRINTK("tag = %x", tag);			switch(tag) {				case ELS_FLOGI:					/* Letz use the Name Server instead */					fi->g.explore_fabric = TRUE;					fi->g.port_discovery = FALSE;					fi->g.alpa_list_index = MAX_NODES;					add_to_ox_id_list(fi, transaction_id, tag);					break;				case ELS_PLOGI:					if (fi->g.fabric_present && (fi->g.name_server == FALSE))						add_to_ox_id_list(fi,transaction_id,ELS_NS_PLOGI);					else						add_to_ox_id_list(fi, transaction_id, tag);					break;				case FC_SCSI_BAD_TARGET:					Cmnd = hostdata->cmnd_handler[transmitted_ox_id & MAX_SCSI_XID];					hostdata->cmnd_handler[transmitted_ox_id & MAX_SCSI_XID] = NULL;					if (Cmnd != NULL) {						Cmnd->result = DID_BAD_TARGET << 16;						(*Cmnd->scsi_done) (Cmnd);					}					else						T_MSG("NULL Command out of handler!");					break;				default:					add_to_ox_id_list(fi, transaction_id, tag);			}					if (fi->g.alpa_list_index >= MAX_NODES) {				if (fi->g.port_discovery == TRUE) {					fi->g.port_discovery = FALSE;					add_display_cache_timer(fi);				}				fi->g.alpa_list_index = MAX_NODES;			}			if (fi->g.port_discovery == TRUE) 				local_port_discovery(fi);		}		else {			/* An IP frame has been successfully transmitted.			 * Free the skb that was used for this IP frame.			 */			if ((status == 0) && (seq_count > 1)) {				dev_kfree_skb_irq((struct sk_buff *)(bus_to_virt(transaction_id)));				netif_wake_queue(fi->dev);			}		}	}	LEAVE("handle_OCI_interrupt");}/* Right now we discard OOO frames */static void handle_OOO_interrupt(struct fc_info *fi){u_int *ptr_imq_entry;int queue_indx, offset, payload_size;int no_of_buffers = 1; /* header is in a separate buffer */	ptr_imq_entry = fi->q.ptr_imqe[fi->q.imq_cons_indx];	offset = ntohl(*(ptr_imq_entry + 1)) & 0x00000007;	queue_indx = ntohl(*(ptr_imq_entry + 1)) & 0xFFFF0000;	queue_indx = queue_indx >> 16;	payload_size = ntohl(*(ptr_imq_entry + 2)) - TACHYON_HEADER_LEN;	/* Calculate total number of buffers */	no_of_buffers += payload_size / MFS_BUFFER_SIZE;	if (payload_size % MFS_BUFFER_SIZE)		no_of_buffers++;	/* provide Tachyon will another set of buffers */	fi->g.mfs_buffer_count += no_of_buffers;	if (fi->g.mfs_buffer_count >= NO_OF_ENTRIES) {	int count = fi->g.mfs_buffer_count / NO_OF_ENTRIES;		fi->g.mfs_buffer_count -= NO_OF_ENTRIES * count;		update_MFSBQ_indx(fi, count);	}}static void handle_MFS_interrupt(struct fc_info *fi){u_int *ptr_imq_entry, *buff_addr;u_int type_of_frame, s_id;int queue_indx, offset, payload_size, starting_indx, starting_offset;u_short received_ox_id;int no_of_buffers = 1; /* header is in a separate buffer */struct sk_buff *skb;int wrap_around = FALSE, no_of_wrap_buffs = NO_OF_ENTRIES - 1;	ENTER("handle_MFS_interrupt");	ptr_imq_entry = fi->q.ptr_imqe[fi->q.imq_cons_indx];	offset = ntohl(*(ptr_imq_entry + 1)) & 0x00000007;	queue_indx = ntohl(*(ptr_imq_entry + 1)) & 0xFFFF0000;	queue_indx = queue_indx >> 16;	DPRINTK("queue_indx = %d, offset  = %d\n", queue_indx, offset);	payload_size = ntohl(*(ptr_imq_entry + 2)) - TACHYON_HEADER_LEN;	DPRINTK("payload_size = %d", payload_size);	/* Calculate total number of buffers */	no_of_buffers += payload_size / MFS_BUFFER_SIZE;	if (payload_size % MFS_BUFFER_SIZE)		no_of_buffers++;	DPRINTK("no_of_buffers = %d", no_of_buffers);	if ((no_of_buffers - 1) <= offset) {		starting_offset = offset - (no_of_buffers - 1);		starting_indx = queue_indx;	}	else {	int temp = no_of_buffers - (offset + 1);	int no_of_queues = temp / NO_OF_ENTRIES;		starting_offset = temp % NO_OF_ENTRIES;		if (starting_offset != 0) {			no_of_wrap_buffs = starting_offset - 1; //exclude header			starting_offset = NO_OF_ENTRIES - starting_offset;			no_of_queues++;		}		starting_indx = queue_indx - no_of_queues;		if (starting_indx < 0) {			no_of_wrap_buffs -= (starting_indx + 1) * NO_OF_ENTRIES; 			starting_indx = MFSBQ_LENGTH + starting_indx;			wrap_around = TRUE;		}	}		DPRINTK("starting_indx = %d, starting offset = %d no_of_wrap_buffs = %d\n", starting_indx, starting_offset, no_of_wrap_buffs);	/* Get Tachyon Header from first buffer */	buff_addr = bus_to_virt(ntohl(*(fi->q.ptr_mfsbq_base + starting_indx*NO_OF_ENTRIES + starting_offset)));		/* extract Type of Frame */	type_of_frame = (u_int)ntohl(*(buff_addr + 4)) & 0xFF000000;	s_id = (u_int)ntohl(*(buff_addr + 3)) & 0x00FFFFFF;	received_ox_id = ntohl(*(buff_addr + 6)) >> 16;	buff_addr += MFS_BUFFER_SIZE/4;	DPRINTK("type_of_frame = %x, s_id = %x, ox_id = %x", type_of_frame, s_id, received_ox_id); 	switch(type_of_frame) {	  case TYPE_LLC_SNAP:		skb = dev_alloc_skb(payload_size);		if (skb == NULL) {			printk(KERN_NOTICE "%s: In handle_MFS_interrupt() Memory squeeze, dropping packet.\n", fi->name);			fi->fc_stats.rx_dropped++;			fi->g.mfs_buffer_count += no_of_buffers;			if (fi->g.mfs_buffer_count >= NO_OF_ENTRIES) {				int count = fi->g.mfs_buffer_count / NO_OF_ENTRIES;				fi->g.mfs_buffer_count -= NO_OF_ENTRIES * count;				update_MFSBQ_indx(fi, count);			}			return;		}		if (wrap_around) {		int wrap_size = no_of_wrap_buffs * MFS_BUFFER_SIZE;		int tail_size = payload_size - wrap_size;			DPRINTK("wrap_size = %d, tail_size = %d\n", wrap_size, tail_size);			if (no_of_wrap_buffs) 				memcpy(skb_put(skb, wrap_size), buff_addr, wrap_size);			buff_addr = bus_to_virt(ntohl(*(fi->q.ptr_mfsbq_base)));			memcpy(skb_put(skb, tail_size), buff_addr, tail_size);		}		else			memcpy(skb_put(skb, payload_size), buff_addr, payload_size);		rx_net_mfs_packet(fi, skb);	  	break;	default:		T_MSG("Unknown Frame Type received. Type = %x", type_of_frame);	}	/* provide Tachyon will another set of buffers */	fi->g.mfs_buffer_count += no_of_buffers;	if (fi->g.mfs_buffer_count >= NO_OF_ENTRIES) {	int count = fi->g.mfs_buffer_count / NO_OF_ENTRIES;		fi->g.mfs_buffer_count -= NO_OF_ENTRIES * count;		update_MFSBQ_indx(fi, count);	}	LEAVE("handle_MFS_interrupt");}static void handle_Unknown_Frame_interrupt(struct fc_info *fi){u_int *ptr_imq_entry;int queue_indx, offset;	ENTER("handle_Unknown_Frame_interrupt");	ptr_imq_entry = fi->q.ptr_imqe[fi->q.imq_cons_indx];	offset = ntohl(*(ptr_imq_entry + 1)) & 0x00000007;	queue_indx = ntohl(*(ptr_imq_entry + 1)) & 0xFFFF0000;	queue_indx = queue_indx >> 16;	/* We discard the "unknown" frame */	/* provide Tachyon will another set of buffers */	if (offset == (NO_OF_ENTRIES - 1))		update_SFSBQ_indx(fi);	LEAVE("handle_Unknown_Frame_interrupt");}static void handle_Busied_Frame_interrupt(struct fc_info *fi){u_int *ptr_imq_entry;int queue_indx, offset;	ENTER("handle_Busied_Frame_interrupt");	ptr_imq_entry = fi->q.ptr_imqe[fi->q.imq_cons_indx];	offset = ntohl(*(ptr_imq_entry + 1)) & 0x00000007;	queue_indx = ntohl(*(ptr_imq_entry + 1)) & 0xFFFF0000;	queue_indx = queue_indx >> 16;	/* We discard the "busied" frame */	/* provide Tachyon will another set of buffers */	if (offset == (NO_OF_ENTRIES - 1))		update_SFSBQ_indx(fi);	LEAVE("handle_Busied_Frame_interrupt");}static void handle_Bad_SCSI_Frame_interrupt(struct fc_info *fi){u_int *ptr_imq_entry, *buff_addr, *tach_header, *ptr_edb;u_int s_id, rctl, frame_class, burst_len, transfered_len, len = 0;int queue_indx, offset, payload_size, i;u_short ox_id, rx_id, x_id, mtu = 512;u_char target_id = 0xFF;	ENTER("handle_Bad_SCSI_Frame_interrupt");	ptr_imq_entry = fi->q.ptr_imqe[fi->q.imq_cons_indx];	offset = ntohl(*(ptr_imq_entry + 1)) & 0x00000007;	queue_indx = ntohl(*(ptr_imq_entry + 1)) & 0xFFFF0000;	queue_indx = queue_indx >> 16;	payload_size = ntohl(*(ptr_imq_entry + 2));	buff_addr = bus_to_virt(ntohl(*(fi->q.ptr_sfsbq_base + queue_indx*NO_OF_ENTRIES + offset)));	rctl = ntohl(*(buff_addr + 2)) & 0xFF000000;	s_id = ntohl(*(buff_addr + 3)) & 0x00FFFFFF;	ox_id = ntohl(*(buff_addr + 6)) >> 16;	rx_id = ntohl(*(buff_addr + 6));	x_id = ox_id & MAX_SCSI_XID;	/* Any frame that comes in with OX_ID that matches an OX_ID 

⌨️ 快捷键说明

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