Enscript Output

extractedLnx/linux-2.6.9/drivers/net/fc/iph5526.c_handle_SFS_interrupt.c

static void handle_SFS_interrupt(struct fc_info *fi)
{
u_int *ptr_imq_entry, *buff_addr;
u_int class_of_frame, type_of_frame, s_id, els_type = 0, rctl;
int queue_indx, offset, payload_size, login_state;
u_short received_ox_id, fs_cmnd_code;
	ENTER("handle_SFS_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));
	DPRINTK("payload_size = %d", payload_size);

	buff_addr = bus_to_virt(ntohl(*(fi->q.ptr_sfsbq_base + queue_indx*NO_OF_ENTRIES + offset)));

	/* extract Type of Frame */
	type_of_frame = ntohl(*(buff_addr + 4)) & 0xFF000000;
	s_id = ntohl(*(buff_addr + 3)) & 0x00FFFFFF;
	received_ox_id = ntohl(*(buff_addr + 6)) >> 16;
	switch(type_of_frame) {
		case TYPE_BLS:
			rctl = ntohl(*(buff_addr + 2)) & 0xFF000000;
			switch(rctl) {
				case RCTL_BASIC_ABTS:
					/* As an Initiator, we should never be receiving 
					 * this.
		 			 */
					DPRINTK1("ABTS received from S_ID 0x%x with OX_ID = %x", s_id, received_ox_id);
					break;
			}
			break;
		case TYPE_ELS:
			class_of_frame = ntohl(*(buff_addr + 8));
			login_state = sid_logged_in(fi, s_id);
			switch(class_of_frame & 0xFF000000) {
				case ELS_PLOGI:
					if (s_id != fi->g.my_id) {
						u_int ret_code;
						DPRINTK1("PLOGI received from D_ID 0x%x with 0X_ID = %x", s_id, received_ox_id);
						if ((ret_code = plogi_ok(fi, buff_addr, payload_size)) == 0){
							tx_logi_acc(fi, ELS_ACC, s_id, received_ox_id);
							add_to_address_cache(fi, buff_addr);
						}
						else {
							u_short cmnd_code = ret_code >> 16;
							u_short expln_code =  ret_code;
							tx_ls_rjt(fi, s_id, received_ox_id, cmnd_code, expln_code);
						}
					}
					break;
				case ELS_ACC:
					els_type = remove_from_ox_id_list(fi, received_ox_id);
					DPRINTK1("ELS_ACC received from D_ID 0x%x in response to ELS %x", s_id, els_type);
					switch(els_type) {
						case ELS_PLOGI:
							add_to_address_cache(fi, buff_addr);
							tx_prli(fi, ELS_PRLI, s_id, OX_ID_FIRST_SEQUENCE);
							break;
						case ELS_FLOGI:
							add_to_address_cache(fi, buff_addr);
							fi->g.my_id = ntohl(*(buff_addr + 2)) & 0x00FFFFFF;
							fi->g.fabric_present = TRUE;
							fi->g.my_ddaa = fi->g.my_id & 0xFFFF00;
							/* Login to the Name Server 
							 */
							tx_logi(fi, ELS_PLOGI, DIRECTORY_SERVER); 
							break;
						case ELS_NS_PLOGI:
							fi->g.name_server = TRUE;
							add_to_address_cache(fi, buff_addr);
							tx_name_server_req(fi, FCS_RFC_4);
							tx_scr(fi);
							/* Some devices have a delay before 
							 * registering with the Name Server 
							 */
							udelay(500); 
							tx_name_server_req(fi, FCS_GP_ID4);
							break;
						case ELS_PRLI:
							mark_scsi_sid(fi, buff_addr, ADD_ENTRY);
							break;
						case ELS_ADISC:
							if (!(validate_login(fi, buff_addr)))
								tx_logo(fi, s_id, OX_ID_FIRST_SEQUENCE);
							break;
					}
					break;
				case ELS_PDISC:
					DPRINTK1("ELS_PDISC received from D_ID 0x%x", s_id);
					tx_logo(fi, s_id, received_ox_id);
					break;
				case ELS_ADISC:
					DPRINTK1("ELS_ADISC received from D_ID 0x%x", s_id);
					if (node_logged_in_prev(fi, buff_addr))
						tx_adisc(fi, ELS_ACC, s_id, received_ox_id);
					else
						tx_logo(fi, s_id, received_ox_id);
					break;
				case ELS_PRLI:
					DPRINTK1("ELS_PRLI received from D_ID 0x%x", s_id);
					if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN)) {
						tx_prli(fi, ELS_ACC, s_id, received_ox_id);
						mark_scsi_sid(fi, buff_addr, ADD_ENTRY);
					}
					else
						tx_logo(fi, s_id, received_ox_id);
					break;
				case ELS_PRLO:
					DPRINTK1("ELS_PRLO received from D_ID 0x%x", s_id);
					if ((login_state == NODE_LOGGED_OUT) || (login_state == NODE_NOT_PRESENT))
						tx_logo(fi, s_id, received_ox_id);
					else
					if (login_state == NODE_LOGGED_IN)

						tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
					else
					if (login_state == NODE_PROCESS_LOGGED_IN) {
						tx_prli(fi, ELS_ACC, s_id, received_ox_id);
						mark_scsi_sid(fi, buff_addr, DELETE_ENTRY);
					}
					break;
				case ELS_LS_RJT:
					els_type = remove_from_ox_id_list(fi, received_ox_id);
					DPRINTK1("ELS_LS_RJT received from D_ID 0x%x in response to %x", s_id, els_type);
					/* We should be chking the reason code.
					 */
					switch (els_type) {
						case ELS_ADISC:
							tx_logi(fi, ELS_PLOGI, s_id);
							break;
					}		
					break;
				case ELS_LOGO:
					els_type = remove_from_ox_id_list(fi, received_ox_id);
					DPRINTK1("ELS_LOGO received from D_ID 0x%x in response to %x", s_id, els_type);
					remove_from_address_cache(fi, buff_addr, ELS_LOGO);
					tx_acc(fi, s_id, received_ox_id);
					if (els_type == ELS_ADISC)
						tx_logi(fi, ELS_PLOGI, s_id);
					break;
				case ELS_RSCN:
					DPRINTK1("ELS_RSCN received from D_ID 0x%x", s_id);
					tx_acc(fi, s_id, received_ox_id);
					remove_from_address_cache(fi, buff_addr, ELS_RSCN);
					break;
				case ELS_FARP_REQ:
					/* We do not support FARP.
					   So, silently discard it */
					DPRINTK1("ELS_FARP_REQ received from D_ID 0x%x", s_id);
					break;
				case ELS_ABTX:
					DPRINTK1("ELS_ABTX received from D_ID 0x%x", s_id);
					if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
						tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
					else
						tx_logo(fi, s_id, received_ox_id);
					break;
				case ELS_FLOGI:
					DPRINTK1("ELS_FLOGI received from D_ID 0x%x", s_id);
					if (fi->g.ptp_up == TRUE) {
						/* The node could have come up as an N_Port
						 * in a Loop! So,try initializing as an NL_port
						 */
						take_tachyon_offline(fi);
						/* write AL_TIME & E_D_TOV into the registers */
						writel(TOV_VALUES, fi->t_r.ptr_fm_tov_reg);
						writel(LOOP_INIT_SOFT_ADDRESS, fi->t_r.ptr_fm_config_reg);
						DPRINTK1("FLOGI received, TACHYON initializing as L_Port...\n");
						writel(INITIALIZE, fi->t_r.ptr_fm_control_reg);
					}
					else {
						if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
							tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
						else
							tx_logo(fi, s_id, received_ox_id);
					}
					break;
				case ELS_ADVC:
					DPRINTK1("ELS_ADVC received from D_ID 0x%x", s_id);
					if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
						tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
					else
						tx_logo(fi, s_id, received_ox_id);
					break;
				case ELS_ECHO:
					DPRINTK1("ELS_ECHO received from D_ID 0x%x", s_id);
					if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
						tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
					else
						tx_logo(fi, s_id, received_ox_id);
					break;
				case ELS_ESTC:
					DPRINTK1("ELS_ESTC received from D_ID 0x%x", s_id);
					if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
						tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
					else
						tx_logo(fi, s_id, received_ox_id);
					break;
				case ELS_ESTS:
					DPRINTK1("ELS_ESTS received from D_ID 0x%x", s_id);
					if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
						tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
					else
						tx_logo(fi, s_id, received_ox_id);
					break;
				case ELS_RCS:
					DPRINTK1("ELS_RCS received from D_ID 0x%x", s_id);
					if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
						tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
					else
						tx_logo(fi, s_id, received_ox_id);
					break;
				case ELS_RES:
					DPRINTK1("ELS_RES received from D_ID 0x%x", s_id);
					if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
						tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
					else
						tx_logo(fi, s_id, received_ox_id);
					break;
				case ELS_RLS:
					DPRINTK1("ELS_RLS received from D_ID 0x%x", s_id);
					if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
						tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
					else
						tx_logo(fi, s_id, received_ox_id);
					break;
				case ELS_RRQ:
					DPRINTK1("ELS_RRQ received from D_ID 0x%x", s_id);
					if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
						tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
					else
						tx_logo(fi, s_id, received_ox_id);
					break;
				case ELS_RSS:
					DPRINTK1("ELS_RSS received from D_ID 0x%x", s_id);
					if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
						tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
					else
						tx_logo(fi, s_id, received_ox_id);
					break;
				case ELS_RTV:
					DPRINTK1("ELS_RTV received from D_ID 0x%x", s_id);
					if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
						tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
					else
						tx_logo(fi, s_id, received_ox_id);
					break;
				case ELS_RSI:
					DPRINTK1("ELS_RSI received from D_ID 0x%x", s_id);
					if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
						tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
					else
						tx_logo(fi, s_id, received_ox_id);
					break;
				case ELS_TEST:
					/* No reply sequence */
					DPRINTK1("ELS_TEST received from D_ID 0x%x", s_id);
					break;
				case ELS_RNC:
					DPRINTK1("ELS_RNC received from D_ID 0x%x", s_id);
					if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
						tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
					else
						tx_logo(fi, s_id, received_ox_id);
					break;
				case ELS_RVCS:
					DPRINTK1("ELS_RVCS received from D_ID 0x%x", s_id);
					if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
						tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
					else
						tx_logo(fi, s_id, received_ox_id);
					break;
				case ELS_TPLS:
					DPRINTK1("ELS_TPLS received from D_ID 0x%x", s_id);
					if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
						tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
					else
						tx_logo(fi, s_id, received_ox_id);
					break;
				case ELS_GAID:
					DPRINTK1("ELS_GAID received from D_ID 0x%x", s_id);
					if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
						tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
					else
						tx_logo(fi, s_id, received_ox_id);
					break;
				case ELS_FACT:
					DPRINTK1("ELS_FACT received from D_ID 0x%x", s_id);
					if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
						tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
					else
						tx_logo(fi, s_id, received_ox_id);
					break;
				case ELS_FAN:
					/* Hmmm... You don't support FAN ??? */
					DPRINTK1("ELS_FAN received from D_ID 0x%x", s_id);
					tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
					break;
				case ELS_FDACT:
					DPRINTK1("ELS_FDACT received from D_ID 0x%x", s_id);
					if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
						tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
					else
						tx_logo(fi, s_id, received_ox_id);
					break;
				case ELS_NACT:
					DPRINTK1("ELS_NACT received from D_ID 0x%x", s_id);
					if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
						tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
					else
						tx_logo(fi, s_id, received_ox_id);
					break;
				case ELS_NDACT:
					DPRINTK1("ELS_NDACT received from D_ID 0x%x", s_id);
					if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
						tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
					else
						tx_logo(fi, s_id, received_ox_id);
					break;
				case ELS_QoSR:
					DPRINTK1("ELS_QoSR received from D_ID 0x%x", s_id);
					if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
						tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
					else
						tx_logo(fi, s_id, received_ox_id);
					break;
				case ELS_FDISC:
					DPRINTK1("ELS_FDISC received from D_ID 0x%x", s_id);
					if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
						tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
					else
						tx_logo(fi, s_id, received_ox_id);
					break;
				default:
					DPRINTK1("ELS Frame %x received from D_ID 0x%x", class_of_frame, s_id);
					if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN))
						tx_ls_rjt(fi, s_id, received_ox_id, CMND_NOT_SUPP, NO_EXPLN);
					else
						tx_logo(fi, s_id, received_ox_id);
					break;
			}
			break;
		case TYPE_FC_SERVICES:
			fs_cmnd_code = (ntohl(*(buff_addr + 10)) & 0xFFFF0000) >>16;
			switch(fs_cmnd_code) {
				case FCS_ACC:
					els_type = remove_from_ox_id_list(fi, received_ox_id);
					DPRINTK1("FCS_ACC received from D_ID 0x%x in response to %x", s_id, els_type);
					if (els_type == FCS_GP_ID4) 
						explore_fabric(fi, buff_addr);
					break;
				case FCS_REJECT:
					DPRINTK1("FCS_REJECT received from D_ID 0x%x in response to %x", s_id, els_type);
					break;
			}
			break;
		case TYPE_LLC_SNAP:
			rx_net_packet(fi, (u_char *)buff_addr, payload_size);
			break;
		default:
			T_MSG("Frame Type %x received from %x", type_of_frame, s_id);
	}

	/* provide Tachyon will another set of buffers */
	if (offset == (NO_OF_ENTRIES - 1))
		update_SFSBQ_indx(fi);
	LEAVE("handle_SFS_interrupt");
}

Generated by GNU enscript 1.6.4.