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.