iph5526.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:148k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. LEAVE("tx_logo");
  2. }
  3. static void tx_adisc(struct fc_info *fi, u_int cmnd_code, u_int d_id, u_short received_ox_id)
  4. {
  5. int int_required = 0;
  6. u_int r_ctl = RCTL_ELS_SCTL;
  7. u_int type  = TYPE_ELS | EXCHANGE_RESPONDER | SEQUENCE_RESPONDER | FIRST_SEQUENCE | END_SEQUENCE;
  8. int size = sizeof(ADISC);
  9. u_int my_mtu = fi->g.my_mtu;
  10. fi->g.adisc.ls_cmnd_code = htonl(cmnd_code);
  11. fi->g.adisc.hard_address = htonl(0);
  12. fi->g.adisc.port_name_high = htonl(N_PORT_NAME_HIGH);
  13. fi->g.adisc.port_name_low = htonl(N_PORT_NAME_LOW);
  14. fi->g.adisc.node_name_high = htonl(NODE_NAME_HIGH);
  15. fi->g.adisc.node_name_low = htonl(NODE_NAME_LOW);
  16. fi->g.adisc.n_port_id = htonl(fi->g.my_id);
  17. if (cmnd_code == ELS_ADISC) {
  18. int_required = 1;
  19. r_ctl = RCTL_ELS_UCTL;
  20. type  = TYPE_ELS | SEQUENCE_INITIATIVE | FIRST_SEQUENCE;
  21. }
  22. fi->g.type_of_frame = FC_ELS;
  23. memcpy(fi->g.els_buffer[fi->g.e_i], &fi->g.adisc, size);
  24. tx_exchange(fi, (char *)(fi->g.els_buffer[fi->g.e_i]),size, r_ctl, type, d_id, my_mtu, int_required, received_ox_id, cmnd_code);
  25. fi->g.e_i++;
  26. if (fi->g.e_i == MAX_PENDING_FRAMES)
  27. fi->g.e_i = 0;
  28. }
  29. static void tx_ls_rjt(struct fc_info *fi, u_int d_id, u_short received_ox_id, u_short reason_code, u_short expln_code)
  30. {
  31. int int_required = 0;
  32. u_int r_ctl = RCTL_ELS_SCTL;
  33. u_int type  = TYPE_ELS | EXCHANGE_RESPONDER | LAST_SEQUENCE;
  34. int size = sizeof(LS_RJT);
  35. u_int my_mtu = fi->g.my_mtu;
  36. ENTER("tx_ls_rjt");
  37. fi->g.ls_rjt.cmnd_code = htonl(ELS_LS_RJT);
  38. fi->g.ls_rjt.reason_code = htonl((reason_code << 16) | expln_code); 
  39. fi->g.type_of_frame = FC_ELS;
  40. memcpy(fi->g.els_buffer[fi->g.e_i], &fi->g.ls_rjt, size);
  41. tx_exchange(fi, (char *)(fi->g.els_buffer[fi->g.e_i]),size, r_ctl, type, d_id, my_mtu, int_required, received_ox_id, ELS_LS_RJT);
  42. fi->g.e_i++;
  43. if (fi->g.e_i == MAX_PENDING_FRAMES)
  44. fi->g.e_i = 0;
  45. LEAVE("tx_ls_rjt");
  46. }
  47. static void tx_abts(struct fc_info *fi, u_int d_id, u_short ox_id)
  48. {
  49. int int_required = 1;
  50. u_int r_ctl = RCTL_BASIC_ABTS;
  51. u_int type  = TYPE_BLS | SEQUENCE_INITIATIVE | FIRST_SEQUENCE;
  52. int size = 0;
  53. u_int my_mtu = fi->g.my_mtu;
  54. ENTER("tx_abts");
  55. fi->g.type_of_frame = FC_BLS;
  56. tx_exchange(fi, NULL, size, r_ctl, type, d_id, my_mtu, int_required, ox_id, RCTL_BASIC_ABTS);
  57. LEAVE("tx_abts");
  58. }
  59. static u_int plogi_ok(struct fc_info *fi, u_int *buff_addr, int size)
  60. {
  61. int ret_code = 0;
  62. u_short mtu = ntohl(*(buff_addr + 10)) & 0x00000FFF;
  63. u_short class3 = ntohl(*(buff_addr + 25)) >> 16;
  64. u_short class3_conc_seq = ntohl(*(buff_addr + 27)) >> 16;
  65. u_short open_seq = ntohl(*(buff_addr + 28)) >> 16;
  66. DPRINTK1("mtu = %x class3 = %x conc_seq = %x open_seq = %x", mtu, class3, class3_conc_seq, open_seq);
  67. size -= TACHYON_HEADER_LEN;
  68. if (!(class3 & 0x8000)) {
  69. DPRINTK1("Received PLOGI with class3 = %x", class3);
  70. ret_code = (LOGICAL_ERR << 16) | NO_EXPLN;
  71. return ret_code;
  72. }
  73. if (mtu < 256) {
  74. DPRINTK1("Received PLOGI with MTU set to %x", mtu);
  75. ret_code = (LOGICAL_ERR << 16) | RECV_FIELD_SIZE;
  76. return ret_code;
  77. }
  78. if (size != PLOGI_LEN) {
  79. DPRINTK1("Received PLOGI of size %x", size);
  80. ret_code = (LOGICAL_ERR << 16) | INV_PAYLOAD_LEN;
  81. return ret_code;
  82. }
  83. if (class3_conc_seq == 0) {
  84. DPRINTK1("Received PLOGI with conc_seq == 0");
  85. ret_code = (LOGICAL_ERR << 16) | CONC_SEQ;
  86. return ret_code;
  87. }
  88. if (open_seq == 0) {
  89. DPRINTK1("Received PLOGI with open_seq == 0");
  90. ret_code = (LOGICAL_ERR << 16) | NO_EXPLN;
  91. return ret_code;
  92. }
  93. /* Could potentially check for more fields, but might end up
  94.    not talking to most of the devices. ;-) */
  95. /* Things that could get checked are:
  96.    common_features = 0x8800
  97.    total_concurrent_seq = at least 1
  98. */
  99. return ret_code;
  100. }
  101. static void tx_acc(struct fc_info *fi, u_int d_id, u_short received_ox_id)
  102. {
  103. int int_required = 0;
  104. u_int r_ctl = RCTL_ELS_SCTL;
  105. u_int type  = TYPE_ELS | EXCHANGE_RESPONDER | LAST_SEQUENCE;
  106. int size = sizeof(ACC);
  107. u_int my_mtu = fi->g.my_mtu;
  108. ENTER("tx_acc");
  109. fi->g.acc.cmnd_code = htonl(ELS_ACC);
  110. fi->g.type_of_frame = FC_ELS;
  111. memcpy(fi->g.els_buffer[fi->g.e_i], &fi->g.acc, size);
  112. tx_exchange(fi, (char *)(fi->g.els_buffer[fi->g.e_i]),size, r_ctl, type, d_id, my_mtu, int_required, received_ox_id, ELS_ACC);
  113. fi->g.e_i++;
  114. if (fi->g.e_i == MAX_PENDING_FRAMES)
  115. fi->g.e_i = 0;
  116. LEAVE("tx_acc");
  117. }
  118. static void tx_name_server_req(struct fc_info *fi, u_int req)
  119. {
  120. int int_required = 1, i, size = 0;
  121. u_short ox_id = OX_ID_FIRST_SEQUENCE;
  122. u_int type  = TYPE_FC_SERVICES | SEQUENCE_INITIATIVE | FIRST_SEQUENCE;
  123. u_int r_ctl = FC4_DEVICE_DATA | UNSOLICITED_CONTROL;
  124. u_int my_mtu = fi->g.my_mtu, d_id = DIRECTORY_SERVER;
  125. CT_HDR ct_hdr;
  126. ENTER("tx_name_server_req");
  127. /* Fill up CT_Header */
  128. ct_hdr.rev_in_id = htonl(FC_CT_REV);
  129. ct_hdr.fs_type = DIRECTORY_SERVER_APP;
  130. ct_hdr.fs_subtype = NAME_SERVICE;
  131. ct_hdr.options = 0;
  132. ct_hdr.resv1 = 0;
  133. ct_hdr.cmnd_resp_code = htons(req >> 16);
  134. ct_hdr.max_res_size = 0;
  135. ct_hdr.resv2 = 0;
  136. ct_hdr.reason_code = 0;
  137. ct_hdr.expln_code = 0;
  138. ct_hdr.vendor_unique = 0;
  139. fi->g.type_of_frame = FC_ELS;
  140. switch(req) {
  141. case FCS_RFC_4:
  142. memcpy(&(fi->g.rfc_4.ct_hdr), &ct_hdr, sizeof(CT_HDR));
  143. fi->g.rfc_4.s_id = htonl(fi->g.my_id);
  144. for (i = 0; i < 32; i++)
  145. fi->g.rfc_4.bit_map[i] = 0;
  146. /* We support IP & SCSI */
  147. fi->g.rfc_4.bit_map[2] = 0x01;
  148. fi->g.rfc_4.bit_map[3] = 0x20;
  149. size = sizeof(RFC_4);
  150. memcpy(fi->g.els_buffer[fi->g.e_i], &fi->g.rfc_4, size);
  151. tx_exchange(fi, (char *)(fi->g.els_buffer[fi->g.e_i]),size, r_ctl, type, d_id, my_mtu, int_required, ox_id, req);
  152. break;
  153. case FCS_GP_ID4:
  154. memcpy(&(fi->g.gp_id4.ct_hdr), &ct_hdr, sizeof(CT_HDR));
  155. fi->g.gp_id4.port_type = htonl(PORT_TYPE_NX_PORTS);
  156. size = sizeof(GP_ID4);
  157. memcpy(fi->g.els_buffer[fi->g.e_i], &fi->g.gp_id4, size);
  158. tx_exchange(fi, (char *)(fi->g.els_buffer[fi->g.e_i]),size, r_ctl, type, d_id, my_mtu, int_required, ox_id, req);
  159. break;
  160. }
  161. fi->g.e_i++;
  162. if (fi->g.e_i == MAX_PENDING_FRAMES)
  163. fi->g.e_i = 0;
  164. LEAVE("tx_name_server_req");
  165. }
  166. static void tx_scr(struct fc_info *fi)
  167. {
  168. int int_required = 1, size = sizeof(SCR);
  169. u_short ox_id = OX_ID_FIRST_SEQUENCE;
  170. u_int type  = TYPE_ELS | SEQUENCE_INITIATIVE | FIRST_SEQUENCE;
  171. u_int r_ctl = RCTL_ELS_UCTL;
  172. u_int my_mtu = fi->g.my_mtu, d_id = FABRIC_CONTROLLER;
  173. ENTER("tx_scr");
  174. fi->g.scr.cmnd_code = htonl(ELS_SCR);
  175. fi->g.scr.reg_function = htonl(FULL_REGISTRATION);
  176. fi->g.type_of_frame = FC_ELS;
  177. memcpy(fi->g.els_buffer[fi->g.e_i], &fi->g.scr, size);
  178. tx_exchange(fi, (char *)(fi->g.els_buffer[fi->g.e_i]),size, r_ctl, type, d_id, my_mtu, int_required, ox_id, ELS_SCR);
  179. fi->g.e_i++;
  180. if (fi->g.e_i == MAX_PENDING_FRAMES)
  181. fi->g.e_i = 0;
  182. LEAVE("tx_scr");
  183. }
  184. static void perform_adisc(struct fc_info *fi)
  185. {
  186. int count = 0;
  187. /* Will be set to TRUE when timer expires in a PLDA environment. 
  188.  */
  189. fi->g.port_discovery = FALSE;
  190. if (fi->node_info_list) {
  191. struct fc_node_info *temp_list = fi->node_info_list;
  192. while(temp_list) {
  193. /* Tx ADISC to all non-fabric based 
  194.      * entities.
  195.      */
  196. if ((temp_list->d_id & 0xFF0000) != 0xFF0000)
  197. tx_adisc(fi, ELS_ADISC, temp_list->d_id, OX_ID_FIRST_SEQUENCE);
  198. temp_list = temp_list->next;
  199. udelay(20);
  200. count++;
  201. }
  202. }
  203. /* Perform Port Discovery after timer expires.
  204.  * We are giving time for the ADISCed nodes to respond
  205.  * so that we dont have to perform PLOGI to those whose
  206.  * login are _still_ valid.
  207.  */
  208. fi->explore_timer.function = port_discovery_timer;
  209. fi->explore_timer.data = (unsigned long)fi;
  210. fi->explore_timer.expires = RUN_AT((count*3*HZ)/100); 
  211. init_timer(&fi->explore_timer);
  212. add_timer(&fi->explore_timer);
  213. }
  214. static void explore_fabric(struct fc_info *fi, u_int *buff_addr)
  215. {
  216. u_int *addr = buff_addr + 12; /* index into payload */
  217. u_char control_code;
  218. u_int d_id;
  219. int count = 0;
  220. ENTER("explore_fabric");
  221. DPRINTK1("entering explore_fabric");
  222. /*fi->g.perform_adisc = TRUE;
  223. fi->g.explore_fabric = TRUE;
  224. perform_adisc(fi);*/
  225. do {
  226. d_id = ntohl(*addr) & 0x00FFFFFF;
  227. if (d_id != fi->g.my_id) {
  228. if (sid_logged_in(fi, d_id) == NODE_NOT_PRESENT)
  229. tx_logi(fi, ELS_PLOGI, d_id); 
  230. else
  231. if (sid_logged_in(fi, d_id) == NODE_LOGGED_OUT)
  232. tx_adisc(fi, ELS_ADISC, d_id, OX_ID_FIRST_SEQUENCE); 
  233. count++;
  234. }
  235. control_code = (ntohl(*addr) & 0xFF000000) >> 24;
  236. addr++;
  237. DPRINTK1("cc = %x, d_id = %x", control_code, d_id);
  238. } while (control_code != 0x80);
  239. fi->explore_timer.function = fabric_explore_timer;
  240. fi->explore_timer.data = (unsigned long)fi;
  241. /* We give 30 msec for each device to respond and then send out
  242.  * our SCSI enquiries. 
  243.  */
  244. fi->explore_timer.expires = RUN_AT((count*3*HZ)/100); 
  245. init_timer(&fi->explore_timer);
  246. add_timer(&fi->explore_timer);
  247. DPRINTK1("leaving explore_fabric");
  248. LEAVE("explore_fabric");
  249. }
  250. static void fabric_explore_timer(unsigned long data)
  251. {
  252. struct fc_info *fi = (struct fc_info*)data;
  253. del_timer(&fi->explore_timer);
  254. if ((fi->g.loop_up == TRUE) && (fi->g.ptp_up == FALSE)) {
  255. /* Initiate Local Port Discovery on the Local Loop.
  256.  */
  257. fi->g.port_discovery = TRUE;
  258. fi->g.alpa_list_index = 1;
  259. local_port_discovery(fi);
  260. }
  261. fi->g.explore_fabric = FALSE;
  262. return;
  263. }
  264. static void port_discovery_timer(unsigned long data)
  265. {
  266. struct fc_info *fi = (struct fc_info*)data;
  267. del_timer(&fi->explore_timer);
  268. if ((fi->g.loop_up == TRUE) && (fi->g.explore_fabric != TRUE)) {
  269. fi->g.port_discovery = TRUE;
  270. fi->g.alpa_list_index = 1;
  271. local_port_discovery(fi);
  272. }
  273. fi->g.perform_adisc = FALSE;
  274. return;
  275. }
  276. static void add_to_ox_id_list(struct fc_info *fi, u_int transaction_id, u_int cmnd_code)
  277. {
  278. struct ox_id_els_map *p, *q = fi->ox_id_list, *r = NULL;
  279. int size = sizeof(struct ox_id_els_map);
  280. while (q != NULL) {
  281. r = q;
  282. q = q->next;
  283. }
  284. p = (struct ox_id_els_map *)kmalloc(size, GFP_ATOMIC);
  285. if (p == NULL) {
  286. T_MSG("kmalloc failed in add_to_ox_id_list()");
  287. return;
  288. }
  289. p->ox_id = transaction_id;
  290. p->els = cmnd_code;
  291. p->next = NULL;
  292. if (fi->ox_id_list == NULL)
  293. fi->ox_id_list = p;
  294. else
  295. r->next = p;
  296. return;
  297. }
  298. static u_int remove_from_ox_id_list(struct fc_info *fi, u_short received_ox_id)
  299. {
  300. struct ox_id_els_map *p = fi->ox_id_list, *q = fi->ox_id_list;
  301. u_int els_type;
  302. while (q != NULL) {
  303. if (q->ox_id == received_ox_id) {
  304. if (q == fi->ox_id_list) 
  305. fi->ox_id_list = fi->ox_id_list->next;
  306. else
  307. if (q->next == NULL) 
  308. p->next = NULL;
  309. else 
  310. p->next = q->next;
  311. els_type = q->els;
  312. kfree(q);
  313. return els_type;
  314. }
  315. p = q;
  316. q = q->next;
  317. }
  318. if (q == NULL)
  319. DPRINTK2("Could not find ox_id %x in ox_id_els_map", received_ox_id);
  320. return 0;
  321. }
  322. static void build_tachyon_header(struct fc_info *fi, u_int my_id, u_int r_ctl, u_int d_id, u_int type, u_char seq_id, u_char df_ctl, u_short ox_id, u_short rx_id, char *data)
  323. {
  324. u_char alpa = d_id & 0x0000FF;
  325. u_int dest_ddaa = d_id &0xFFFF00;
  326. ENTER("build_tachyon_header");
  327. DPRINTK("d_id = %x, my_ddaa = %x", d_id, fi->g.my_ddaa);
  328. /* Does it have to go to/thru a Fabric? */
  329. if ((dest_ddaa != 0) && ((d_id == F_PORT) || (fi->g.fabric_present && (dest_ddaa != fi->g.my_ddaa))))
  330. alpa = 0x00;
  331. fi->g.tach_header.resv = 0x00000000;
  332. fi->g.tach_header.sof_and_eof = SOFI3 | EOFN;
  333. fi->g.tach_header.dest_alpa = alpa;
  334. /* Set LCr properly to have enuff credit */
  335. if (alpa == REPLICATE)
  336. fi->g.tach_header.lcr_and_time_stamp = htons(0xC00);/* LCr=3 */
  337. else
  338. fi->g.tach_header.lcr_and_time_stamp = 0;
  339. fi->g.tach_header.r_ctl_and_d_id = htonl(r_ctl | d_id);
  340. fi->g.tach_header.vc_id_and_s_id = htonl(my_id);
  341. fi->g.tach_header.type_and_f_cntl = htonl(type);
  342. fi->g.tach_header.seq_id = seq_id;
  343. fi->g.tach_header.df_cntl = df_ctl;
  344. fi->g.tach_header.seq_cnt = 0;
  345. fi->g.tach_header.ox_id = htons(ox_id);
  346. fi->g.tach_header.rx_id = htons(rx_id);
  347. fi->g.tach_header.ro = 0;
  348. if (data) {
  349. /* We use the Seq_Count to keep track of IP frames in the
  350.  * OCI_interrupt handler. Initial Seq_Count of IP frames is 1.
  351.  */
  352. if (fi->g.type_of_frame == FC_BROADCAST)
  353. fi->g.tach_header.seq_cnt = htons(0x1);
  354. else
  355. fi->g.tach_header.seq_cnt = htons(0x2);
  356. fi->g.tach_header.nw_header.d_naa = htons(0x1000);
  357. fi->g.tach_header.nw_header.s_naa = htons(0x1000);
  358. memcpy(&(fi->g.tach_header.nw_header.dest_high), data, 2);
  359. memcpy(&(fi->g.tach_header.nw_header.dest_low), data + 2, 4);
  360. memcpy(&(fi->g.tach_header.nw_header.source_high), data + 6, 2);
  361. memcpy(&(fi->g.tach_header.nw_header.source_low), data + 8, 4);
  362. }
  363. LEAVE("build_tachyon_header");
  364. }
  365. static void build_EDB(struct fc_info *fi, char *data, u_short flags, u_short len)
  366. {
  367. fi->g.edb.buf_addr = ntohl((u_int)virt_to_bus(data));
  368. fi->g.edb.ehf = ntohs(flags);
  369. if (len % 4)
  370. len += (4 - (len % 4));
  371. fi->g.edb.buf_len = ntohs(len);
  372. }
  373. static void build_ODB(struct fc_info *fi, u_char seq_id, u_int d_id, u_int len, u_int cntl, u_short mtu, u_short ox_id, u_short rx_id, int NW_header, int int_required, u_int frame_class)
  374. {
  375. fi->g.odb.seq_d_id = htonl(seq_id << 24 | d_id);
  376. fi->g.odb.tot_len = len;
  377. if (NW_header)
  378. fi->g.odb.tot_len += NW_HEADER_LEN;
  379. if (fi->g.odb.tot_len % 4)
  380. fi->g.odb.tot_len += (4 - (fi->g.odb.tot_len % 4));
  381. fi->g.odb.tot_len = htonl(fi->g.odb.tot_len);
  382. switch(int_required) {
  383. case NO_COMP_AND_INT:
  384. fi->g.odb.cntl = htons(ODB_CLASS_3 | ODB_EE_CREDIT | ODB_NO_INT | ODB_NO_COMP | cntl);
  385. break;
  386. case INT_AND_COMP_REQ:
  387. fi->g.odb.cntl = htons(ODB_CLASS_3 | ODB_EE_CREDIT | cntl);
  388. break;
  389. case NO_INT_COMP_REQ:
  390. fi->g.odb.cntl = htons(ODB_CLASS_3 | ODB_EE_CREDIT | ODB_NO_INT | cntl);
  391. break;
  392. }
  393. fi->g.odb.rx_id = htons(rx_id);
  394. fi->g.odb.cs_enable = 0;
  395. fi->g.odb.cs_seed = htons(1);
  396. fi->g.odb.hdr_addr = htonl(virt_to_bus(fi->q.ptr_tachyon_header[fi->q.tachyon_header_indx]));
  397. fi->g.odb.frame_len = htons(mtu);
  398. if (NW_header) {
  399. /* The pointer to the sk_buff is in here. Freed up when the
  400.  * OCI_interrupt is received.
  401.  */
  402. fi->g.odb.trans_id = htonl(frame_class);
  403. fi->g.odb.hdr_len = TACHYON_HEADER_LEN + NW_HEADER_LEN;
  404. }
  405. else {
  406. /* helps in tracking transmitted OX_IDs */
  407. fi->g.odb.trans_id = htonl((frame_class & 0xFFFF0000) | ox_id);
  408. fi->g.odb.hdr_len = TACHYON_HEADER_LEN;
  409. }
  410. fi->g.odb.hdr_len = htons(fi->g.odb.hdr_len);
  411. fi->g.odb.edb_addr = htonl(virt_to_bus(fi->q.ptr_edb[fi->q.edb_buffer_indx]));
  412. }
  413. static void fill_login_frame(struct fc_info *fi, u_int logi)
  414. {
  415. int i;
  416. fi->g.login.ls_cmnd_code= htonl(logi);
  417. fi->g.login.fc_ph_version = htons(PH_VERSION);
  418. if (fi->g.loop_up)
  419. fi->g.login.buff_to_buff_credit = htons(LOOP_BB_CREDIT);
  420. else
  421. if (fi->g.ptp_up)
  422. fi->g.login.buff_to_buff_credit = htons(PT2PT_BB_CREDIT);
  423. if ((logi != ELS_FLOGI) || (logi == ELS_ACC))
  424. fi->g.login.common_features = htons(PLOGI_C_F);
  425. else
  426. if (logi == ELS_FLOGI)
  427. fi->g.login.common_features = htons(FLOGI_C_F);
  428. fi->g.login.recv_data_field_size = htons(TACH_FRAME_SIZE);
  429. fi->g.login.n_port_total_conc_seq = htons(CONCURRENT_SEQUENCES);
  430. fi->g.login.rel_off_by_info_cat = htons(RO_INFO_CATEGORY);
  431. fi->g.login.ED_TOV = htonl(E_D_TOV);
  432. fi->g.login.n_port_name_high = htonl(N_PORT_NAME_HIGH);
  433. fi->g.login.n_port_name_low = htonl(N_PORT_NAME_LOW);
  434. fi->g.login.node_name_high = htonl(NODE_NAME_HIGH);
  435. fi->g.login.node_name_low = htonl(NODE_NAME_LOW);
  436. /* Fill Class 1 parameters */
  437. fi->g.login.c_of_s[0].service_options = htons(0);
  438. fi->g.login.c_of_s[0].initiator_ctl = htons(0);
  439. fi->g.login.c_of_s[0].recipient_ctl = htons(0);
  440. fi->g.login.c_of_s[0].recv_data_field_size = htons(0);
  441. fi->g.login.c_of_s[0].concurrent_sequences = htons(0);
  442. fi->g.login.c_of_s[0].n_port_end_to_end_credit = htons(0);
  443. fi->g.login.c_of_s[0].open_seq_per_exchange = htons(0);
  444. fi->g.login.c_of_s[0].resv = htons(0);
  445. /* Fill Class 2 parameters */
  446. fi->g.login.c_of_s[1].service_options = htons(0);
  447. fi->g.login.c_of_s[1].initiator_ctl = htons(0);
  448. fi->g.login.c_of_s[1].recipient_ctl = htons(0);
  449. fi->g.login.c_of_s[1].recv_data_field_size = htons(0);
  450. fi->g.login.c_of_s[1].concurrent_sequences = htons(0);
  451. fi->g.login.c_of_s[1].n_port_end_to_end_credit = htons(0);
  452. fi->g.login.c_of_s[1].open_seq_per_exchange = htons(0);
  453. fi->g.login.c_of_s[1].resv = htons(0);
  454. /* Fill Class 3 parameters */
  455. if (logi == ELS_FLOGI)
  456. fi->g.login.c_of_s[2].service_options  = htons(SERVICE_VALID | SEQUENCE_DELIVERY);
  457. else
  458. fi->g.login.c_of_s[2].service_options  = htons(SERVICE_VALID);
  459. fi->g.login.c_of_s[2].initiator_ctl = htons(0);
  460. fi->g.login.c_of_s[2].recipient_ctl = htons(0);
  461. fi->g.login.c_of_s[2].recv_data_field_size = htons(TACH_FRAME_SIZE);
  462. fi->g.login.c_of_s[2].concurrent_sequences = htons(CLASS3_CONCURRENT_SEQUENCE);
  463. fi->g.login.c_of_s[2].n_port_end_to_end_credit = htons(0);
  464. fi->g.login.c_of_s[2].open_seq_per_exchange = htons(CLASS3_OPEN_SEQUENCE);
  465. fi->g.login.c_of_s[2].resv = htons(0);
  466. for(i = 0; i < 4; i++) {
  467. fi->g.login.resv[i] = 0;
  468. fi->g.login.vendor_version_level[i] = 0;
  469. }
  470. }
  471. /* clear the Interrupt Latch on the (i)chip, so that you can receive 
  472.  * Interrupts from Tachyon in future 
  473.  */
  474. static void reset_latch(struct fc_info *fi)
  475. {
  476. writel(readl(fi->i_r.ptr_ichip_hw_status_reg) | ICHIP_HSR_INT_LATCH, fi->i_r.ptr_ichip_hw_status_reg);
  477. }
  478. static void update_OCQ_indx(struct fc_info *fi)
  479. {
  480. fi->q.ocq_prod_indx++;
  481. if (fi->q.ocq_prod_indx == OCQ_LENGTH)
  482. fi->q.ocq_prod_indx = 0;
  483. writel(fi->q.ocq_prod_indx, fi->t_r.ptr_ocq_prod_indx_reg);
  484. }
  485. static void update_IMQ_indx(struct fc_info *fi, int count)
  486. {
  487. fi->q.imq_cons_indx += count;
  488. if (fi->q.imq_cons_indx >= IMQ_LENGTH)
  489. fi->q.imq_cons_indx -= IMQ_LENGTH;
  490. writel(fi->q.imq_cons_indx, fi->t_r.ptr_imq_cons_indx_reg);
  491. }
  492. static void update_SFSBQ_indx(struct fc_info *fi)
  493. {
  494. fi->q.sfsbq_prod_indx++;
  495. if (fi->q.sfsbq_prod_indx == SFSBQ_LENGTH)
  496. fi->q.sfsbq_prod_indx = 0;
  497. writel(fi->q.sfsbq_prod_indx, fi->t_r.ptr_sfsbq_prod_reg);
  498. }
  499. static void update_MFSBQ_indx(struct fc_info *fi, int count)
  500. {
  501. fi->q.mfsbq_prod_indx += count;
  502. if (fi->q.mfsbq_prod_indx >= MFSBQ_LENGTH)
  503. fi->q.mfsbq_prod_indx -= MFSBQ_LENGTH;
  504. writel(fi->q.mfsbq_prod_indx, fi->t_r.ptr_mfsbq_prod_reg);
  505. }
  506. static void update_tachyon_header_indx(struct fc_info *fi)
  507. {
  508. fi->q.tachyon_header_indx++;
  509. if (fi->q.tachyon_header_indx == NO_OF_TACH_HEADERS)
  510. fi->q.tachyon_header_indx = 0;
  511. }
  512. static void update_EDB_indx(struct fc_info *fi)
  513. {
  514. fi->q.edb_buffer_indx++;
  515. if (fi->q.edb_buffer_indx == EDB_LEN)
  516. fi->q.edb_buffer_indx = 0;
  517. }
  518. static int iph5526_open(struct net_device *dev)
  519. {
  520. netif_start_queue(dev);
  521. MOD_INC_USE_COUNT;
  522. return 0;
  523. }
  524. static int iph5526_close(struct net_device *dev)
  525. {
  526. netif_stop_queue(dev);
  527. MOD_DEC_USE_COUNT;
  528. return 0;
  529. }
  530. static void iph5526_timeout(struct net_device *dev)
  531. {
  532. struct fc_info *fi = (struct fc_info*)dev->priv;
  533. printk(KERN_WARNING "%s: timed out on send.n", dev->name);
  534. fi->fc_stats.rx_dropped++;
  535. dev->trans_start = jiffies;
  536. netif_wake_queue(dev);
  537. }
  538. static int iph5526_send_packet(struct sk_buff *skb, struct net_device *dev)
  539. {
  540. struct fc_info *fi = (struct fc_info*)dev->priv;
  541. int status = 0;
  542. short type = 0;
  543. u_long flags;
  544. struct fcllc *fcllc;
  545. ENTER("iph5526_send_packet");
  546. netif_stop_queue(dev);
  547. /* Strip off the pseudo header.
  548.  */
  549. skb->data = skb->data + 2*FC_ALEN; 
  550. skb->len = skb->len - 2*FC_ALEN;
  551. fcllc = (struct fcllc *)skb->data;
  552. type = ntohs(fcllc->ethertype);
  553. spin_lock_irqsave(&fi->fc_lock, flags);
  554. switch(type) {
  555. case ETH_P_IP:
  556. status = tx_ip_packet(skb, skb->len, fi);
  557. break;
  558. case ETH_P_ARP:
  559. status = tx_arp_packet(skb->data, skb->len, fi);
  560. break;
  561. default:
  562. T_MSG("WARNING!!! Received Unknown Packet Type... Discarding...");
  563. fi->fc_stats.rx_dropped++;
  564. break;
  565. }
  566. spin_unlock_irqrestore(&fi->fc_lock, flags);
  567. if (status) {
  568. fi->fc_stats.tx_bytes += skb->len;
  569. fi->fc_stats.tx_packets++;
  570. }
  571. else
  572. fi->fc_stats.rx_dropped++;
  573. dev->trans_start = jiffies;
  574. /* We free up the IP buffers in the OCI_interrupt handler.
  575.  * status == 0 implies that the frame was not transmitted. So the
  576.  * skb is freed here.
  577.  */
  578. if ((type == ETH_P_ARP) || (status == 0))
  579. dev_kfree_skb(skb);
  580. netif_wake_queue(dev);
  581. LEAVE("iph5526_send_packet");
  582. return 0;
  583. }
  584. static int iph5526_change_mtu(struct net_device *dev, int mtu)
  585. {
  586. return 0;
  587. }
  588. static int tx_ip_packet(struct sk_buff *skb, unsigned long len, struct fc_info *fi)
  589. {
  590. u_int d_id;
  591. int int_required = 1;
  592. u_int r_ctl = FC4_DEVICE_DATA | UNSOLICITED_DATA;
  593. u_int type = TYPE_LLC_SNAP;
  594. u_short ox_id = OX_ID_FIRST_SEQUENCE;
  595. u_int mtu;
  596. struct fc_node_info *q;
  597. ENTER("tx_ip_packet");
  598. q = look_up_cache(fi, skb->data - 2*FC_ALEN);
  599. if (q != NULL) {
  600. d_id = q->d_id;
  601. DPRINTK("Look-Up Cache Succeeded for d_id = %x", d_id);
  602. mtu = q->mtu;
  603. if (q->login == LOGIN_COMPLETED){
  604. fi->g.type_of_frame = FC_IP;
  605. return tx_exchange(fi, skb->data, len, r_ctl, type, d_id, mtu, int_required, ox_id, virt_to_bus(skb));
  606. }
  607. if (q->d_id == BROADCAST) {
  608. struct fc_node_info *p = fi->node_info_list;
  609. int return_value = FALSE;
  610. fi->g.type_of_frame = FC_BROADCAST;
  611. /* Do unicast to local nodes.
  612.  */
  613. int_required = 0;
  614. while(p != NULL) {
  615. d_id = p->d_id;
  616. if ((d_id & 0xFFFF00) == fi->g.my_ddaa)
  617. return_value |= tx_exchange(fi, skb->data, len, r_ctl, type, d_id, fi->g.my_mtu, int_required, ox_id, TYPE_LLC_SNAP);
  618. p = p->next;
  619. }
  620. kfree(q);
  621. return return_value;
  622. }
  623. if (q->login != LOGIN_COMPLETED) {
  624. DPRINTK1("Node not logged in... Txing PLOGI to %x", d_id);
  625. /* FIXME: we are dumping the frame here */
  626. tx_logi(fi, ELS_PLOGI, d_id); 
  627. }
  628. }
  629. DPRINTK2("Look-Up Cache Failed");
  630. LEAVE("tx_ip_packet");
  631. return 0;
  632. }
  633. static int tx_arp_packet(char *data, unsigned long len, struct fc_info *fi)
  634. {
  635. u_int opcode = data[ARP_OPCODE_0]; 
  636. u_int d_id;
  637. int int_required = 0, return_value = FALSE;
  638. u_int r_ctl = FC4_DEVICE_DATA | UNSOLICITED_DATA;
  639. u_int type = TYPE_LLC_SNAP;
  640. u_short ox_id = OX_ID_FIRST_SEQUENCE;
  641. u_int my_mtu = fi->g.my_mtu;
  642. ENTER("tx_arp_packet");
  643. opcode = opcode << 8 | data[ARP_OPCODE_1];
  644. fi->g.type_of_frame = FC_IP;
  645. if (opcode == ARPOP_REQUEST) {
  646. struct fc_node_info *q = fi->node_info_list;
  647. d_id = BROADCAST;
  648. return_value |= tx_exchange(fi, data, len, r_ctl, type, d_id, my_mtu, int_required, ox_id, TYPE_LLC_SNAP);
  649. /* Some devices support HW_TYPE 0x01 */
  650. memcpy(fi->g.arp_buffer, data - 2*FC_ALEN, len + 2*FC_ALEN);
  651. fi->g.arp_buffer[9 + 2*FC_ALEN] = 0x01;
  652. return_value |= tx_exchange(fi, (char *)(fi->g.arp_buffer + 2*FC_ALEN), len, r_ctl, type, d_id, my_mtu, int_required, ox_id, TYPE_LLC_SNAP);
  653. /* Do unicast to local nodes.
  654.  */
  655. while(q != NULL) {
  656. fi->g.type_of_frame = FC_BROADCAST;
  657. d_id = q->d_id;
  658. if ((d_id & 0xFFFF00) == fi->g.my_ddaa) {
  659. return_value |= tx_exchange(fi, data, len, r_ctl, type, d_id, my_mtu, int_required, ox_id, TYPE_LLC_SNAP);
  660. // Some devices support HW_TYPE 0x01
  661. memcpy(fi->g.arp_buffer, data - 2*FC_ALEN, len + 2*FC_ALEN);
  662. fi->g.arp_buffer[9 + 2*FC_ALEN] = 0x01;
  663. return_value |= tx_exchange(fi, (char *)(fi->g.arp_buffer + 2*FC_ALEN), len, r_ctl, type, d_id, my_mtu, int_required, ox_id, TYPE_LLC_SNAP);
  664. }
  665. q = q->next;
  666. }
  667. return return_value;
  668. }
  669. else
  670. if (opcode == ARPOP_REPLY) {
  671. struct fc_node_info *q; u_int mtu;
  672. DPRINTK("We are sending out an ARP reply");
  673. q = look_up_cache(fi, data - 2*FC_ALEN);
  674. if (q != NULL) {
  675. d_id = q->d_id;
  676. DPRINTK("Look-Up Cache Succeeded for d_id = %x", d_id);
  677. mtu = q->mtu;
  678. if (q->login == LOGIN_COMPLETED){
  679. tx_exchange(fi, data, len, r_ctl, type, d_id, mtu, int_required, ox_id, TYPE_LLC_SNAP);
  680. /* Some devices support HW_TYPE 0x01 */
  681. memcpy(fi->g.arp_buffer, data - 2*FC_ALEN, len + 2*FC_ALEN);
  682. fi->g.arp_buffer[9 + 2*FC_ALEN] = 0x01;
  683. return tx_exchange(fi, (char *)(fi->g.arp_buffer + 2*FC_ALEN), len, r_ctl, type, d_id, my_mtu, int_required, ox_id, TYPE_LLC_SNAP);
  684. }
  685. else {
  686. DPRINTK1("Node not logged in... Txing PLOGI to %x", d_id);
  687. tx_logi(fi, ELS_PLOGI, d_id); /* FIXME: we are dumping the frame here */
  688. }
  689. }
  690. DPRINTK2("Look-Up Cache Failed");
  691. }
  692. else {
  693. T_MSG("Warning!!! Invalid Opcode in ARP Packet!");
  694. }
  695. LEAVE("tx_arp_packet");
  696. return 0;
  697. }
  698. static void rx_net_packet(struct fc_info *fi, u_char *buff_addr, int payload_size)
  699. {
  700. struct net_device *dev = fi->dev;
  701. struct sk_buff *skb;
  702. u_int skb_size = 0;
  703. struct fch_hdr fch;
  704. ENTER("rx_net_packet");
  705. skb_size = payload_size - TACHYON_HEADER_LEN;
  706. DPRINTK("skb_size = %d", skb_size);
  707. fi->fc_stats.rx_bytes += skb_size - 2;
  708. skb = dev_alloc_skb(skb_size);
  709. if (skb == NULL) {
  710. printk(KERN_NOTICE "%s: In rx_net_packet() Memory squeeze, dropping packet.n", dev->name);
  711. fi->fc_stats.rx_dropped++;
  712. return;
  713. }
  714. /* Skip over the Tachyon Frame Header.
  715.  */
  716. buff_addr += TACHYON_HEADER_LEN; 
  717. memcpy(fch.daddr, buff_addr + 2, FC_ALEN);
  718. memcpy(fch.saddr, buff_addr + 10, FC_ALEN);
  719. buff_addr += 2;
  720. memcpy(buff_addr, fch.daddr, FC_ALEN);
  721. memcpy(buff_addr + 6, fch.saddr, FC_ALEN);
  722. skb_reserve(skb, 2);
  723. memcpy(skb_put(skb, skb_size - 2), buff_addr, skb_size - 2);
  724. skb->dev = dev;
  725. skb->protocol = fc_type_trans(skb, dev);
  726. DPRINTK("protocol = %x", skb->protocol);
  727. /* Hmmm... to accept HW Type 0x01 as well... 
  728.  */
  729. if (skb->protocol == ntohs(ETH_P_ARP))
  730. skb->data[1] = 0x06;
  731. netif_rx(skb);
  732. dev->last_rx = jiffies;
  733. fi->fc_stats.rx_packets++;
  734. LEAVE("rx_net_packet");
  735. }
  736. static void rx_net_mfs_packet(struct fc_info *fi, struct sk_buff *skb)
  737. {
  738. struct net_device *dev = fi->dev;
  739. struct fch_hdr fch;
  740. ENTER("rx_net_mfs_packet");
  741. /* Construct your Hard Header */
  742. memcpy(fch.daddr, skb->data + 2, FC_ALEN);
  743. memcpy(fch.saddr, skb->data + 10, FC_ALEN);
  744. skb_pull(skb, 2);
  745. memcpy(skb->data, fch.daddr, FC_ALEN);
  746. memcpy(skb->data + 6, fch.saddr, FC_ALEN);
  747. skb->dev = dev;
  748. skb->protocol = fc_type_trans(skb, dev);
  749. DPRINTK("protocol = %x", skb->protocol);
  750. netif_rx(skb);
  751. dev->last_rx = jiffies;
  752. LEAVE("rx_net_mfs_packet");
  753. }
  754. unsigned short fc_type_trans(struct sk_buff *skb, struct net_device *dev) 
  755. {
  756. struct fch_hdr *fch=(struct fch_hdr *)skb->data;
  757. struct fcllc *fcllc;
  758. skb->mac.raw = skb->data;
  759. fcllc = (struct fcllc *)(skb->data + sizeof(struct fch_hdr) + 2);
  760. skb_pull(skb,sizeof(struct fch_hdr) + 2);
  761. if(*fch->daddr & 1) {
  762. if(!memcmp(fch->daddr,dev->broadcast,FC_ALEN)) 
  763. skb->pkt_type = PACKET_BROADCAST;
  764. else
  765. skb->pkt_type = PACKET_MULTICAST;
  766. }
  767. else if(dev->flags & IFF_PROMISC) {
  768. if(memcmp(fch->daddr, dev->dev_addr, FC_ALEN))
  769. skb->pkt_type=PACKET_OTHERHOST;
  770. }
  771. /* Strip the SNAP header from ARP packets since we don't 
  772.  * pass them through to the 802.2/SNAP layers.
  773.  */
  774. if (fcllc->dsap == EXTENDED_SAP &&
  775. (fcllc->ethertype == ntohs(ETH_P_IP) ||
  776.  fcllc->ethertype == ntohs(ETH_P_ARP))) {
  777. skb_pull(skb, sizeof(struct fcllc));
  778. return fcllc->ethertype;
  779. }
  780. return ntohs(ETH_P_802_2);
  781. }
  782. static int tx_exchange(struct fc_info *fi, char *data, u_int len, u_int r_ctl, u_int type, u_int d_id, u_int mtu, int int_required, u_short tx_ox_id, u_int frame_class)
  783. {
  784. u_char df_ctl; 
  785. int NW_flag = 0, h_size, return_value;
  786. u_short rx_id = RX_ID_FIRST_SEQUENCE;
  787. u_int tachyon_status;
  788. u_int my_id = fi->g.my_id;
  789. ENTER("tx_exchange");
  790. tachyon_status = readl(fi->t_r.ptr_tach_status_reg);
  791. DPRINTK("Tachyon Status = %x len = %d MTU = %d", tachyon_status, len, mtu);
  792. if (tachyon_status & OSM_FROZEN) {
  793. reset_tachyon(fi, ERROR_RELEASE);
  794. reset_tachyon(fi, OCQ_RESET);
  795. DPRINTK("Tachyon Status = %x len = %d MTU = %d", tachyon_status, len, mtu);
  796. }
  797. if (tx_ox_id == OX_ID_FIRST_SEQUENCE) {
  798. switch(fi->g.type_of_frame) {
  799. case FC_SCSI_READ:
  800. tx_ox_id = fi->g.scsi_oxid | SCSI_READ_BIT;
  801. break;
  802. case FC_SCSI_WRITE:
  803. tx_ox_id = fi->g.scsi_oxid;
  804. break;
  805. default:
  806. tx_ox_id = fi->g.ox_id;
  807. break;
  808. }
  809. }
  810. else {
  811. switch(fi->g.type_of_frame) {
  812. case FC_SCSI_READ:
  813. rx_id = fi->g.scsi_oxid | SCSI_READ_BIT;
  814. break;
  815. case FC_SCSI_WRITE:
  816. rx_id = fi->g.scsi_oxid;
  817. break;
  818. case FC_BLS:
  819. rx_id = RX_ID_FIRST_SEQUENCE;
  820. break;
  821. default:
  822. rx_id = fi->g.ox_id;
  823. break;
  824. }
  825. }
  826. if (type == TYPE_LLC_SNAP) {
  827. df_ctl = 0x20;
  828. NW_flag = 1;
  829. /* Multi Frame Sequence ? If yes, set RO bit */
  830. if (len > mtu)
  831. type |= RELATIVE_OFF_PRESENT;
  832. build_tachyon_header(fi, my_id, r_ctl, d_id, type, fi->g.seq_id, df_ctl, tx_ox_id, rx_id, data - 2*FC_ALEN);
  833. }
  834. else {
  835. df_ctl = 0;
  836. /* Multi Frame Sequence ? If yes, set RO bit */
  837. if (len > mtu)
  838. type |= RELATIVE_OFF_PRESENT;
  839. build_tachyon_header(fi, my_id, r_ctl, d_id, type, fi->g.seq_id, df_ctl, tx_ox_id, rx_id, NULL);
  840. }
  841. /* Get free Tachyon Headers and EDBs */
  842. if (get_free_header(fi) || get_free_EDB(fi))
  843. return 0;
  844. if ((type & 0xFF000000) == TYPE_LLC_SNAP) {
  845. h_size =  TACHYON_HEADER_LEN + NW_HEADER_LEN;
  846. memcpy(fi->q.ptr_tachyon_header[fi->q.tachyon_header_indx], &(fi->g.tach_header), h_size);
  847. }
  848. else 
  849. memcpy(fi->q.ptr_tachyon_header[fi->q.tachyon_header_indx], &(fi->g.tach_header), TACHYON_HEADER_LEN);
  850. return_value = tx_sequence(fi, data, len, mtu, d_id, tx_ox_id, rx_id, fi->g.seq_id, NW_flag, int_required, frame_class);
  851. switch(fi->g.type_of_frame) {
  852. case FC_SCSI_READ:
  853. case FC_SCSI_WRITE:
  854. update_scsi_oxid(fi);
  855. break;
  856. case FC_BLS:
  857. break;
  858. default:
  859. fi->g.ox_id++;
  860. if (fi->g.ox_id == 0xFFFF)
  861. fi->g.ox_id = NOT_SCSI_XID;
  862. break;
  863. }
  864. if (fi->g.seq_id == MAX_SEQ_ID)
  865. fi->g.seq_id = 0;
  866. else
  867. fi->g.seq_id++;
  868. LEAVE("tx_exchange");
  869. return return_value;
  870. }
  871. static int tx_sequence(struct fc_info *fi, char *data, u_int len, u_int mtu, u_int d_id, u_short ox_id, u_short rx_id, u_char seq_id, int NW_flag, int int_required, u_int frame_class)
  872. {
  873. u_int cntl = 0;
  874. int return_value;
  875. ENTER("tx_sequence");
  876. build_EDB(fi, data, EDB_END, len);
  877. memcpy(fi->q.ptr_edb[fi->q.edb_buffer_indx], &(fi->g.edb), sizeof(EDB));
  878. build_ODB(fi, seq_id, d_id, len, cntl, mtu, ox_id, rx_id, NW_flag, int_required, frame_class);
  879. memcpy(fi->q.ptr_odb[fi->q.ocq_prod_indx], &(fi->g.odb), sizeof(ODB));
  880. if (fi->g.link_up != TRUE) {
  881. DPRINTK2("Fibre Channel Link not up. Dropping Exchange!");
  882. return_value = FALSE;
  883. }
  884. else {
  885. /* To be on the safe side, a check should be included
  886.  * at this point to check if we are overrunning 
  887.  * Tachyon.
  888.  */
  889. update_OCQ_indx(fi);
  890. return_value = TRUE;
  891. }
  892. update_EDB_indx(fi);
  893. update_tachyon_header_indx(fi);
  894. LEAVE("tx_sequence");
  895. return return_value;
  896. }
  897. static int get_free_header(struct fc_info *fi)
  898. {
  899. u_short temp_ox_id;
  900. u_int *tach_header, initial_indx = fi->q.tachyon_header_indx;
  901. /* Check if the header is in use.
  902.  * We could have an outstanding command.
  903.  * We should find a free slot as we can queue a
  904.  * maximum of 32 SCSI commands only. 
  905.  */
  906. tach_header = fi->q.ptr_tachyon_header[fi->q.tachyon_header_indx];
  907. temp_ox_id = ntohl(*(tach_header + 6)) >> 16;
  908. /* We care about the SCSI writes only. Those are the wicked ones
  909.  * that need an additional set of buffers.
  910.  */
  911. while(temp_ox_id <= MAX_SCSI_XID) {
  912. update_tachyon_header_indx(fi);
  913. if (fi->q.tachyon_header_indx == initial_indx) {
  914. /* Should never happen.
  915.  */
  916. T_MSG("No free Tachyon headers available");
  917. reset_tachyon(fi, SOFTWARE_RESET);
  918. return 1;
  919. }
  920. tach_header = fi->q.ptr_tachyon_header[fi->q.tachyon_header_indx];
  921. temp_ox_id = ntohl(*(tach_header + 6)) >> 16;
  922. }
  923. return 0;
  924. }
  925. static int get_free_EDB(struct fc_info *fi)
  926. {
  927. unsigned int initial_indx = fi->q.edb_buffer_indx;
  928. /* Check if the EDB is in use.
  929.  * We could have an outstanding SCSI Write command.
  930.  * We should find a free slot as we can queue a
  931.  * maximum of 32 SCSI commands only. 
  932.  */
  933. while (fi->q.free_edb_list[fi->q.edb_buffer_indx] != EDB_FREE) {
  934. update_EDB_indx(fi);
  935. if (fi->q.edb_buffer_indx == initial_indx) {
  936. T_MSG("No free EDB buffers avaliable")
  937. reset_tachyon(fi, SOFTWARE_RESET);
  938. return 1;
  939. }
  940. }
  941. return 0;
  942. }
  943. static int validate_login(struct fc_info *fi, u_int *base_ptr)
  944. {
  945. struct fc_node_info *q = fi->node_info_list;
  946. char n_port_name[PORT_NAME_LEN];
  947. char node_name[NODE_NAME_LEN];
  948. u_int s_id;
  949. ENTER("validate_login");
  950. /*index to Port Name in the payload. We need the 8 byte Port Name */
  951. memcpy(n_port_name, base_ptr + 10, PORT_NAME_LEN);
  952. memcpy(node_name, base_ptr + 12, NODE_NAME_LEN);
  953. s_id = ntohl(*(base_ptr + 3)) & 0x00FFFFFF;
  954. /* check if Fibre Channel IDs have changed */
  955. while(q != NULL) {
  956. if (memcmp(n_port_name, q->hw_addr, PORT_NAME_LEN) == 0) {
  957. if ((s_id != q->d_id) || (memcmp(node_name, q->node_name, NODE_NAME_LEN) != 0)) {
  958. DPRINTK1("Fibre Channel ID of Node has changed. Txing LOGO.");
  959. return 0;
  960. }
  961. q->login = LOGIN_COMPLETED;
  962. #if DEBUG_5526_2
  963. display_cache(fi);
  964. #endif
  965. return 1;
  966. }
  967. q = q->next;
  968. }
  969. DPRINTK1("Port Name does not match. Txing LOGO.");
  970. return 0;
  971. LEAVE("validate_login");
  972. }
  973. static void add_to_address_cache(struct fc_info *fi, u_int *base_ptr)
  974. {
  975. int size = sizeof(struct fc_node_info);
  976. struct fc_node_info *p, *q = fi->node_info_list, *r = NULL;
  977. char n_port_name[PORT_NAME_LEN];
  978. u_int s_id;
  979. ENTER("add_to_address_cache");
  980. /*index to Port Name in the payload. We need the 8 byte Port Name */
  981. memcpy(n_port_name, base_ptr + 13, PORT_NAME_LEN);
  982. s_id = ntohl(*(base_ptr + 3)) & 0x00FFFFFF;
  983. /* check if info already exists */
  984. while(q != NULL) {
  985. if (memcmp(n_port_name, q->hw_addr, PORT_NAME_LEN) == 0) {
  986. if (s_id != q->d_id) {
  987. memcpy(&(q->c_of_s[0]), base_ptr + 17, 3 * sizeof(CLASS_OF_SERVICE));
  988. q->mtu = ntohl(*(base_ptr + 10)) & 0x00000FFF;
  989. q->d_id = s_id;
  990. memcpy(q->node_name, base_ptr + 15, NODE_NAME_LEN);
  991. }
  992. q->login = LOGIN_COMPLETED;
  993. q->scsi = FALSE;
  994. fi->num_nodes++;
  995. #if DEBUG_5526_2
  996. display_cache(fi);
  997. #endif
  998. return;
  999. }
  1000. r = q;
  1001. q = q->next;
  1002. }
  1003. p = (struct fc_node_info *)kmalloc(size, GFP_ATOMIC);
  1004. if (p == NULL) {
  1005. T_MSG("kmalloc failed in add_to_address_cache()");
  1006. return;
  1007. }
  1008. memcpy(&(p->c_of_s[0]), base_ptr + 17, 3 * sizeof(CLASS_OF_SERVICE));
  1009. p->mtu = ntohl(*(base_ptr + 10)) & 0x00000FFF;
  1010. p->d_id = s_id;
  1011. memcpy(p->hw_addr, base_ptr + 13, PORT_NAME_LEN);
  1012. memcpy(p->node_name, base_ptr + 15, NODE_NAME_LEN);
  1013. p->login = LOGIN_COMPLETED;
  1014. p->scsi = FALSE;
  1015. p->target_id = 0xFF;
  1016. p->next = NULL;
  1017. if (fi->node_info_list == NULL)
  1018. fi->node_info_list = p;
  1019. else
  1020. r->next = p;
  1021. fi->num_nodes++;
  1022. #if DEBUG_5526_2
  1023. display_cache(fi);
  1024. #endif
  1025. LEAVE("add_to_address_cache");
  1026. return;
  1027. }
  1028. static void remove_from_address_cache(struct fc_info *fi, u_int *base_ptr, u_int cmnd_code)
  1029. {
  1030. struct fc_node_info *q = fi->node_info_list;
  1031. u_int s_id;
  1032. ENTER("remove_from_address_cache");
  1033. s_id = ntohl(*(base_ptr + 3)) & 0x00FFFFFF;
  1034. switch(cmnd_code) {
  1035. case ELS_LOGO:
  1036. /* check if info exists */
  1037. while (q != NULL) {
  1038. if (s_id == q->d_id) {
  1039. if (q->login == LOGIN_COMPLETED)
  1040. q->login = LOGIN_ATTEMPTED;
  1041. if (fi->num_nodes > 0)
  1042. fi->num_nodes--;
  1043. #if DEBUG_5526_2
  1044. display_cache(fi);
  1045. #endif
  1046. return;
  1047. }
  1048. q = q->next;
  1049. }
  1050. DPRINTK1("ELS_LOGO received from node 0x%x which is not logged-in", s_id);
  1051. break;
  1052. case ELS_RSCN:
  1053. {
  1054. int payload_len = ntohl(*(base_ptr + 8)) & 0xFF;
  1055. int no_of_pages, i;
  1056. u_char address_format;
  1057. u_short received_ox_id = ntohl(*(base_ptr + 6)) >> 16;
  1058. u_int node_id, mask, *page_ptr = base_ptr + 9;
  1059. if ((payload_len < 4) || (payload_len > 256)) {
  1060. DPRINTK1("RSCN with invalid payload length received");
  1061. tx_ls_rjt(fi, s_id, received_ox_id, LOGICAL_ERR, RECV_FIELD_SIZE);
  1062. return;
  1063. }
  1064. /* Page_size includes the Command Code */
  1065. no_of_pages = (payload_len / 4) - 1;
  1066. for (i = 0; i < no_of_pages; i++) {
  1067. address_format = ntohl(*page_ptr) >> 24; 
  1068. node_id = ntohl(*page_ptr) & 0x00FFFFFF;
  1069. switch(address_format) {
  1070. case PORT_ADDRESS_FORMAT:
  1071. rscn_handler(fi, node_id);
  1072. break;
  1073. case AREA_ADDRESS_FORMAT:
  1074. case DOMAIN_ADDRESS_FORMAT:
  1075. if (address_format == AREA_ADDRESS_FORMAT)
  1076. mask = 0xFFFF00;
  1077. else
  1078. mask = 0xFF0000;
  1079. while(q != NULL) {
  1080. if ((q->d_id & mask) == (node_id & mask)) 
  1081. rscn_handler(fi, q->d_id);
  1082. q = q->next;
  1083. }
  1084. /* There might be some new nodes to be 
  1085.  * discovered. But, some of the earlier 
  1086.  * requests as a result of the RSCN might be 
  1087.  * in progress. We dont want to duplicate that 
  1088.  * effort. So letz call SCR after a lag.
  1089.  */
  1090. fi->explore_timer.function = scr_timer;
  1091. fi->explore_timer.data = (unsigned long)fi;
  1092. fi->explore_timer.expires = RUN_AT((no_of_pages*3*HZ)/100); 
  1093. init_timer(&fi->explore_timer);
  1094. add_timer(&fi->explore_timer);
  1095. break;
  1096. default:
  1097. T_MSG("RSCN with invalid address format received");
  1098. tx_ls_rjt(fi, s_id, received_ox_id, LOGICAL_ERR, NO_EXPLN);
  1099. }
  1100. page_ptr += 1;
  1101. } /* end of for loop */
  1102. } /* end of case RSCN: */
  1103. break;
  1104. }
  1105. #if DEBUG_5526_2
  1106. display_cache(fi);
  1107. #endif
  1108. LEAVE("remove_from_address_cache");
  1109. }
  1110. static void rscn_handler(struct fc_info *fi, u_int node_id)
  1111. {
  1112. struct fc_node_info *q = fi->node_info_list;
  1113. int login_state = sid_logged_in(fi, node_id);
  1114. if ((login_state == NODE_LOGGED_IN) || (login_state == NODE_PROCESS_LOGGED_IN)) {
  1115. while(q != NULL) {
  1116. if (q->d_id == node_id) {
  1117. q->login = LOGIN_ATTEMPTED;
  1118. if (fi->num_nodes > 0)
  1119. fi->num_nodes--;
  1120. break;
  1121. }
  1122. else
  1123. q = q->next;
  1124. }
  1125. }
  1126. else
  1127. if (login_state == NODE_LOGGED_OUT)
  1128. tx_adisc(fi, ELS_ADISC, node_id, OX_ID_FIRST_SEQUENCE); 
  1129. else
  1130. if (login_state == NODE_LOGGED_OUT)
  1131. tx_logi(fi, ELS_PLOGI, node_id);
  1132. }
  1133. static void scr_timer(unsigned long data)
  1134. {
  1135. struct fc_info *fi = (struct fc_info *)data;
  1136. del_timer(&fi->explore_timer);
  1137. tx_name_server_req(fi, FCS_GP_ID4);
  1138. }
  1139. static int sid_logged_in(struct fc_info *fi, u_int s_id)
  1140. {
  1141. struct fc_node_info *temp = fi->node_info_list;
  1142. while(temp != NULL)
  1143. if ((temp->d_id == s_id) && (temp->login == LOGIN_COMPLETED)) {
  1144. if (temp->scsi != FALSE)
  1145. return NODE_PROCESS_LOGGED_IN;
  1146. else
  1147. return NODE_LOGGED_IN;
  1148. }
  1149. else
  1150. if ((temp->d_id == s_id) && (temp->login != LOGIN_COMPLETED))
  1151. return NODE_LOGGED_OUT;
  1152. else
  1153. temp = temp->next;
  1154. return NODE_NOT_PRESENT;
  1155. }
  1156. static void mark_scsi_sid(struct fc_info *fi, u_int *buff_addr, u_char action)
  1157. {
  1158. struct fc_node_info *temp = fi->node_info_list;
  1159. u_int s_id;
  1160. u_int service_params;
  1161. s_id = ntohl(*(buff_addr + 3)) & 0x00FFFFFF;
  1162. service_params = ntohl(*(buff_addr + 12)) & 0x000000F0;
  1163. while(temp != NULL)
  1164. if ((temp->d_id == s_id) && (temp->login == LOGIN_COMPLETED)) {
  1165. if (action == DELETE_ENTRY) {
  1166. temp->scsi = FALSE;
  1167. #if DEBUG_5526_2
  1168. display_cache(fi);
  1169. #endif
  1170. return;
  1171. }
  1172. /* Check if it is a SCSI Target */
  1173. if (!(service_params & TARGET_FUNC)) {
  1174. temp->scsi = INITIATOR;
  1175. #if DEBUG_5526_2
  1176. display_cache(fi);
  1177. #endif
  1178. return;
  1179. }
  1180. temp->scsi = TARGET;
  1181. /* This helps to maintain the target_id no matter what your
  1182.  *  Fibre Channel ID is.
  1183.  */
  1184. if (temp->target_id == 0xFF) {
  1185. if (fi->g.no_of_targets <= MAX_SCSI_TARGETS)
  1186. temp->target_id = fi->g.no_of_targets++;
  1187. else
  1188. T_MSG("MAX TARGETS reached!");
  1189. }
  1190. else
  1191. DPRINTK1("Target_id %d already present", temp->target_id);
  1192. #if DEBUG_5526_2
  1193. display_cache(fi);
  1194. #endif
  1195. return;
  1196. }
  1197. else
  1198. temp = temp->next;
  1199. return;
  1200. }
  1201. static int node_logged_in_prev(struct fc_info *fi, u_int *buff_addr)
  1202. {
  1203. struct fc_node_info *temp;
  1204. u_char *data = (u_char *)buff_addr;
  1205. u_int s_id;
  1206. char node_name[NODE_NAME_LEN];
  1207. s_id = ntohl(*(buff_addr + 3)) & 0x00FFFFFF;
  1208. memcpy(node_name, buff_addr + 12, NODE_NAME_LEN);
  1209. /* point to port_name in the ADISC payload */
  1210. data += 10 * 4;
  1211. /* point to last 6 bytes of port_name */
  1212. data += 2;
  1213. temp = look_up_cache(fi, data);
  1214. if (temp != NULL) {
  1215. if ((temp->d_id == s_id) && (memcmp(node_name, temp->node_name, NODE_NAME_LEN) == 0)) {
  1216. temp->login = LOGIN_COMPLETED;
  1217. #if DEBUG_5526_2
  1218. display_cache(fi);
  1219. #endif
  1220. return TRUE;
  1221. }
  1222. }
  1223. return FALSE;
  1224. }
  1225. static struct fc_node_info *look_up_cache(struct fc_info *fi, char *data)
  1226. {
  1227. struct fc_node_info *temp_list = fi->node_info_list, *q;
  1228. u_char n_port_name[FC_ALEN], temp_addr[FC_ALEN];
  1229. ENTER("look_up_cache");
  1230. memcpy(n_port_name, data, FC_ALEN);
  1231. while(temp_list) {
  1232. if (memcmp(n_port_name, &(temp_list->hw_addr[2]), FC_ALEN) == 0)
  1233. return temp_list;
  1234. else
  1235. temp_list = temp_list->next;
  1236. }
  1237. /* Broadcast IP ?
  1238.  */
  1239. temp_addr[0] = temp_addr[1] = temp_addr[2] = 0xFF;
  1240. temp_addr[3] = temp_addr[4] = temp_addr[5] = 0xFF;
  1241. if (memcmp(n_port_name, temp_addr, FC_ALEN) == 0) {
  1242. q = (struct fc_node_info *)kmalloc(sizeof(struct fc_node_info), GFP_ATOMIC);
  1243. if (q == NULL) {
  1244. T_MSG("kmalloc failed in look_up_cache()");
  1245. return NULL;
  1246. }
  1247. q->d_id = BROADCAST;
  1248. return q;
  1249. }
  1250. LEAVE("look_up_cache");
  1251. return NULL;
  1252. }
  1253. static int display_cache(struct fc_info *fi)
  1254. {
  1255. struct fc_node_info *q = fi->node_info_list;
  1256. #if DEBUG_5526_2
  1257. struct ox_id_els_map *temp_ox_id_list = fi->ox_id_list;
  1258. #endif
  1259. int count = 0, j;
  1260. printk("nFibre Channel Node Information for %sn", fi->name);
  1261. printk("My FC_ID = %x, My WWN = %x %x, ", fi->g.my_id, fi->g.my_node_name_high, fi->g.my_node_name_low);
  1262. if (fi->g.ptp_up == TRUE)
  1263. printk("Port_Type = N_Portn");
  1264. if (fi->g.loop_up == TRUE)
  1265. printk("Port_Type = L_Portn");
  1266. while(q != NULL) {
  1267. printk("WWN = ");
  1268. for (j = 0; j < PORT_NAME_LEN; j++)
  1269. printk("%x ", q->hw_addr[j]); 
  1270. printk("FC_ID = %x, ", q->d_id);
  1271. printk("Login = ");
  1272. if (q->login == LOGIN_COMPLETED)
  1273. printk("ON ");
  1274. else
  1275. printk("OFF ");
  1276. if (q->scsi == TARGET)
  1277. printk("Target_ID = %d ", q->target_id);
  1278. printk("n");
  1279. q = q->next;
  1280. count++;
  1281. }
  1282. #if DEBUG_5526_2
  1283. printk("OX_ID -> ELS Mapn");
  1284. while(temp_ox_id_list) {
  1285. printk("ox_id = %x, ELS = %xn", temp_ox_id_list->ox_id, temp_ox_id_list->els);
  1286. temp_ox_id_list = temp_ox_id_list->next;
  1287. }
  1288. #endif
  1289. return 0;
  1290. }
  1291. static struct net_device_stats * iph5526_get_stats(struct net_device *dev)
  1292. {
  1293. struct fc_info *fi = (struct fc_info*)dev->priv; 
  1294. return (struct net_device_stats *) &fi->fc_stats;
  1295. }
  1296. /* SCSI stuff starts here */
  1297. int iph5526_detect(Scsi_Host_Template *tmpt)
  1298. {
  1299. struct Scsi_Host *host = NULL;
  1300. struct iph5526_hostdata *hostdata;
  1301. struct fc_info *fi = NULL;
  1302. int no_of_hosts = 0, timeout, i, j, count = 0;
  1303. u_int pci_maddr = 0;
  1304. struct pci_dev *pdev = NULL;
  1305. tmpt->proc_name = "iph5526";
  1306. if (pci_present() == 0) {
  1307. printk("iph5526: PCI not presentn");
  1308. return 0;
  1309. }
  1310. for (i = 0; i <= MAX_FC_CARDS; i++) 
  1311. fc[i] = NULL;
  1312. for (i = 0; i < clone_list[i].vendor_id != 0; i++)
  1313. while ((pdev = pci_find_device(clone_list[i].vendor_id, clone_list[i].device_id, pdev))) {
  1314. unsigned short pci_command;
  1315. if (pci_enable_device(pdev))
  1316. continue;
  1317. if (count < MAX_FC_CARDS) {
  1318. fc[count] = kmalloc(sizeof(struct fc_info), GFP_ATOMIC);
  1319. if (fc[count] == NULL) {
  1320. printk("iph5526.c: Unable to register card # %dn", count + 1);
  1321. return no_of_hosts;
  1322. }
  1323. memset(fc[count], 0, sizeof(struct fc_info));
  1324. }
  1325. else {
  1326. printk("iph5526.c: Maximum Number of cards reached.n");
  1327. return no_of_hosts;
  1328. }
  1329. fi = fc[count];
  1330. sprintf(fi->name, "fc%d", count);
  1331. host = scsi_register(tmpt, sizeof(struct iph5526_hostdata));
  1332. if(host==NULL)
  1333. return no_of_hosts;
  1334. hostdata = (struct iph5526_hostdata *)host->hostdata;
  1335. memset(hostdata, 0 , sizeof(struct iph5526_hostdata));
  1336. for (j = 0; j < MAX_SCSI_TARGETS; j++)
  1337. hostdata->tag_ages[j] = jiffies;
  1338. hostdata->fi = fi;
  1339. fi->host = host;
  1340. //host->max_id = MAX_SCSI_TARGETS;
  1341. host->max_id = 5;
  1342. host->hostt->use_new_eh_code = 1;
  1343. host->this_id = tmpt->this_id;
  1344. pci_maddr = pci_resource_start(pdev, 0);
  1345. if (pci_resource_flags(pdev, 0) & IORESOURCE_IO) {
  1346. printk("iph5526.c : Cannot find proper PCI device base address.n");
  1347. scsi_unregister(host);
  1348. kfree(fc[count]);
  1349. fc[count] = NULL;
  1350. continue;
  1351. }
  1352. DPRINTK("pci_maddr = %x", pci_maddr);
  1353. pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
  1354. pci_irq_line = pdev->irq;
  1355. printk("iph5526.c: PCI BIOS reports %s at i/o %#x, irq %d.n", clone_list[i].name, pci_maddr, pci_irq_line);
  1356. fi->g.mem_base = ioremap(pci_maddr & PAGE_MASK, 1024);
  1357. /* We use Memory Mapped IO. The initial space contains the
  1358.  * PCI Configuration registers followed by the (i) chip
  1359.  * registers followed by the Tachyon registers.
  1360.  */
  1361. /* Thatz where (i)chip maps Tachyon Address Space.
  1362.  */
  1363. fi->g.tachyon_base = (u_long)fi->g.mem_base + TACHYON_OFFSET + ( pci_maddr & ~PAGE_MASK );
  1364. DPRINTK("fi->g.tachyon_base = %x", (u_int)fi->g.tachyon_base);
  1365. if (fi->g.mem_base == NULL) {
  1366. printk("iph5526.c : ioremap failed!!!n");
  1367. scsi_unregister(host);
  1368. kfree(fc[count]);
  1369. fc[count] = NULL;
  1370. continue;
  1371. }
  1372. DPRINTK("IRQ1 = %dn", pci_irq_line);
  1373. printk(version);
  1374. fi->base_addr = (long) pdev;
  1375. if (pci_irq_line) {
  1376. int irqval = 0;
  1377. /* Found it, get IRQ.
  1378.  */
  1379. irqval = request_irq(pci_irq_line, &tachyon_interrupt, pci_irq_line ? SA_SHIRQ : 0, fi->name, host);
  1380. if (irqval) {
  1381. printk("iph5526.c : Unable to get IRQ %d (irqval = %d).n", pci_irq_line, irqval);
  1382. scsi_unregister(host);
  1383. kfree(fc[count]);
  1384. fc[count] = NULL;
  1385. continue;
  1386. }
  1387. host->irq = fi->irq = pci_irq_line;
  1388. pci_irq_line = 0;
  1389. fi->clone_id = clone_list[i].vendor_id;
  1390. }
  1391. if (!initialize_register_pointers(fi) || !tachyon_init(fi)) {
  1392. printk("iph5526.c: TACHYON initialization failed for card # %d!!!n", count + 1);
  1393. free_irq(host->irq, host);
  1394. scsi_unregister(host);
  1395. if (fi) 
  1396. clean_up_memory(fi);
  1397. kfree(fc[count]);
  1398. fc[count] = NULL;
  1399. break;
  1400. }
  1401. DPRINTK1("Fibre Channel card initialized");
  1402. /* Wait for the Link to come up and the login process 
  1403.  * to complete. 
  1404.  */
  1405. for(timeout = jiffies + 10*HZ; time_before(jiffies, timeout) && ((fi->g.link_up == FALSE) || (fi->g.port_discovery == TRUE) || (fi->g.explore_fabric == TRUE) || (fi->g.perform_adisc == TRUE));)
  1406. {
  1407. cpu_relax();
  1408. barrier();
  1409. }
  1410. count++;
  1411. no_of_hosts++;
  1412. }
  1413. DPRINTK1("no_of_hosts = %d",no_of_hosts);
  1414. /* This is to make sure that the ACC to the PRLI comes in 
  1415.  * for the last ALPA. 
  1416.  */
  1417. mdelay(1000); /* Ugly! Let the Gods forgive me */
  1418. DPRINTK1("leaving iph5526_detectn");
  1419. return no_of_hosts;
  1420. }
  1421. int iph5526_biosparam(Disk * disk, kdev_t n, int ip[])
  1422. {
  1423. int size = disk->capacity;
  1424. ip[0] = 64;
  1425. ip[1] = 32;
  1426. ip[2] = size >> 11;
  1427. if (ip[2] > 1024) {
  1428. ip[0] = 255;
  1429. ip[1] = 63;
  1430. ip[2] = size / (ip[0] * ip[1]);
  1431. }
  1432. return 0;
  1433. }
  1434. int iph5526_queuecommand(Scsi_Cmnd *Cmnd, void (*done) (Scsi_Cmnd *))
  1435. {
  1436. int int_required = 0;
  1437. u_int r_ctl = FC4_DEVICE_DATA | UNSOLICITED_COMMAND;
  1438. u_int type = TYPE_FCP | SEQUENCE_INITIATIVE;
  1439. u_int frame_class = Cmnd->target;
  1440. u_short ox_id = OX_ID_FIRST_SEQUENCE;
  1441. struct Scsi_Host *host = Cmnd->host;
  1442. struct iph5526_hostdata *hostdata = (struct iph5526_hostdata*)host->hostdata;
  1443. struct fc_info *fi = hostdata->fi;
  1444. struct fc_node_info *q;
  1445. u_long flags;
  1446. ENTER("iph5526_queuecommand");
  1447. spin_lock_irqsave(&fi->fc_lock, flags);
  1448. Cmnd->scsi_done = done;
  1449. if (Cmnd->device->tagged_supported) {
  1450. switch(Cmnd->tag) {
  1451. case SIMPLE_QUEUE_TAG:
  1452. hostdata->cmnd.fcp_cntl = FCP_CNTL_QTYPE_SIMPLE;
  1453. break;
  1454. case HEAD_OF_QUEUE_TAG:
  1455. hostdata->cmnd.fcp_cntl = FCP_CNTL_QTYPE_HEAD_OF_Q;
  1456. break;
  1457. case  ORDERED_QUEUE_TAG:
  1458. hostdata->cmnd.fcp_cntl = FCP_CNTL_QTYPE_ORDERED;
  1459. break;
  1460. default:
  1461. if ((jiffies - hostdata->tag_ages[Cmnd->target]) > (5 * HZ)) {
  1462. hostdata->cmnd.fcp_cntl = FCP_CNTL_QTYPE_ORDERED;
  1463. hostdata->tag_ages[Cmnd->target] = jiffies;
  1464. }
  1465. else
  1466. hostdata->cmnd.fcp_cntl = FCP_CNTL_QTYPE_SIMPLE;
  1467. break;
  1468. }
  1469. }
  1470. /*else
  1471. hostdata->cmnd.fcp_cntl = FCP_CNTL_QTYPE_UNTAGGED;
  1472. */
  1473. hostdata->cmnd.fcp_addr[3] = 0;
  1474. hostdata->cmnd.fcp_addr[2] = 0;
  1475. hostdata->cmnd.fcp_addr[1] = 0;
  1476. hostdata->cmnd.fcp_addr[0] = htons(Cmnd->lun);
  1477. memcpy(&hostdata->cmnd.fcp_cdb, Cmnd->cmnd, Cmnd->cmd_len);
  1478. hostdata->cmnd.fcp_data_len = htonl(Cmnd->request_bufflen);
  1479. /* Get an used OX_ID. We could have pending commands.
  1480.  */
  1481. if (get_scsi_oxid(fi)) {
  1482. spin_unlock_irqrestore(&fi->fc_lock, flags);
  1483. return 1;
  1484. }
  1485. fi->q.free_scsi_oxid[fi->g.scsi_oxid] = OXID_INUSE;
  1486. /* Maintain a handler so that we can associate the done() function
  1487.  * on completion of the SCSI command. 
  1488.  */
  1489. hostdata->cmnd_handler[fi->g.scsi_oxid] = Cmnd;
  1490. switch(Cmnd->cmnd[0]) {
  1491. case WRITE_6:
  1492. case WRITE_10:
  1493. case WRITE_12:
  1494. fi->g.type_of_frame = FC_SCSI_WRITE;
  1495. hostdata->cmnd.fcp_cntl = htonl(FCP_CNTL_WRITE | hostdata->cmnd.fcp_cntl);
  1496. break;
  1497. default:
  1498. fi->g.type_of_frame = FC_SCSI_READ;
  1499. hostdata->cmnd.fcp_cntl = htonl(FCP_CNTL_READ | hostdata->cmnd.fcp_cntl);
  1500. }
  1501. memcpy(fi->q.ptr_fcp_cmnd[fi->q.fcp_cmnd_indx], &(hostdata->cmnd), sizeof(fcp_cmd));
  1502. q = resolve_target(fi, Cmnd->target);
  1503. if (q == NULL) {
  1504. u_int bad_id = fi->g.my_ddaa | 0xFE;
  1505. /* We transmit to an non-existant AL_PA so that the "done" 
  1506.  * function can be called while receiving the interrupt 
  1507.  * due to a Timeout for a bad AL_PA. In a PTP configuration,
  1508.  * the int_required field is set, since there is no notion
  1509.  * of AL_PAs. This approach sucks, but works alright!
  1510.  */
  1511. if (fi->g.ptp_up == TRUE)
  1512. int_required = 1;
  1513. tx_exchange(fi, (char *)(&(hostdata->cmnd)), sizeof(fcp_cmd), r_ctl, type, bad_id, fi->g.my_mtu, int_required, ox_id, FC_SCSI_BAD_TARGET);
  1514. spin_unlock_irqrestore(&fi->fc_lock, flags);
  1515. DPRINTK1("Target ID %x not present", Cmnd->target);
  1516. return 0;
  1517. }
  1518. if (q->login == LOGIN_COMPLETED) {
  1519. if (add_to_sest(fi, Cmnd, q)) {
  1520. DPRINTK1("add_to_sest() failed.");
  1521. spin_unlock_irqrestore(&fi->fc_lock, flags);
  1522. return 0;
  1523. }
  1524. tx_exchange(fi, (char *)(fi->q.ptr_fcp_cmnd[fi->q.fcp_cmnd_indx]), sizeof(fcp_cmd), r_ctl, type, q->d_id, q->mtu, int_required, ox_id, frame_class << 16);
  1525. update_FCP_CMND_indx(fi);
  1526. }
  1527. spin_unlock_irqrestore(&fi->fc_lock, flags);
  1528. /* If q != NULL, then we have a SCSI Target. 
  1529.  * If q->login != LOGIN_COMPLETED, then that device could be 
  1530.  * offline temporarily. So we let the command to time-out. 
  1531.  */
  1532. LEAVE("iph5526_queuecommand");
  1533. return 0;
  1534. }
  1535. int iph5526_abort(Scsi_Cmnd *Cmnd)
  1536. {
  1537. struct Scsi_Host *host = Cmnd->host;
  1538. struct iph5526_hostdata *hostdata = (struct iph5526_hostdata *)host->hostdata;
  1539. struct fc_info *fi = hostdata->fi;
  1540. struct fc_node_info *q;
  1541. u_int r_ctl = FC4_DEVICE_DATA | UNSOLICITED_COMMAND;
  1542. u_int type = TYPE_FCP | SEQUENCE_INITIATIVE;
  1543. u_short ox_id = OX_ID_FIRST_SEQUENCE;
  1544. int int_required = 1, i, abort_status = FALSE;
  1545. u_long flags;
  1546. ENTER("iph5526_abort");
  1547. spin_lock_irqsave(&fi->fc_lock, flags);
  1548. q = resolve_target(fi, Cmnd->target);
  1549. if (q == NULL) {
  1550. u_int bad_id = fi->g.my_ddaa | 0xFE;
  1551. /* This should not happen as we should always be able to
  1552.  * resolve a target id. But, jus in case...
  1553.  * We transmit to an non-existant AL_PA so that the done 
  1554.  * function can be called while receiving the interrupt 
  1555.  * for a bad AL_PA. 
  1556.  */
  1557. DPRINTK1("Unresolved Target ID!");
  1558. tx_exchange(fi, (char *)(&(hostdata->cmnd)), sizeof(fcp_cmd), r_ctl, type, bad_id, fi->g.my_mtu, int_required, ox_id, FC_SCSI_BAD_TARGET);
  1559. DPRINTK1("Target ID %x not present", Cmnd->target);
  1560. spin_unlock_irqrestore(&fi->fc_lock, flags);
  1561. return FAILED;
  1562. }
  1563. /* If q != NULL, then we have a SCSI Target. If 
  1564.  * q->login != LOGIN_COMPLETED, then that device could 
  1565.  * be offline temporarily. So we let the command to time-out. 
  1566.  */
  1567. /* Get the OX_ID for the Command to be aborted.
  1568.  */
  1569. for (i = 0; i <= MAX_SCSI_XID; i++) {
  1570. if (hostdata->cmnd_handler[i] == Cmnd) {
  1571. hostdata->cmnd_handler[i] = NULL;
  1572. ox_id = i;
  1573. break;
  1574. }
  1575. }
  1576. if (i > MAX_SCSI_XID) {
  1577. T_MSG("Command could not be resolved to OX_ID");
  1578. spin_unlock_irqrestore(&fi->fc_lock, flags);
  1579. return FAILED;
  1580. }
  1581. switch(Cmnd->cmnd[0]) {
  1582. case WRITE_6:
  1583. case WRITE_10:
  1584. case WRITE_12:
  1585. break;
  1586. default:
  1587. ox_id |= SCSI_READ_BIT;
  1588. }
  1589. abort_status = abort_exchange(fi, ox_id);
  1590. if ((q->login == LOGIN_COMPLETED) && (abort_status == TRUE)) {
  1591. /* Then, transmit an ABTS to the target. The rest 
  1592.  * is done when the BA_ACC is received for the ABTS.
  1593.      */
  1594. tx_abts(fi, q->d_id, ox_id);
  1595. }
  1596. else {
  1597. u_int STE_bit;
  1598. u_short x_id;
  1599. /* Invalidate resources for that Exchange.
  1600.  */
  1601. x_id = ox_id & MAX_SCSI_XID;
  1602. STE_bit = ntohl(*fi->q.ptr_sest[x_id]);
  1603. if (STE_bit & SEST_V) {
  1604. *(fi->q.ptr_sest[x_id]) &= htonl(SEST_INV);
  1605. invalidate_SEST_entry(fi, ox_id);
  1606. }
  1607. }
  1608. LEAVE("iph5526_abort");
  1609. spin_unlock_irqrestore(&fi->fc_lock, flags);
  1610. return SUCCESS;
  1611. }
  1612. static int abort_exchange(struct fc_info *fi, u_short ox_id)
  1613. {
  1614. u_short x_id;
  1615. volatile u_int flush_SEST, STE_bit;
  1616. x_id = ox_id & MAX_SCSI_XID;
  1617. DPRINTK1("Aborting Exchange %x", ox_id);
  1618. STE_bit = ntohl(*fi->q.ptr_sest[x_id]);
  1619. /* Is the Exchange still active?.
  1620.  */
  1621. if (STE_bit & SEST_V) {
  1622. if (ox_id & SCSI_READ_BIT) {
  1623. /* If the Exchange to be aborted is Inbound, 
  1624.  * Flush the SEST Entry from Tachyon's Cache.
  1625.  */
  1626. *(fi->q.ptr_sest[x_id]) &= htonl(SEST_INV);
  1627. flush_tachyon_cache(fi, ox_id);
  1628. flush_SEST = readl(fi->t_r.ptr_tach_flush_oxid_reg);
  1629. while ((flush_SEST & 0x80000000) != 0) 
  1630. flush_SEST = readl(fi->t_r.ptr_tach_flush_oxid_reg);
  1631. STE_bit = ntohl(*fi->q.ptr_sest[x_id]);
  1632. while ((STE_bit & 0x80000000) != 0)
  1633. STE_bit = ntohl(*fi->q.ptr_sest[x_id]);
  1634. flush_SEST = readl(fi->t_r.ptr_tach_flush_oxid_reg);
  1635. invalidate_SEST_entry(fi, ox_id);
  1636. }
  1637. else {
  1638. int i;
  1639. u_int *ptr_edb;
  1640. /* For In-Order Reassembly, the following is done:
  1641.  * First, write zero as the buffer length in the EDB. 
  1642.    */
  1643. ptr_edb = bus_to_virt(ntohl(*(fi->q.ptr_sest[x_id] + 7)));
  1644. for (i = 0; i < EDB_LEN; i++)
  1645. if (fi->q.ptr_edb[i] == ptr_edb)
  1646. break;
  1647. if (i < EDB_LEN) 
  1648. *ptr_edb = *ptr_edb & 0x0000FFFF;
  1649. else
  1650. T_MSG("EDB not found while clearing in abort_exchange()");
  1651. }
  1652. DPRINTK1("Exchange %x invalidated", ox_id);
  1653. return TRUE;
  1654. }
  1655. else {
  1656. DPRINTK1("SEST Entry for exchange %x not valid", ox_id);
  1657. return FALSE;
  1658. }
  1659. }
  1660. static void flush_tachyon_cache(struct fc_info *fi, u_short ox_id)
  1661. {
  1662. volatile u_int tachyon_status;
  1663. if (fi->g.loop_up == TRUE) {
  1664. writel(HOST_CONTROL, fi->t_r.ptr_fm_control_reg);
  1665. /* Make sure that the Inbound FIFO is empty.
  1666.  */
  1667. do {
  1668. tachyon_status = readl(fi->t_r.ptr_tach_status_reg);
  1669. udelay(200);
  1670. }while ((tachyon_status & RECEIVE_FIFO_EMPTY) == 0);
  1671. /* Ok. Go ahead and flushhhhhhhhh!
  1672.  */
  1673. writel(0x80000000 | ox_id, fi->t_r.ptr_tach_flush_oxid_reg);
  1674. writel(EXIT_HOST_CONTROL, fi->t_r.ptr_fm_control_reg);
  1675. return;
  1676. }
  1677. if (fi->g.ptp_up == TRUE) {
  1678. take_tachyon_offline(fi);
  1679. /* Make sure that the Inbound FIFO is empty.
  1680.  */
  1681. do {
  1682. tachyon_status = readl(fi->t_r.ptr_tach_status_reg);
  1683. udelay(200);
  1684. }while ((tachyon_status & RECEIVE_FIFO_EMPTY) == 0);
  1685. writel(0x80000000 | ox_id, fi->t_r.ptr_tach_flush_oxid_reg);
  1686. /* Write the Initialize command to the FM Control reg.
  1687.  */
  1688. fi->g.n_port_try = TRUE;
  1689. DPRINTK1("In abort_exchange, TACHYON initializing as N_Port...n");
  1690. writel(INITIALIZE, fi->t_r.ptr_fm_control_reg);
  1691. }
  1692. }
  1693. static struct fc_node_info *resolve_target(struct fc_info *fi, u_char target)
  1694. {
  1695. struct fc_node_info *temp = fi->node_info_list;
  1696. while(temp != NULL)
  1697. if (temp->target_id == target) {
  1698. if ((temp->scsi == TARGET) && (temp->login == LOGIN_COMPLETED))
  1699. return temp;
  1700. else {
  1701. if (temp->login != LOGIN_COMPLETED) {
  1702. /* The Target is not currently logged in.
  1703.  * It could be a Target on the Local Loop or
  1704.  * on a Remote Loop connected through a switch.
  1705.  * In either case, we will know whenever the Target
  1706.  * comes On-Line again. We let the command to 
  1707.  * time-out so that it gets retried.
  1708.  */
  1709. T_MSG("Target %d not logged in.", temp->target_id);
  1710. tx_logi(fi, ELS_PLOGI, temp->d_id);
  1711. return temp;
  1712. }
  1713. else {
  1714. if (temp->scsi != TARGET) {
  1715. /* For some reason, we did not get a response to
  1716.  * PRLI. Letz try it again...
  1717.  */
  1718. DPRINTK1("Node not PRLIied. Txing PRLI...");
  1719. tx_prli(fi, ELS_PRLI, temp->d_id, OX_ID_FIRST_SEQUENCE);
  1720. }
  1721. }
  1722. return temp;
  1723. }
  1724. }
  1725. else
  1726. temp = temp->next;
  1727. return NULL;
  1728. }
  1729. static int add_to_sest(struct fc_info *fi, Scsi_Cmnd *Cmnd, struct fc_node_info *ni)
  1730. {
  1731. /* we have at least 1 buffer, the terminator */
  1732. int no_of_sdb_buffers = 1, i; 
  1733. int no_of_edb_buffers = 0; 
  1734. u_int *req_buffer = (u_int *)Cmnd->request_buffer;
  1735. u_int *ptr_sdb = NULL;
  1736. struct scatterlist *sl1, *sl2 = NULL;
  1737. int no_of_sg = 0;
  1738. switch(fi->g.type_of_frame) {
  1739. case FC_SCSI_READ:
  1740. fi->g.inb_sest_entry.flags_and_byte_offset = htonl(INB_SEST_VED);
  1741. fi->g.inb_sest_entry.byte_count = 0;
  1742. fi->g.inb_sest_entry.no_of_recvd_frames = 0;
  1743. fi->g.inb_sest_entry.no_of_expected_frames = 0;
  1744. fi->g.inb_sest_entry.last_fctl = 0;
  1745. if (Cmnd->use_sg) {
  1746. no_of_sg = Cmnd->use_sg;
  1747. sl1 = sl2 = (struct scatterlist *)Cmnd->request_buffer;
  1748. for (i = 0; i < no_of_sg; i++) {
  1749. no_of_sdb_buffers += sl1->length / SEST_BUFFER_SIZE;
  1750. if (sl1->length % SEST_BUFFER_SIZE)
  1751. no_of_sdb_buffers++;
  1752. sl1++;
  1753. }
  1754. }
  1755. else {
  1756. no_of_sdb_buffers += Cmnd->request_bufflen / SEST_BUFFER_SIZE;
  1757. if (Cmnd->request_bufflen % SEST_BUFFER_SIZE)
  1758. no_of_sdb_buffers++;
  1759. } /* if !use_sg */
  1760. /* We are working with the premise that at the max we would
  1761.  * get a scatter-gather buffer containing 63 buffers
  1762.  * of size 1024 bytes each. Is it a _bad_ assumption?
  1763.  */
  1764. if (no_of_sdb_buffers > 512) {
  1765. T_MSG("Number of SDB buffers needed = %d", no_of_sdb_buffers);
  1766. T_MSG("Disable Scatter-Gather!!!");
  1767. return 1;
  1768. }
  1769. /* Store it in the sdb_table so that we can retrieve that
  1770.  * free up the memory when the Read Command completes.
  1771.  */
  1772. if (get_free_SDB(fi))
  1773. return 1;
  1774. ptr_sdb = fi->q.ptr_sdb_slot[fi->q.sdb_indx];
  1775. fi->q.sdb_slot_status[fi->q.sdb_indx] = SDB_BUSY;
  1776. fi->g.inb_sest_entry.sdb_address = htonl(virt_to_bus(ptr_sdb));
  1777. if (Cmnd->use_sg) {
  1778. int count = 0, j;
  1779. for(i = 0; i < no_of_sg; i++) {
  1780. char *addr_ptr = sl2->address;
  1781. count = sl2->length / SEST_BUFFER_SIZE;
  1782. if (sl2->length % SEST_BUFFER_SIZE)
  1783. count++;
  1784. for (j = 0; j < count; j++) {
  1785. *(ptr_sdb) = htonl(virt_to_bus(addr_ptr));
  1786. addr_ptr += SEST_BUFFER_SIZE;
  1787. ptr_sdb++;
  1788. }
  1789. count = 0;
  1790. sl2++;
  1791. }
  1792. }
  1793. else {
  1794. for (i = 0; i < no_of_sdb_buffers - 1; i++) {
  1795. *(ptr_sdb) = htonl(virt_to_bus(req_buffer));
  1796. req_buffer += SEST_BUFFER_SIZE/4;
  1797. ptr_sdb++;
  1798. }
  1799. }
  1800. *(ptr_sdb) = htonl(0x1); /* Terminator */
  1801. /* The scratch pad is used to hold the index into the SDB.
  1802.  */
  1803. fi->g.inb_sest_entry.scratch_pad = fi->q.sdb_indx;
  1804. fi->g.inb_sest_entry.expected_ro = 0;
  1805. fi->g.inb_sest_entry.buffer_index = 0;
  1806. fi->g.inb_sest_entry.buffer_offset = 0;
  1807. memcpy(fi->q.ptr_sest[fi->g.scsi_oxid], &fi->g.inb_sest_entry, sizeof(INB_SEST_ENTRY));
  1808. break;
  1809. case FC_SCSI_WRITE:
  1810. fi->g.outb_sest_entry.flags_and_did = htonl(OUTB_SEST_VED | ni->d_id);
  1811. fi->g.outb_sest_entry.max_frame_len = htons(ni->mtu << 4);
  1812. fi->g.outb_sest_entry.cntl = htons(ODB_CLASS_3 | ODB_EE_CREDIT | ODB_NO_INT | ODB_NO_COMP);
  1813. fi->g.outb_sest_entry.total_seq_length = INV_SEQ_LEN;
  1814. fi->g.outb_sest_entry.link = htons(OUTB_SEST_LINK);
  1815. fi->g.outb_sest_entry.transaction_id = htonl(fi->g.scsi_oxid);
  1816. fi->g.outb_sest_entry.seq_id = fi->g.seq_id;
  1817. fi->g.outb_sest_entry.reserved = 0x0;
  1818. fi->g.outb_sest_entry.header_length = htons(TACHYON_HEADER_LEN);
  1819. {
  1820. u_char df_ctl = 0;
  1821. u_short rx_id = RX_ID_FIRST_SEQUENCE;
  1822. u_int r_ctl = FC4_DEVICE_DATA | SOLICITED_DATA;
  1823. u_int type = TYPE_FCP | SEQUENCE_INITIATIVE;
  1824. /* Multi Frame Sequence ? If yes, set RO bit. 
  1825.  */
  1826. if (Cmnd->request_bufflen > ni->mtu)
  1827. type |= RELATIVE_OFF_PRESENT;
  1828. build_tachyon_header(fi, fi->g.my_id, r_ctl, ni->d_id, type, fi->g.seq_id, df_ctl, fi->g.scsi_oxid, rx_id, NULL);
  1829. if (get_free_header(fi) || get_free_EDB(fi))
  1830. return 1;
  1831. memcpy(fi->q.ptr_tachyon_header[fi->q.tachyon_header_indx], &(fi->g.tach_header), TACHYON_HEADER_LEN);
  1832. fi->g.outb_sest_entry.header_address = htonl(virt_to_bus(fi->q.ptr_tachyon_header[fi->q.tachyon_header_indx]));
  1833. update_tachyon_header_indx(fi);
  1834. }
  1835. if (Cmnd->use_sg) {
  1836. no_of_sg = Cmnd->use_sg;
  1837. sl1 = sl2 = (struct scatterlist *)Cmnd->request_buffer;
  1838. for (i = 0; i < no_of_sg; i++) {
  1839. no_of_edb_buffers += sl1->length / SEST_BUFFER_SIZE;
  1840. if (sl1->length % SEST_BUFFER_SIZE)
  1841. no_of_edb_buffers++;
  1842. sl1++;
  1843. }
  1844. }
  1845. else {
  1846. no_of_edb_buffers += Cmnd->request_bufflen / SEST_BUFFER_SIZE;
  1847. if (Cmnd->request_bufflen % SEST_BUFFER_SIZE)
  1848. no_of_edb_buffers++;
  1849. } /* if !use_sg */
  1850. /* We need "no_of_edb_buffers" _contiguous_ EDBs 
  1851.  * that are FREE. Check for that first.
  1852.  */
  1853. for (i = 0; i < no_of_edb_buffers; i++) {
  1854. int j;
  1855. if ((fi->q.edb_buffer_indx + no_of_edb_buffers) >= EDB_LEN)
  1856. fi->q.edb_buffer_indx = 0;
  1857. if (fi->q.free_edb_list[fi->q.edb_buffer_indx + i] != EDB_FREE) {
  1858. for (j = 0; j < i; j++)
  1859. update_EDB_indx(fi);
  1860. if (get_free_EDB(fi))
  1861. return 1;
  1862. i = 0;
  1863. }
  1864. }
  1865. /* We got enuff FREE EDBs.
  1866.  */
  1867. if (Cmnd->use_sg) {
  1868. fi->g.outb_sest_entry.edb_address = htonl(virt_to_bus(fi->q.ptr_edb[fi->q.edb_buffer_indx]));
  1869. sl1 = (struct scatterlist *)Cmnd->request_buffer;
  1870. for(i = 0; i < no_of_sg; i++) {
  1871. int count = 0, j;
  1872. count = sl1->length / SEST_BUFFER_SIZE;
  1873. for (j = 0; j < count; j++) {
  1874. build_EDB(fi, (char *)sl1->address, 0, SEST_BUFFER_SIZE);
  1875. memcpy(fi->q.ptr_edb[fi->q.edb_buffer_indx], &(fi->g.edb), sizeof(EDB));
  1876. /* Mark this EDB as being in use */
  1877. fi->q.free_edb_list[fi->q.edb_buffer_indx] = EDB_BUSY;
  1878. /* We have already made sure that we have enuff
  1879.      * free EDBs that are contiguous. So this is 
  1880.  * safe.
  1881.      */
  1882. update_EDB_indx(fi);
  1883. sl1->address += SEST_BUFFER_SIZE;
  1884. }
  1885. /* Just in case itz not a multiple of 
  1886.  * SEST_BUFFER_SIZE bytes.
  1887.  */
  1888. if (sl1->length % SEST_BUFFER_SIZE) {
  1889. build_EDB(fi, (char *)sl1->address, 0, sl1->length % SEST_BUFFER_SIZE);
  1890. memcpy(fi->q.ptr_edb[fi->q.edb_buffer_indx], &(fi->g.edb), sizeof(EDB));
  1891. fi->q.free_edb_list[fi->q.edb_buffer_indx] = EDB_BUSY;
  1892. update_EDB_indx(fi);
  1893. }
  1894. sl1++;
  1895. }
  1896. /* The last EDB is special. It needs the "end bit" to
  1897.  * be set.
  1898.  */
  1899. *(fi->q.ptr_edb[fi->q.edb_buffer_indx - 1] + 1) = *(fi->q.ptr_edb[fi->q.edb_buffer_indx - 1] + 1) | ntohs(EDB_END);
  1900. }
  1901. else {
  1902. int count = 0, j;
  1903. fi->g.outb_sest_entry.edb_address = htonl(virt_to_bus(fi->q.ptr_edb[fi->q.edb_buffer_indx]));
  1904. count = Cmnd->request_bufflen / SEST_BUFFER_SIZE;
  1905. for (j = 0; j < count; j++) {
  1906. build_EDB(fi, (char *)req_buffer, 0, SEST_BUFFER_SIZE);
  1907. memcpy(fi->q.ptr_edb[fi->q.edb_buffer_indx], &(fi->g.edb), sizeof(EDB));
  1908. /* Mark this EDB as being in use */
  1909. fi->q.free_edb_list[fi->q.edb_buffer_indx] = EDB_BUSY;
  1910. /* We have already made sure that we have enuff
  1911.      * free EDBs that are contiguous. So this is 
  1912.  * safe.
  1913.      */
  1914. update_EDB_indx(fi);
  1915. req_buffer += SEST_BUFFER_SIZE;
  1916. }
  1917. /* Just in case itz not a multiple of 
  1918.  * SEST_BUFFER_SIZE bytes.
  1919.  */
  1920. if (Cmnd->request_bufflen % SEST_BUFFER_SIZE) {
  1921. build_EDB(fi, (char *)req_buffer, EDB_END, Cmnd->request_bufflen % SEST_BUFFER_SIZE);
  1922. memcpy(fi->q.ptr_edb[fi->q.edb_buffer_indx], &(fi->g.edb), sizeof(EDB));
  1923. fi->q.free_edb_list[fi->q.edb_buffer_indx] = EDB_BUSY;
  1924. update_EDB_indx(fi);
  1925. }
  1926. else {
  1927. /* Mark the last EDB as the "end edb".
  1928.  */
  1929. *(fi->q.ptr_edb[fi->q.edb_buffer_indx - 1] + 1) = *(fi->q.ptr_edb[fi->q.edb_buffer_indx - 1] + 1) | htons(EDB_END);
  1930. }
  1931. }
  1932. /* Finally we have something to send!.
  1933.  */
  1934. memcpy(fi->q.ptr_sest[fi->g.scsi_oxid], &fi->g.outb_sest_entry, sizeof(OUTB_SEST_ENTRY));
  1935. break;
  1936. }
  1937. return 0;
  1938. }
  1939. static void update_FCP_CMND_indx(struct fc_info *fi)
  1940. {
  1941. fi->q.fcp_cmnd_indx++;
  1942. if (fi->q.fcp_cmnd_indx == NO_OF_FCP_CMNDS)
  1943. fi->q.fcp_cmnd_indx = 0;
  1944. }
  1945. static int get_scsi_oxid(struct fc_info *fi)
  1946. {
  1947. u_short initial_oxid = fi->g.scsi_oxid;
  1948. /* Check if the OX_ID is in use.
  1949.  * We could have an outstanding SCSI command.
  1950.  */
  1951. while (fi->q.free_scsi_oxid[fi->g.scsi_oxid] != OXID_AVAILABLE) {
  1952. update_scsi_oxid(fi);
  1953. if (fi->g.scsi_oxid == initial_oxid) {
  1954. T_MSG("No free OX_IDs avaliable")
  1955. reset_tachyon(fi, SOFTWARE_RESET);
  1956. return 1;
  1957. }
  1958. }
  1959. return 0;
  1960. }
  1961. static void update_scsi_oxid(struct fc_info *fi)
  1962. {
  1963. fi->g.scsi_oxid++;
  1964. if (fi->g.scsi_oxid == (MAX_SCSI_XID + 1))
  1965. fi->g.scsi_oxid = 0;
  1966. }
  1967. static int get_free_SDB(struct fc_info *fi)
  1968. {
  1969. unsigned int initial_indx = fi->q.sdb_indx;
  1970. /* Check if the SDB is in use.
  1971.  * We could have an outstanding SCSI Read command.
  1972.  * We should find a free slot as we can queue a
  1973.  * maximum of 32 SCSI commands only. 
  1974.  */
  1975. while (fi->q.sdb_slot_status[fi->q.sdb_indx] != SDB_FREE) {
  1976. update_SDB_indx(fi);
  1977. if (fi->q.sdb_indx == initial_indx) {
  1978. T_MSG("No free SDB buffers avaliable")
  1979. reset_tachyon(fi, SOFTWARE_RESET);
  1980. return 1;
  1981. }
  1982. }
  1983. return 0;
  1984. }
  1985. static void update_SDB_indx(struct fc_info *fi)
  1986. {
  1987. fi->q.sdb_indx++;
  1988. if (fi->q.sdb_indx == NO_OF_SDB_ENTRIES)
  1989. fi->q.sdb_indx = 0;
  1990. }
  1991. int iph5526_release(struct Scsi_Host *host)
  1992. {
  1993. struct iph5526_hostdata *hostdata = (struct iph5526_hostdata*)host->hostdata;
  1994. struct fc_info *fi = hostdata->fi;
  1995. free_irq(host->irq, host);
  1996. iounmap(fi->g.mem_base);
  1997. return 0;
  1998. }
  1999. const char *iph5526_info(struct Scsi_Host *host)
  2000. {
  2001. static char buf[80];
  2002. sprintf(buf, "Interphase 5526 Fibre Channel PCI SCSI Adapter using IRQ %dn", host->irq);
  2003. return buf;
  2004. }
  2005. #ifdef MODULE
  2006. #define NAMELEN 8 /* # of chars for storing dev->name */
  2007. static struct net_device *dev_fc[MAX_FC_CARDS];
  2008. static int io;
  2009. static int irq;
  2010. static int bad; /* 0xbad = bad sig or no reset ack */
  2011. static int scsi_registered;
  2012. int init_module(void)
  2013. {
  2014. int i = 0;
  2015. driver_template.module = &__this_module;
  2016. scsi_register_module(MODULE_SCSI_HA, &driver_template);
  2017. if (driver_template.present)
  2018. scsi_registered = TRUE; 
  2019. else {
  2020. printk("iph5526: SCSI registeration failed!!!n");
  2021. scsi_registered = FALSE;
  2022. scsi_unregister_module(MODULE_SCSI_HA, &driver_template);
  2023. }
  2024. while(fc[i] != NULL) {
  2025. dev_fc[i] = NULL;
  2026. dev_fc[i] = init_fcdev(dev_fc[i], 0);
  2027. if (dev_fc[i] == NULL) {
  2028. printk("iph5526.c: init_fcdev failed for card #%dn", i+1);
  2029. break;
  2030. }
  2031. dev_fc[i]->irq = irq;
  2032. dev_fc[i]->mem_end = bad;
  2033. dev_fc[i]->base_addr = io;
  2034. dev_fc[i]->init = iph5526_probe;
  2035. dev_fc[i]->priv = fc[i];
  2036. fc[i]->dev = dev_fc[i];
  2037. if (register_fcdev(dev_fc[i]) != 0) {
  2038. kfree(dev_fc[i]);
  2039. dev_fc[i] = NULL;
  2040. if (i == 0) {
  2041. printk("iph5526.c: IP registeration failed!!!n");
  2042. return -ENODEV;
  2043. }
  2044. }
  2045. i++;
  2046. }
  2047. if (i == 0)
  2048. return -ENODEV;
  2049. return 0;
  2050. }
  2051. void cleanup_module(void)
  2052. {
  2053. int i = 0;
  2054. while(fc[i] != NULL) {
  2055. struct net_device *dev = fc[i]->dev;
  2056. void *priv = dev->priv;
  2057. fc[i]->g.dont_init = TRUE;
  2058. take_tachyon_offline(fc[i]);
  2059. unregister_fcdev(dev);
  2060. clean_up_memory(fc[i]);
  2061. if (dev->priv)
  2062. kfree(priv);
  2063. kfree(dev);
  2064. dev = NULL;
  2065. i++;
  2066. }
  2067. if (scsi_registered == TRUE)
  2068. scsi_unregister_module(MODULE_SCSI_HA, &driver_template); 
  2069. }
  2070. #endif /* MODULE */
  2071. void clean_up_memory(struct fc_info *fi)
  2072. {
  2073. int i,j;
  2074. ENTER("clean_up_memory");
  2075. if (fi->q.ptr_mfsbq_base)
  2076. free_pages((u_long)bus_to_virt(ntohl(*(fi->q.ptr_mfsbq_base))), 5);
  2077. DPRINTK("after kfree2");
  2078. for (i = 0; i < SFSBQ_LENGTH; i++)
  2079. for (j = 0; j < NO_OF_ENTRIES; j++)
  2080. if (fi->q.ptr_sfs_buffers[i*NO_OF_ENTRIES + j])
  2081. kfree(fi->q.ptr_sfs_buffers[i*NO_OF_ENTRIES + j]);
  2082. DPRINTK("after kfree1");
  2083. if (fi->q.ptr_ocq_base)
  2084. free_page((u_long)fi->q.ptr_ocq_base);
  2085. if (fi->q.ptr_imq_base)
  2086. free_page((u_long)fi->q.ptr_imq_base);
  2087. if (fi->q.ptr_mfsbq_base)
  2088. free_page((u_long)fi->q.ptr_mfsbq_base);
  2089. if (fi->q.ptr_sfsbq_base)
  2090. free_page((u_long)fi->q.ptr_sfsbq_base);
  2091. if (fi->q.ptr_edb_base)
  2092. free_pages((u_long)fi->q.ptr_edb_base, 5);
  2093. if (fi->q.ptr_sest_base)
  2094. free_pages((u_long)fi->q.ptr_sest_base, 5);
  2095. if (fi->q.ptr_tachyon_header_base)
  2096. free_page((u_long)fi->q.ptr_tachyon_header_base);
  2097. if (fi->q.ptr_sdb_base)
  2098. free_pages((u_long)fi->q.ptr_sdb_base, 5);
  2099. if (fi->q.ptr_fcp_cmnd_base)
  2100. free_page((u_long)fi->q.ptr_fcp_cmnd_base);
  2101. DPRINTK("after free_pages"); 
  2102. if (fi->q.ptr_host_ocq_cons_indx)
  2103. kfree(fi->q.ptr_host_ocq_cons_indx);
  2104. if (fi->q.ptr_host_hpcq_cons_indx)
  2105. kfree(fi->q.ptr_host_hpcq_cons_indx);
  2106. if (fi->q.ptr_host_imq_prod_indx)
  2107. kfree(fi->q.ptr_host_imq_prod_indx);
  2108. DPRINTK("after kfree3");
  2109. while (fi->node_info_list) {
  2110. struct fc_node_info *temp_list = fi->node_info_list;
  2111. fi->node_info_list = fi->node_info_list->next;
  2112. kfree(temp_list);
  2113. }
  2114. while (fi->ox_id_list) {
  2115. struct ox_id_els_map *temp = fi->ox_id_list;
  2116. fi->ox_id_list = fi->ox_id_list->next;
  2117. kfree(temp);
  2118. }
  2119. LEAVE("clean_up_memory");
  2120. }
  2121. static int initialize_register_pointers(struct fc_info *fi)
  2122. {
  2123. ENTER("initialize_register_pointers");
  2124. if(fi->g.tachyon_base == 0)
  2125. return -ENOMEM; 
  2126. fi->i_r.ptr_ichip_hw_control_reg = ICHIP_HW_CONTROL_REG_OFF + fi->g.tachyon_base;
  2127. fi->i_r.ptr_ichip_hw_status_reg = ICHIP_HW_STATUS_REG_OFF + fi->g.tachyon_base;
  2128. fi->i_r.ptr_ichip_hw_addr_mask_reg = ICHIP_HW_ADDR_MASK_REG_OFF + fi->g.tachyon_base;
  2129. fi->t_r.ptr_ocq_base_reg = OCQ_BASE_REGISTER_OFFSET + fi->g.tachyon_base;
  2130. fi->t_r.ptr_ocq_len_reg = OCQ_LENGTH_REGISTER_OFFSET + fi->g.tachyon_base;
  2131. fi->t_r.ptr_ocq_prod_indx_reg = OCQ_PRODUCER_REGISTER_OFFSET + fi->g.tachyon_base;
  2132. fi->t_r.ptr_ocq_cons_indx_reg = OCQ_CONSUMER_REGISTER_OFFSET + fi->g.tachyon_base;
  2133. fi->t_r.ptr_imq_base_reg = IMQ_BASE_REGISTER_OFFSET + fi->g.tachyon_base;
  2134. fi->t_r.ptr_imq_len_reg = IMQ_LENGTH_REGISTER_OFFSET + fi->g.tachyon_base;
  2135. fi->t_r.ptr_imq_cons_indx_reg = IMQ_CONSUMER_REGISTER_OFFSET + fi->g.tachyon_base;
  2136. fi->t_r.ptr_imq_prod_indx_reg = IMQ_PRODUCER_REGISTER_OFFSET + fi->g.tachyon_base;
  2137. fi->t_r.ptr_mfsbq_base_reg = MFSBQ_BASE_REGISTER_OFFSET + fi->g.tachyon_base;
  2138. fi->t_r.ptr_mfsbq_len_reg = MFSBQ_LENGTH_REGISTER_OFFSET + fi->g.tachyon_base;
  2139. fi->t_r.ptr_mfsbq_prod_reg = MFSBQ_PRODUCER_REGISTER_OFFSET + fi->g.tachyon_base;
  2140. fi->t_r.ptr_mfsbq_cons_reg = MFSBQ_CONSUMER_REGISTER_OFFSET + fi->g.tachyon_base;
  2141. fi->t_r.ptr_mfsbuff_len_reg = MFS_LENGTH_REGISTER_OFFSET + fi->g.tachyon_base;
  2142. fi->t_r.ptr_sfsbq_base_reg = SFSBQ_BASE_REGISTER_OFFSET + fi->g.tachyon_base;
  2143. fi->t_r.ptr_sfsbq_len_reg = SFSBQ_LENGTH_REGISTER_OFFSET + fi->g.tachyon_base;
  2144. fi->t_r.ptr_sfsbq_prod_reg = SFSBQ_PRODUCER_REGISTER_OFFSET + fi->g.tachyon_base;
  2145. fi->t_r.ptr_sfsbq_cons_reg = SFSBQ_CONSUMER_REGISTER_OFFSET + fi->g.tachyon_base;
  2146. fi->t_r.ptr_sfsbuff_len_reg = SFS_LENGTH_REGISTER_OFFSET + fi->g.tachyon_base;
  2147. fi->t_r.ptr_sest_base_reg = SEST_BASE_REGISTER_OFFSET + fi->g.tachyon_base;
  2148. fi->t_r.ptr_sest_len_reg = SEST_LENGTH_REGISTER_OFFSET + fi->g.tachyon_base;
  2149. fi->t_r.ptr_scsibuff_len_reg = SCSI_LENGTH_REGISTER_OFFSET + fi->g.tachyon_base;
  2150. fi->t_r.ptr_tach_config_reg = TACHYON_CONFIG_REGISTER_OFFSET + fi->g.tachyon_base;
  2151. fi->t_r.ptr_tach_control_reg = TACHYON_CONTROL_REGISTER_OFFSET + fi->g.tachyon_base;
  2152. fi->t_r.ptr_tach_status_reg = TACHYON_STATUS_REGISTER_OFFSET + fi->g.tachyon_base;
  2153. fi->t_r.ptr_tach_flush_oxid_reg = TACHYON_FLUSH_SEST_REGISTER_OFFSET + fi->g.tachyon_base;
  2154. fi->t_r.ptr_fm_config_reg = FMGR_CONFIG_REGISTER_OFFSET + fi->g.tachyon_base;
  2155. fi->t_r.ptr_fm_control_reg = FMGR_CONTROL_REGISTER_OFFSET + fi->g.tachyon_base;
  2156. fi->t_r.ptr_fm_status_reg = FMGR_STATUS_REGISTER_OFFSET + fi->g.tachyon_base;
  2157. fi->t_r.ptr_fm_tov_reg = FMGR_TIMER_REGISTER_OFFSET + fi->g.tachyon_base;
  2158. fi->t_r.ptr_fm_wwn_hi_reg = FMGR_WWN_HI_REGISTER_OFFSET + fi->g.tachyon_base;
  2159. fi->t_r.ptr_fm_wwn_low_reg = FMGR_WWN_LO_REGISTER_OFFSET + fi->g.tachyon_base;
  2160. fi->t_r.ptr_fm_rx_al_pa_reg = FMGR_RCVD_ALPA_REGISTER_OFFSET + fi->g.tachyon_base;
  2161. LEAVE("initialize_register_pointers");
  2162. return 1;
  2163. }
  2164. /*
  2165.  * Local variables:
  2166.  *  compile-command: "gcc -DKERNEL -Wall -O6 -fomit-frame-pointer -I/usr/src/linux/net/tcp -c iph5526.c"
  2167.  *  version-control: t
  2168.  *  kept-new-versions: 5
  2169.  * End:
  2170.  */