fc.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:32k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /* fc.c: Generic Fibre Channel and FC4 SCSI driver.
  2.  *
  3.  * Copyright (C) 1997,1998,1999 Jakub Jelinek (jj@ultra.linux.cz)
  4.  * Copyright (C) 1997,1998 Jirka Hanika (geo@ff.cuni.cz)
  5.  *
  6.  * There are two kinds of Fibre Channel adapters used in Linux. Either
  7.  * the adapter is "smart" and does all FC bookkeeping by itself and
  8.  * just presents a standard SCSI interface to the operating system
  9.  * (that's e.g. the case with Qlogic FC cards), or leaves most of the FC
  10.  * bookkeeping to the OS (e.g. soc, socal). Drivers for the former adapters
  11.  * will look like normal SCSI drivers (with the exception of max_id will be
  12.  * usually 127), the latter on the other side allows SCSI, IP over FC and other
  13.  * protocols. This driver tree is for the latter adapters.
  14.  *
  15.  * This file should support both Point-to-Point and Arbitrated Loop topologies.
  16.  *
  17.  * Sources:
  18.  * Fibre Channel Physical & Signaling Interface (FC-PH), dpANS, 1994
  19.  * dpANS Fibre Channel Protocol for SCSI (X3.269-199X), Rev. 012, 1995
  20.  * Fibre Channel Arbitrated Loop (FC-AL), Rev. 4.5, 1995
  21.  * Fibre Channel Private Loop SCSI Direct Attach (FC-PLDA), Rev. 2.1, 1997
  22.  */
  23. #include <linux/module.h>
  24. #include <linux/kernel.h>
  25. #include <linux/sched.h>
  26. #include <linux/types.h>
  27. #include <linux/fcntl.h>
  28. #include <linux/interrupt.h>
  29. #include <linux/ptrace.h>
  30. #include <linux/ioport.h>
  31. #include <linux/in.h>
  32. #include <linux/slab.h>
  33. #include <linux/string.h>
  34. #include <linux/init.h>
  35. #include <linux/blk.h>
  36. #include <asm/pgtable.h>
  37. #include <asm/irq.h>
  38. #include <asm/semaphore.h>
  39. #include "fcp_impl.h"
  40. #include "../scsi/hosts.h"
  41. /* #define FCDEBUG */
  42. #define fc_printk printk ("%s: ", fc->name); printk 
  43. #ifdef FCDEBUG
  44. #define FCD(x)  fc_printk x;
  45. #define FCND(x) printk ("FC: "); printk x;
  46. #else
  47. #define FCD(x)
  48. #define FCND(x)
  49. #endif
  50. #ifdef __sparc__
  51. #define dma_alloc_consistent(d,s,p) sbus_alloc_consistent(d,s,p)
  52. #define dma_free_consistent(d,s,v,h) sbus_free_consistent(d,s,v,h)
  53. #define dma_map_single(d,v,s,dir) sbus_map_single(d,v,s,dir)
  54. #define dma_unmap_single(d,h,s,dir) sbus_unmap_single(d,h,s,dir)
  55. #define dma_map_sg(d,s,n,dir) sbus_map_sg(d,s,n,dir)
  56. #define dma_unmap_sg(d,s,n,dir) sbus_unmap_sg(d,s,n,dir)
  57. #define scsi_to_fc_dma_dir(dir) scsi_to_sbus_dma_dir(dir)
  58. #define FC_DMA_BIDIRECTIONAL SBUS_DMA_BIDIRECTIONAL
  59. #else
  60. #define dma_alloc_consistent(d,s,p) pci_alloc_consistent(d,s,p)
  61. #define dma_free_consistent(d,s,v,h) pci_free_consistent(d,s,v,h)
  62. #define dma_map_single(d,v,s,dir) pci_map_single(d,v,s,dir)
  63. #define dma_unmap_single(d,h,s,dir) pci_unmap_single(d,h,s,dir)
  64. #define dma_map_sg(d,s,n,dir) pci_map_sg(d,s,n,dir)
  65. #define dma_unmap_sg(d,s,n,dir) pci_unmap_sg(d,s,n,dir)
  66. #define scsi_to_fc_dma_dir(dir) scsi_to_pci_dma_dir(dir)
  67. #define FC_DMA_BIDIRECTIONAL PCI_DMA_BIDIRECTIONAL
  68. #endif        
  69. #define FCP_CMND(SCpnt) ((fcp_cmnd *)&(SCpnt->SCp))
  70. #define FC_SCMND(SCpnt) ((fc_channel *)(SCpnt->host->hostdata[0]))
  71. #define SC_FCMND(fcmnd) ((Scsi_Cmnd *)((long)fcmnd - (long)&(((Scsi_Cmnd *)0)->SCp)))
  72. static int fcp_scsi_queue_it(fc_channel *, Scsi_Cmnd *, fcp_cmnd *, int);
  73. void fcp_queue_empty(fc_channel *);
  74. static void fcp_scsi_insert_queue (fc_channel *fc, fcp_cmnd *fcmd)
  75. {
  76. if (!fc->scsi_que) {
  77. fc->scsi_que = fcmd;
  78. fcmd->next = fcmd;
  79. fcmd->prev = fcmd;
  80. } else {
  81. fc->scsi_que->prev->next = fcmd;
  82. fcmd->prev = fc->scsi_que->prev;
  83. fc->scsi_que->prev = fcmd;
  84. fcmd->next = fc->scsi_que;
  85. }
  86. }
  87. static void fcp_scsi_remove_queue (fc_channel *fc, fcp_cmnd *fcmd)
  88. {
  89. if (fcmd == fcmd->next) {
  90. fc->scsi_que = NULL;
  91. return;
  92. }
  93. if (fcmd == fc->scsi_que)
  94. fc->scsi_que = fcmd->next;
  95. fcmd->prev->next = fcmd->next;
  96. fcmd->next->prev = fcmd->prev;
  97. }
  98. fc_channel *fc_channels = NULL;
  99. #define LSMAGIC 620829043
  100. typedef struct {
  101. /* Must be first */
  102. struct semaphore sem;
  103. int magic;
  104. int count;
  105. logi *logi;
  106. fcp_cmnd *fcmds;
  107. atomic_t todo;
  108. struct timer_list timer;
  109. unsigned char grace[0];
  110. } ls;
  111. #define LSOMAGIC 654907799
  112. typedef struct {
  113. /* Must be first */
  114. struct semaphore sem;
  115. int magic;
  116. int count;
  117. fcp_cmnd *fcmds;
  118. atomic_t todo;
  119. struct timer_list timer;
  120. } lso;
  121. #define LSEMAGIC 84482456
  122. typedef struct {
  123. /* Must be first */
  124. struct semaphore sem;
  125. int magic;
  126. int status;
  127. struct timer_list timer;
  128. } lse;
  129. static void fcp_login_timeout(unsigned long data)
  130. {
  131. ls *l = (ls *)data;
  132. FCND(("Login timeoutn"))
  133. up(&l->sem);
  134. }
  135. static void fcp_login_done(fc_channel *fc, int i, int status)
  136. {
  137. fcp_cmnd *fcmd;
  138. logi *plogi;
  139. fc_hdr *fch;
  140. ls *l = (ls *)fc->ls;
  141. FCD(("Login done %d %dn", i, status))
  142. if (i < l->count) {
  143. if (fc->state == FC_STATE_FPORT_OK) {
  144. FCD(("Additional FPORT_OK received with status %dn", status))
  145. return;
  146. }
  147. switch (status) {
  148. case FC_STATUS_OK: /* Oh, we found a fabric */
  149. case FC_STATUS_P_RJT: /* Oh, we haven't found any */
  150. fc->state = FC_STATE_FPORT_OK;
  151. fcmd = l->fcmds + i;
  152. plogi = l->logi + 3 * i;
  153. dma_unmap_single (fc->dev, fcmd->cmd, 3 * sizeof(logi),
  154.   FC_DMA_BIDIRECTIONAL);
  155. plogi->code = LS_PLOGI;
  156. memcpy (&plogi->nport_wwn, &fc->wwn_nport, sizeof(fc_wwn));
  157. memcpy (&plogi->node_wwn, &fc->wwn_node, sizeof(fc_wwn));
  158. memcpy (&plogi->common, fc->common_svc, sizeof(common_svc_parm));
  159. memcpy (&plogi->class1, fc->class_svcs, 3*sizeof(svc_parm));
  160. fch = &fcmd->fch;
  161. fcmd->token += l->count;
  162. FILL_FCHDR_RCTL_DID(fch, R_CTL_ELS_REQ, fc->did);
  163. FILL_FCHDR_SID(fch, fc->sid);
  164. #ifdef FCDEBUG
  165. {
  166. int i;
  167. unsigned *x = (unsigned *)plogi;
  168. printk ("logi: ");
  169. for (i = 0; i < 21; i++)
  170. printk ("%08x ", x[i]);
  171. printk ("n");
  172. }
  173. #endif
  174. fcmd->cmd = dma_map_single (fc->dev, plogi, 3 * sizeof(logi),
  175.     FC_DMA_BIDIRECTIONAL);
  176. fcmd->rsp = fcmd->cmd + 2 * sizeof(logi);
  177. if (fc->hw_enque (fc, fcmd))
  178. printk ("FC: Cannot enque PLOGI packet on %sn", fc->name);
  179. break;
  180. case FC_STATUS_ERR_OFFLINE:
  181. fc->state = FC_STATE_MAYBEOFFLINE;
  182. FCD (("FC is offline %dn", l->grace[i]))
  183. break;
  184. default:
  185. printk ("FLOGI failed for %s with status %dn", fc->name, status);
  186. /* Do some sort of error recovery here */
  187. break;
  188. }
  189. } else {
  190. i -= l->count;
  191. if (fc->state != FC_STATE_FPORT_OK) {
  192. FCD(("Unexpected N-PORT rsp received"))
  193. return;
  194. }
  195. switch (status) {
  196. case FC_STATUS_OK:
  197. plogi = l->logi + 3 * i;
  198. dma_unmap_single (fc->dev, l->fcmds[i].cmd, 3 * sizeof(logi),
  199.   FC_DMA_BIDIRECTIONAL);
  200. if (!fc->wwn_dest.lo && !fc->wwn_dest.hi) {
  201. memcpy (&fc->wwn_dest, &plogi[1].node_wwn, sizeof(fc_wwn)); 
  202. FCD(("Dest WWN %08x%08xn", *(u32 *)&fc->wwn_dest, fc->wwn_dest.lo))
  203. } else if (fc->wwn_dest.lo != plogi[1].node_wwn.lo ||
  204.    fc->wwn_dest.hi != plogi[1].node_wwn.hi) {
  205. printk ("%s: mismatch in wwns. Got %08x%08x, expected %08x%08xn",
  206. fc->name,
  207. *(u32 *)&plogi[1].node_wwn, plogi[1].node_wwn.lo,
  208. *(u32 *)&fc->wwn_dest, fc->wwn_dest.lo);
  209. }
  210. fc->state = FC_STATE_ONLINE;
  211. printk ("%s: ONLINEn", fc->name);
  212. if (atomic_dec_and_test (&l->todo))
  213. up(&l->sem);
  214. break;
  215. case FC_STATUS_ERR_OFFLINE:
  216. fc->state = FC_STATE_OFFLINE;
  217. dma_unmap_single (fc->dev, l->fcmds[i].cmd, 3 * sizeof(logi),
  218.   FC_DMA_BIDIRECTIONAL);
  219. printk ("%s: FC is offlinen", fc->name);
  220. if (atomic_dec_and_test (&l->todo))
  221. up(&l->sem);
  222. break;
  223. default:
  224. printk ("PLOGI failed for %s with status %dn", fc->name, status);
  225. /* Do some sort of error recovery here */
  226. break;
  227. }
  228. }
  229. }
  230. static void fcp_report_map_done(fc_channel *fc, int i, int status)
  231. {
  232. fcp_cmnd *fcmd;
  233. fc_hdr *fch;
  234. unsigned char j;
  235. ls *l = (ls *)fc->ls;
  236. fc_al_posmap *p;
  237. FCD(("Report map done %d %dn", i, status))
  238. switch (status) {
  239. case FC_STATUS_OK: /* Ok, let's have a fun on a loop */
  240. dma_unmap_single (fc->dev, l->fcmds[i].cmd, 3 * sizeof(logi),
  241.   FC_DMA_BIDIRECTIONAL);
  242. p = (fc_al_posmap *)(l->logi + 3 * i);
  243. #ifdef FCDEBUG
  244. {
  245. u32 *u = (u32 *)p;
  246. FCD(("%08xn", u[0]))
  247. u ++;
  248. FCD(("%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08xn", u[0],u[1],u[2],u[3],u[4],u[5],u[6],u[7]))
  249. }
  250. #endif
  251. if ((p->magic & 0xffff0000) != FC_AL_LILP || !p->len) {
  252. printk ("FC: Bad magic from REPORT_AL_MAP on %s - %08xn", fc->name, p->magic);
  253. fc->state = FC_STATE_OFFLINE;
  254. } else {
  255. fc->posmap = (fcp_posmap *)kmalloc(sizeof(fcp_posmap)+p->len, GFP_KERNEL);
  256. if (!fc->posmap) {
  257. printk("FC: Not enough memory, offlining channeln");
  258. fc->state = FC_STATE_OFFLINE;
  259. } else {
  260. int k;
  261. memset(fc->posmap, 0, sizeof(fcp_posmap)+p->len);
  262. /* FIXME: This is where SOCAL transfers our AL-PA.
  263.    Keep it here till we found out what other cards do... */
  264. fc->sid = (p->magic & 0xff);
  265. for (i = 0; i < p->len; i++)
  266. if (p->alpa[i] == fc->sid)
  267. break;
  268. k = p->len;
  269. if (i == p->len)
  270. i = 0;
  271. else {
  272. p->len--;
  273. i++;
  274. }
  275. fc->posmap->len = p->len;
  276. for (j = 0; j < p->len; j++) {
  277. if (i == k) i = 0;
  278. fc->posmap->list[j] = p->alpa[i++];
  279. }
  280. fc->state = FC_STATE_ONLINE;
  281. }
  282. }
  283. printk ("%s: ONLINEn", fc->name);
  284. if (atomic_dec_and_test (&l->todo))
  285. up(&l->sem);
  286. break;
  287. case FC_STATUS_POINTTOPOINT: /* We're Point-to-Point, no AL... */
  288. FCD(("SID %d DID %dn", fc->sid, fc->did))
  289. fcmd = l->fcmds + i;
  290. dma_unmap_single(fc->dev, fcmd->cmd, 3 * sizeof(logi),
  291.  FC_DMA_BIDIRECTIONAL);
  292. fch = &fcmd->fch;
  293. memset(l->logi + 3 * i, 0, 3 * sizeof(logi));
  294. FILL_FCHDR_RCTL_DID(fch, R_CTL_ELS_REQ, FS_FABRIC_F_PORT);
  295. FILL_FCHDR_SID(fch, 0);
  296. FILL_FCHDR_TYPE_FCTL(fch, TYPE_EXTENDED_LS, F_CTL_FIRST_SEQ | F_CTL_SEQ_INITIATIVE);
  297. FILL_FCHDR_SEQ_DF_SEQ(fch, 0, 0, 0);
  298. FILL_FCHDR_OXRX(fch, 0xffff, 0xffff);
  299. fch->param = 0;
  300. l->logi [3 * i].code = LS_FLOGI;
  301. fcmd->cmd = dma_map_single (fc->dev, l->logi + 3 * i, 3 * sizeof(logi),
  302.     FC_DMA_BIDIRECTIONAL);
  303. fcmd->rsp = fcmd->cmd + sizeof(logi);
  304. fcmd->cmdlen = sizeof(logi);
  305. fcmd->rsplen = sizeof(logi);
  306. fcmd->data = (dma_addr_t)NULL;
  307. fcmd->class = FC_CLASS_SIMPLE;
  308. fcmd->proto = TYPE_EXTENDED_LS;
  309. if (fc->hw_enque (fc, fcmd))
  310. printk ("FC: Cannot enque FLOGI packet on %sn", fc->name);
  311. break;
  312. case FC_STATUS_ERR_OFFLINE:
  313. fc->state = FC_STATE_MAYBEOFFLINE;
  314. FCD (("FC is offline %dn", l->grace[i]))
  315. break;
  316. default:
  317. printk ("FLOGI failed for %s with status %dn", fc->name, status);
  318. /* Do some sort of error recovery here */
  319. break;
  320. }
  321. }
  322. void fcp_register(fc_channel *fc, u8 type, int unregister)
  323. {
  324. int size, i;
  325. int slots = (fc->can_queue * 3) >> 1;
  326. FCND(("Going to %sregistern", unregister ? "un" : ""))
  327. if (type == TYPE_SCSI_FCP) {
  328. if (!unregister) {
  329. fc->scsi_cmd_pool = (fcp_cmd *)
  330. dma_alloc_consistent (fc->dev,
  331.       slots * (sizeof (fcp_cmd) + fc->rsp_size),
  332.       &fc->dma_scsi_cmd);
  333. fc->scsi_rsp_pool = (char *)(fc->scsi_cmd_pool + slots);
  334. fc->dma_scsi_rsp = fc->dma_scsi_cmd + slots * sizeof (fcp_cmd);
  335. fc->scsi_bitmap_end = (slots + 63) & ~63;
  336. size = fc->scsi_bitmap_end / 8;
  337. fc->scsi_bitmap = kmalloc (size, GFP_KERNEL);
  338. memset (fc->scsi_bitmap, 0, size);
  339. set_bit (0, fc->scsi_bitmap);
  340. for (i = fc->can_queue; i < fc->scsi_bitmap_end; i++)
  341. set_bit (i, fc->scsi_bitmap);
  342. fc->scsi_free = fc->can_queue;
  343. fc->cmd_slots = (fcp_cmnd **)kmalloc(slots * sizeof(fcp_cmnd*), GFP_KERNEL);
  344. memset(fc->cmd_slots, 0, slots * sizeof(fcp_cmnd*));
  345. fc->abort_count = 0;
  346. } else {
  347. fc->scsi_name[0] = 0;
  348. kfree (fc->scsi_bitmap);
  349. kfree (fc->cmd_slots);
  350. FCND(("Unregisteringn"));
  351. if (fc->rst_pkt) {
  352. if (fc->rst_pkt->eh_state == SCSI_STATE_UNUSED)
  353. kfree(fc->rst_pkt);
  354. else {
  355. /* Can't happen. Some memory would be lost. */
  356. printk("FC: Reset in progress. Now?!");
  357. }
  358. }
  359. FCND(("Unregisteredn"));
  360. }
  361. } else
  362. printk ("FC: %segistering unknown type %02xn", unregister ? "Unr" : "R", type);
  363. }
  364. static void fcp_scsi_done(Scsi_Cmnd *SCpnt);
  365. static inline void fcp_scsi_receive(fc_channel *fc, int token, int status, fc_hdr *fch)
  366. {
  367. fcp_cmnd *fcmd;
  368. fcp_rsp  *rsp;
  369. int host_status;
  370. Scsi_Cmnd *SCpnt;
  371. int sense_len;
  372. int rsp_status;
  373. fcmd = fc->cmd_slots[token];
  374. if (!fcmd) return;
  375. rsp = (fcp_rsp *) (fc->scsi_rsp_pool + fc->rsp_size * token);
  376. SCpnt = SC_FCMND(fcmd);
  377. if (SCpnt->done != fcp_scsi_done)
  378. return;
  379. rsp_status = rsp->fcp_status;
  380. FCD(("rsp_status %08x status %08xn", rsp_status, status))
  381. switch (status) {
  382. case FC_STATUS_OK:
  383. host_status=DID_OK;
  384. if (rsp_status & FCP_STATUS_RESID) {
  385. #ifdef FCDEBUG
  386. FCD(("Resid %dn", rsp->fcp_resid))
  387. {
  388. fcp_cmd *cmd = fc->scsi_cmd_pool + token;
  389. int i;
  390. printk ("Command ");
  391. for (i = 0; i < sizeof(fcp_cmd); i+=4)
  392. printk ("%08x ", *(u32 *)(((char *)cmd)+i));
  393. printk ("nResponse ");
  394. for (i = 0; i < fc->rsp_size; i+=4)
  395. printk ("%08x ", *(u32 *)(((char *)rsp)+i));
  396. printk ("n");
  397. }
  398. #endif
  399. }
  400. if (rsp_status & FCP_STATUS_SENSE_LEN) {
  401. sense_len = rsp->fcp_sense_len;
  402. if (sense_len > sizeof(SCpnt->sense_buffer)) sense_len = sizeof(SCpnt->sense_buffer);
  403. memcpy(SCpnt->sense_buffer, ((char *)(rsp+1)), sense_len);
  404. }
  405. if (fcmd->data) {
  406. if (SCpnt->use_sg)
  407. dma_unmap_sg(fc->dev, (struct scatterlist *)SCpnt->buffer, SCpnt->use_sg,
  408.      scsi_to_fc_dma_dir(SCpnt->sc_data_direction));
  409. else
  410. dma_unmap_single(fc->dev, fcmd->data, SCpnt->request_bufflen,
  411.  scsi_to_fc_dma_dir(SCpnt->sc_data_direction));
  412. }
  413. break;
  414. default:
  415. host_status=DID_ERROR; /* FIXME */
  416. FCD(("Wrong FC status %d for token %dn", status, token))
  417. break;
  418. }
  419. if (status_byte(rsp_status) == QUEUE_FULL) {
  420. printk ("%s: (%d,%d) Received rsp_status 0x%xn", fc->name, SCpnt->channel, SCpnt->target, rsp_status);
  421. }
  422. SCpnt->result = (host_status << 16) | (rsp_status & 0xff);
  423. #ifdef FCDEBUG
  424. if (host_status || SCpnt->result || rsp_status) printk("FC: host_status %d, packet status %dn",
  425. host_status, SCpnt->result);
  426. #endif
  427. SCpnt->done = fcmd->done;
  428. fcmd->done=NULL;
  429. clear_bit(token, fc->scsi_bitmap);
  430. fc->scsi_free++;
  431. FCD(("Calling scsi_done with %08xn", SCpnt->result))
  432. SCpnt->scsi_done(SCpnt);
  433. }
  434. void fcp_receive_solicited(fc_channel *fc, int proto, int token, int status, fc_hdr *fch)
  435. {
  436. int magic;
  437. FCD(("receive_solicited %d %d %dn", proto, token, status))
  438. switch (proto) {
  439. case TYPE_SCSI_FCP:
  440. fcp_scsi_receive(fc, token, status, fch); break;
  441. case TYPE_EXTENDED_LS:
  442. case PROTO_REPORT_AL_MAP:
  443. magic = 0;
  444. if (fc->ls)
  445. magic = ((ls *)(fc->ls))->magic;
  446. if (magic == LSMAGIC) {
  447. ls *l = (ls *)fc->ls;
  448. int i = (token >= l->count) ? token - l->count : token;
  449. /* Let's be sure */
  450. if ((unsigned)i < l->count && l->fcmds[i].fc == fc) {
  451. if (proto == TYPE_EXTENDED_LS)
  452. fcp_login_done(fc, token, status);
  453. else
  454. fcp_report_map_done(fc, token, status);
  455. break;
  456. }
  457. }
  458. FCD(("fc %p fc->ls %p fc->cmd_slots %pn", fc, fc->ls, fc->cmd_slots))
  459. if (proto == TYPE_EXTENDED_LS && !fc->ls && fc->cmd_slots) {
  460. fcp_cmnd *fcmd;
  461. fcmd = fc->cmd_slots[token];
  462. if (fcmd && fcmd->ls && ((ls *)(fcmd->ls))->magic == LSEMAGIC) {
  463. lse *l = (lse *)fcmd->ls;
  464. l->status = status;
  465. up (&l->sem);
  466. }
  467. }
  468. break;
  469. case PROTO_OFFLINE:
  470. if (fc->ls && ((lso *)(fc->ls))->magic == LSOMAGIC) {
  471. lso *l = (lso *)fc->ls;
  472. if ((unsigned)token < l->count && l->fcmds[token].fc == fc) {
  473. /* Wow, OFFLINE response arrived :) */
  474. FCD(("OFFLINE Response arrivedn"))
  475. fc->state = FC_STATE_OFFLINE;
  476. if (atomic_dec_and_test (&l->todo))
  477. up(&l->sem);
  478. }
  479. }
  480. break;
  481. default:
  482. break;
  483. }
  484. }
  485. void fcp_state_change(fc_channel *fc, int state)
  486. {
  487. FCD(("state_change %d %dn", state, fc->state))
  488. if (state == FC_STATE_ONLINE && fc->state == FC_STATE_MAYBEOFFLINE)
  489. fc->state = FC_STATE_UNINITED;
  490. else if (state == FC_STATE_ONLINE)
  491. printk (KERN_WARNING "%s: state change to ONLINEn", fc->name);
  492. else
  493. printk (KERN_ERR "%s: state change to OFFLINEn", fc->name);
  494. }
  495. int fcp_initialize(fc_channel *fcchain, int count)
  496. {
  497. fc_channel *fc;
  498. fcp_cmnd *fcmd;
  499. int i, retry, ret;
  500. ls *l;
  501. FCND(("fcp_inititialize %08lxn", (long)fcp_init))
  502. FCND(("fc_channels %08lxn", (long)fc_channels))
  503. FCND((" SID %d DID %dn", fcchain->sid, fcchain->did))
  504. l = kmalloc(sizeof (ls) + count, GFP_KERNEL);
  505. if (!l) {
  506. printk ("FC: Cannot allocate memory for initializationn");
  507. return -ENOMEM;
  508. }
  509. memset (l, 0, sizeof(ls) + count);
  510. l->magic = LSMAGIC;
  511. l->count = count;
  512. FCND(("FCP Init for %d channelsn", count))
  513. init_MUTEX_LOCKED(&l->sem);
  514. l->timer.function = fcp_login_timeout;
  515. l->timer.data = (unsigned long)l;
  516. atomic_set (&l->todo, count);
  517. l->logi = kmalloc (count * 3 * sizeof(logi), GFP_KERNEL);
  518. l->fcmds = kmalloc (count * sizeof(fcp_cmnd), GFP_KERNEL);
  519. if (!l->logi || !l->fcmds) {
  520. if (l->logi) kfree (l->logi);
  521. if (l->fcmds) kfree (l->fcmds);
  522. kfree (l);
  523. printk ("FC: Cannot allocate DMA memory for initializationn");
  524. return -ENOMEM;
  525. }
  526. memset (l->logi, 0, count * 3 * sizeof(logi));
  527. memset (l->fcmds, 0, count * sizeof(fcp_cmnd));
  528. for (fc = fcchain, i = 0; fc && i < count; fc = fc->next, i++) {
  529. fc->state = FC_STATE_UNINITED;
  530. fc->rst_pkt = NULL; /* kmalloc when first used */
  531. }
  532. /* First try if we are in a AL topology */
  533. FCND(("Initializing REPORT_MAP packetsn"))
  534. for (fc = fcchain, i = 0; fc && i < count; fc = fc->next, i++) {
  535. fcmd = l->fcmds + i;
  536. fc->login = fcmd;
  537. fc->ls = (void *)l;
  538. /* Assumes sizeof(fc_al_posmap) < 3 * sizeof(logi), which is true */
  539. fcmd->cmd = dma_map_single (fc->dev, l->logi + 3 * i, 3 * sizeof(logi),
  540.     FC_DMA_BIDIRECTIONAL);
  541. fcmd->proto = PROTO_REPORT_AL_MAP;
  542. fcmd->token = i;
  543. fcmd->fc = fc;
  544. }
  545. for (retry = 0; retry < 8; retry++) {
  546. int nqueued = 0;
  547. FCND(("Sending REPORT_MAP/FLOGI/PLOGI packetsn"))
  548. for (fc = fcchain, i = 0; fc && i < count; fc = fc->next, i++) {
  549. if (fc->state == FC_STATE_ONLINE || fc->state == FC_STATE_OFFLINE)
  550. continue;
  551. disable_irq(fc->irq);
  552. if (fc->state == FC_STATE_MAYBEOFFLINE) {
  553. if (!l->grace[i]) {
  554. l->grace[i]++;
  555. FCD(("Gracen"))
  556. } else {
  557. fc->state = FC_STATE_OFFLINE;
  558. enable_irq(fc->irq);
  559. dma_unmap_single (fc->dev, l->fcmds[i].cmd, 3 * sizeof(logi), FC_DMA_BIDIRECTIONAL);
  560. if (atomic_dec_and_test (&l->todo))
  561. goto all_done;
  562. }
  563. }
  564. ret = fc->hw_enque (fc, fc->login);
  565. enable_irq(fc->irq);
  566. if (!ret) {
  567. nqueued++;
  568. continue;
  569. }
  570. if (ret == -ENOSYS && fc->login->proto == PROTO_REPORT_AL_MAP) {
  571. /* Oh yes, this card handles Point-to-Point only, so let's try that. */
  572. fc_hdr *fch;
  573. FCD(("SID %d DID %dn", fc->sid, fc->did))
  574. fcmd = l->fcmds + i;
  575. dma_unmap_single(fc->dev, fcmd->cmd, 3 * sizeof(logi), FC_DMA_BIDIRECTIONAL);
  576. fch = &fcmd->fch;
  577. FILL_FCHDR_RCTL_DID(fch, R_CTL_ELS_REQ, FS_FABRIC_F_PORT);
  578. FILL_FCHDR_SID(fch, 0);
  579. FILL_FCHDR_TYPE_FCTL(fch, TYPE_EXTENDED_LS, F_CTL_FIRST_SEQ | F_CTL_SEQ_INITIATIVE);
  580. FILL_FCHDR_SEQ_DF_SEQ(fch, 0, 0, 0);
  581. FILL_FCHDR_OXRX(fch, 0xffff, 0xffff);
  582. fch->param = 0;
  583. l->logi [3 * i].code = LS_FLOGI;
  584. fcmd->cmd = dma_map_single (fc->dev, l->logi + 3 * i, 3 * sizeof(logi), FC_DMA_BIDIRECTIONAL);
  585. fcmd->rsp = fcmd->cmd + sizeof(logi);
  586. fcmd->cmdlen = sizeof(logi);
  587. fcmd->rsplen = sizeof(logi);
  588. fcmd->data = (dma_addr_t)NULL;
  589. fcmd->class = FC_CLASS_SIMPLE;
  590. fcmd->proto = TYPE_EXTENDED_LS;
  591. } else
  592. printk ("FC: Cannot enque FLOGI/REPORT_MAP packet on %sn", fc->name);
  593. }
  594. if (nqueued) {
  595. l->timer.expires = jiffies + 5 * HZ;
  596. add_timer(&l->timer);
  597. down(&l->sem);
  598. if (!atomic_read(&l->todo)) {
  599. FCND(("All channels answered in timen"))
  600. break; /* All fc channels have answered us */
  601. }
  602. }
  603. }
  604. all_done:
  605. for (fc = fcchain, i = 0; fc && i < count; fc = fc->next, i++) {
  606. fc->ls = NULL;
  607. switch (fc->state) {
  608. case FC_STATE_ONLINE: break;
  609. case FC_STATE_OFFLINE: break;
  610. default: dma_unmap_single (fc->dev, l->fcmds[i].cmd, 3 * sizeof(logi), FC_DMA_BIDIRECTIONAL);
  611. break;
  612. }
  613. }
  614. del_timer(&l->timer);
  615. kfree (l->logi);
  616. kfree (l->fcmds);
  617. kfree (l);
  618. return 0;
  619. }
  620. int fcp_forceoffline(fc_channel *fcchain, int count)
  621. {
  622. fc_channel *fc;
  623. fcp_cmnd *fcmd;
  624. int i, ret;
  625. lso l;
  626. memset (&l, 0, sizeof(lso));
  627. l.count = count;
  628. l.magic = LSOMAGIC;
  629. FCND(("FCP Force Offline for %d channelsn", count))
  630. init_MUTEX_LOCKED(&l.sem);
  631. l.timer.function = fcp_login_timeout;
  632. l.timer.data = (unsigned long)&l;
  633. atomic_set (&l.todo, count);
  634. l.fcmds = kmalloc (count * sizeof(fcp_cmnd), GFP_KERNEL);
  635. if (!l.fcmds) {
  636. kfree (l.fcmds);
  637. printk ("FC: Cannot allocate memory for forcing offlinen");
  638. return -ENOMEM;
  639. }
  640. memset (l.fcmds, 0, count * sizeof(fcp_cmnd));
  641. FCND(("Initializing OFFLINE packetsn"))
  642. for (fc = fcchain, i = 0; fc && i < count; fc = fc->next, i++) {
  643. fc->state = FC_STATE_UNINITED;
  644. fcmd = l.fcmds + i;
  645. fc->login = fcmd;
  646. fc->ls = (void *)&l;
  647. fcmd->did = fc->did;
  648. fcmd->class = FC_CLASS_OFFLINE;
  649. fcmd->proto = PROTO_OFFLINE;
  650. fcmd->token = i;
  651. fcmd->fc = fc;
  652. disable_irq(fc->irq);
  653. ret = fc->hw_enque (fc, fc->login);
  654. enable_irq(fc->irq);
  655. if (ret) printk ("FC: Cannot enque OFFLINE packet on %sn", fc->name);
  656. }
  657. l.timer.expires = jiffies + 5 * HZ;
  658. add_timer(&l.timer);
  659. down(&l.sem);
  660. del_timer(&l.timer);
  661. for (fc = fcchain, i = 0; fc && i < count; fc = fc->next, i++)
  662. fc->ls = NULL;
  663. kfree (l.fcmds);
  664. return 0;
  665. }
  666. int fcp_init(fc_channel *fcchain)
  667. {
  668. fc_channel *fc;
  669. int count=0;
  670. int ret;
  671. for (fc = fcchain; fc; fc = fc->next) {
  672. fc->fcp_register = fcp_register;
  673. count++;
  674. }
  675. ret = fcp_initialize (fcchain, count);
  676. if (ret)
  677. return ret;
  678. if (!fc_channels)
  679. fc_channels = fcchain;
  680. else {
  681. for (fc = fc_channels; fc->next; fc = fc->next);
  682. fc->next = fcchain;
  683. }
  684. return ret;
  685. }
  686. void fcp_release(fc_channel *fcchain, int count)  /* count must > 0 */
  687. {
  688. fc_channel *fc;
  689. fc_channel *fcx;
  690. for (fc = fcchain; --count && fc->next; fc = fc->next);
  691. if (count) {
  692. printk("FC: nothing to releasen");
  693. return;
  694. }
  695. if (fc_channels == fcchain)
  696. fc_channels = fc->next;
  697. else {
  698. for (fcx = fc_channels; fcx->next != fcchain; fcx = fcx->next);
  699. fcx->next = fc->next;
  700. }
  701. fc->next = NULL;
  702. /*
  703.  *  We've just grabbed fcchain out of the fc_channel list
  704.  *  and zero-terminated it, while destroying the count.
  705.  *
  706.  *  Freeing the fc's is the low level driver's responsibility.
  707.  */
  708. }
  709. static void fcp_scsi_done (Scsi_Cmnd *SCpnt)
  710. {
  711. if (FCP_CMND(SCpnt)->done)
  712. FCP_CMND(SCpnt)->done(SCpnt);
  713. }
  714. static int fcp_scsi_queue_it(fc_channel *fc, Scsi_Cmnd *SCpnt, fcp_cmnd *fcmd, int prepare)
  715. {
  716. long i;
  717. fcp_cmd *cmd;
  718. u32 fcp_cntl;
  719. if (prepare) {
  720. i = find_first_zero_bit (fc->scsi_bitmap, fc->scsi_bitmap_end);
  721. set_bit (i, fc->scsi_bitmap);
  722. fcmd->token = i;
  723. cmd = fc->scsi_cmd_pool + i;
  724. if (fc->encode_addr (SCpnt, cmd->fcp_addr, fc, fcmd)) {
  725. /* Invalid channel/id/lun and couldn't map it into fcp_addr */
  726. clear_bit (i, fc->scsi_bitmap);
  727. SCpnt->result = (DID_BAD_TARGET << 16);
  728. SCpnt->scsi_done(SCpnt);
  729. return 0;
  730. }
  731. fc->scsi_free--;
  732. fc->cmd_slots[fcmd->token] = fcmd;
  733. if (SCpnt->device->tagged_supported) {
  734. if (jiffies - fc->ages[SCpnt->channel * fc->targets + SCpnt->target] > (5 * 60 * HZ)) {
  735. fc->ages[SCpnt->channel * fc->targets + SCpnt->target] = jiffies;
  736. fcp_cntl = FCP_CNTL_QTYPE_ORDERED;
  737. } else
  738. fcp_cntl = FCP_CNTL_QTYPE_SIMPLE;
  739. } else
  740. fcp_cntl = FCP_CNTL_QTYPE_UNTAGGED;
  741. if (!SCpnt->request_bufflen && !SCpnt->use_sg) {
  742. cmd->fcp_cntl = fcp_cntl;
  743. fcmd->data = (dma_addr_t)NULL;
  744. } else {
  745. switch (SCpnt->cmnd[0]) {
  746. case WRITE_6:
  747. case WRITE_10:
  748. case WRITE_12:
  749. cmd->fcp_cntl = (FCP_CNTL_WRITE | fcp_cntl); break;
  750. default:
  751. cmd->fcp_cntl = (FCP_CNTL_READ | fcp_cntl); break;
  752. }
  753. if (!SCpnt->use_sg) {
  754. cmd->fcp_data_len = SCpnt->request_bufflen;
  755. fcmd->data = dma_map_single (fc->dev, (char *)SCpnt->request_buffer,
  756.      SCpnt->request_bufflen,
  757.      scsi_to_fc_dma_dir(SCpnt->sc_data_direction));
  758. } else {
  759. struct scatterlist *sg = (struct scatterlist *)SCpnt->buffer;
  760. int nents;
  761. FCD(("XXX: Use_sg %d %dn", SCpnt->use_sg, sg->length))
  762. nents = dma_map_sg (fc->dev, sg, SCpnt->use_sg,
  763.     scsi_to_fc_dma_dir(SCpnt->sc_data_direction));
  764. if (nents > 1) printk ("%s: SG for nents %d (use_sg %d) not handled yetn", fc->name, nents, SCpnt->use_sg);
  765. fcmd->data = sg_dma_address(sg);
  766. cmd->fcp_data_len = sg_dma_len(sg);
  767. }
  768. }
  769. memcpy (cmd->fcp_cdb, SCpnt->cmnd, SCpnt->cmd_len);
  770. memset (cmd->fcp_cdb+SCpnt->cmd_len, 0, sizeof(cmd->fcp_cdb)-SCpnt->cmd_len);
  771. FCD(("XXX: %04x.%04x.%04x.%04x - %08x%08x%08xn", cmd->fcp_addr[0], cmd->fcp_addr[1], cmd->fcp_addr[2], cmd->fcp_addr[3], *(u32 *)SCpnt->cmnd, *(u32 *)(SCpnt->cmnd+4), *(u32 *)(SCpnt->cmnd+8)))
  772. }
  773. FCD(("Trying to enque %pn", fcmd))
  774. if (!fc->scsi_que) {
  775. if (!fc->hw_enque (fc, fcmd)) {
  776. FCD(("hw_enque succeeded for %pn", fcmd))
  777. return 0;
  778. }
  779. }
  780. FCD(("Putting into que1 %pn", fcmd))
  781. fcp_scsi_insert_queue (fc, fcmd);
  782. return 0;
  783. }
  784. int fcp_scsi_queuecommand(Scsi_Cmnd *SCpnt, void (* done)(Scsi_Cmnd *))
  785. {
  786. fcp_cmnd *fcmd = FCP_CMND(SCpnt);
  787. fc_channel *fc = FC_SCMND(SCpnt);
  788. FCD(("Entering SCSI queuecommand %pn", fcmd))
  789. if (SCpnt->done != fcp_scsi_done) {
  790. fcmd->done = SCpnt->done;
  791. SCpnt->done = fcp_scsi_done;
  792. SCpnt->scsi_done = done;
  793. fcmd->proto = TYPE_SCSI_FCP;
  794. if (!fc->scsi_free) {
  795. FCD(("FC: !scsi_free, putting cmd on ML queuen"))
  796. #if (FCP_SCSI_USE_NEW_EH_CODE == 0)
  797. printk("fcp_scsi_queue_command: queue full, losing cmd, badn");
  798. #endif
  799. return 1;
  800. }
  801. return fcp_scsi_queue_it(fc, SCpnt, fcmd, 1);
  802. }
  803. return fcp_scsi_queue_it(fc, SCpnt, fcmd, 0);
  804. }
  805. void fcp_queue_empty(fc_channel *fc)
  806. {
  807. fcp_cmnd *fcmd;
  808. FCD(("Queue emptyn"))
  809. while ((fcmd = fc->scsi_que)) {
  810. /* The hw told us we can try again queue some packet */
  811. if (fc->hw_enque (fc, fcmd))
  812. break;
  813. fcp_scsi_remove_queue (fc, fcmd);
  814. }
  815. }
  816. int fcp_old_abort(Scsi_Cmnd *SCpnt)
  817. {
  818. printk("FC: Abort not implementedn");
  819. return 1;
  820. }
  821. int fcp_scsi_abort(Scsi_Cmnd *SCpnt)
  822. {
  823. /* Internal bookkeeping only. Lose 1 cmd_slots slot. */
  824. fcp_cmnd *fcmd = FCP_CMND(SCpnt);
  825. fc_channel *fc = FC_SCMND(SCpnt);
  826. /*
  827.  * We react to abort requests by simply forgetting
  828.  * about the command and pretending everything's sweet.
  829.  * This may or may not be silly. We can't, however,
  830.  * immediately reuse the command's cmd_slots slot,
  831.  * as its result may arrive later and we cannot
  832.  * check whether it is the aborted one, can't we?
  833.  *
  834.  * Therefore, after the first few aborts are done,
  835.  * we tell the scsi error handler to do something clever.
  836.  * It will eventually call host reset, refreshing
  837.  * cmd_slots for us.
  838.  *
  839.  * There is a theoretical chance that we sometimes allow
  840.  * more than can_queue packets to the jungle this way,
  841.  * but the worst outcome possible is a series of
  842.  * more aborts and eventually the dev_reset catharsis.
  843.  */
  844. if (++fc->abort_count < (fc->can_queue >> 1)) {
  845. SCpnt->result = DID_ABORT;
  846. fcmd->done(SCpnt);
  847. printk("FC: soft abortn");
  848. return SUCCESS;
  849. } else {
  850. printk("FC: hard abort refusedn");
  851. return FAILED;
  852. }
  853. }
  854. void fcp_scsi_reset_done(Scsi_Cmnd *SCpnt)
  855. {
  856. fc_channel *fc = FC_SCMND(SCpnt);
  857. fc->rst_pkt->eh_state = SCSI_STATE_FINISHED;
  858. up(fc->rst_pkt->host->eh_action);
  859. }
  860. #define FCP_RESET_TIMEOUT (2*HZ)
  861. int fcp_scsi_dev_reset(Scsi_Cmnd *SCpnt)
  862. {
  863. fcp_cmd *cmd;
  864. fcp_cmnd *fcmd;
  865. fc_channel *fc = FC_SCMND(SCpnt);
  866.         DECLARE_MUTEX_LOCKED(sem);
  867. if (!fc->rst_pkt) {
  868. fc->rst_pkt = (Scsi_Cmnd *) kmalloc(sizeof(SCpnt), GFP_KERNEL);
  869. if (!fc->rst_pkt) return FAILED;
  870. fcmd = FCP_CMND(fc->rst_pkt);
  871. fcmd->token = 0;
  872. cmd = fc->scsi_cmd_pool + 0;
  873. FCD(("Preparing rst packetn"))
  874. fc->encode_addr (SCpnt, cmd->fcp_addr, fc, fcmd);
  875. fc->rst_pkt->channel = SCpnt->channel;
  876. fc->rst_pkt->target = SCpnt->target;
  877. fc->rst_pkt->lun = 0;
  878. fc->rst_pkt->cmd_len = 0;
  879. fc->cmd_slots[0] = fcmd;
  880. cmd->fcp_cntl = FCP_CNTL_QTYPE_ORDERED | FCP_CNTL_RESET;
  881. fcmd->data = (dma_addr_t)NULL;
  882. fcmd->proto = TYPE_SCSI_FCP;
  883. memcpy (cmd->fcp_cdb, SCpnt->cmnd, SCpnt->cmd_len);
  884. memset (cmd->fcp_cdb+SCpnt->cmd_len, 0, sizeof(cmd->fcp_cdb)-SCpnt->cmd_len);
  885. FCD(("XXX: %04x.%04x.%04x.%04x - %08x%08x%08xn", cmd->fcp_addr[0], cmd->fcp_addr[1], cmd->fcp_addr[2], cmd->fcp_addr[3], *(u32 *)SCpnt->cmnd, *(u32 *)(SCpnt->cmnd+4), *(u32 *)(SCpnt->cmnd+8)))
  886. } else {
  887. fcmd = FCP_CMND(fc->rst_pkt);
  888. if (fc->rst_pkt->eh_state == SCSI_STATE_QUEUED)
  889. return FAILED; /* or SUCCESS. Only these */
  890. }
  891. fc->rst_pkt->done = NULL;
  892.         fc->rst_pkt->eh_state = SCSI_STATE_QUEUED;
  893. fc->rst_pkt->eh_timeout.data = (unsigned long) fc->rst_pkt;
  894. fc->rst_pkt->eh_timeout.expires = jiffies + FCP_RESET_TIMEOUT;
  895. fc->rst_pkt->eh_timeout.function = (void (*)(unsigned long))fcp_scsi_reset_done;
  896.         add_timer(&fc->rst_pkt->eh_timeout);
  897. /*
  898.  * Set up the semaphore so we wait for the command to complete.
  899.  */
  900. fc->rst_pkt->host->eh_action = &sem;
  901. fc->rst_pkt->request.rq_status = RQ_SCSI_BUSY;
  902. fc->rst_pkt->done = fcp_scsi_reset_done;
  903. fcp_scsi_queue_it(fc, fc->rst_pkt, fcmd, 0);
  904. down(&sem);
  905. fc->rst_pkt->host->eh_action = NULL;
  906. del_timer(&fc->rst_pkt->eh_timeout);
  907. /*
  908.  * See if timeout.  If so, tell the host to forget about it.
  909.  * In other words, we don't want a callback any more.
  910.  */
  911. if (fc->rst_pkt->eh_state == SCSI_STATE_TIMEOUT ) {
  912. fc->rst_pkt->eh_state = SCSI_STATE_UNUSED;
  913. return FAILED;
  914. }
  915. fc->rst_pkt->eh_state = SCSI_STATE_UNUSED;
  916. return SUCCESS;
  917. }
  918. int fcp_scsi_bus_reset(Scsi_Cmnd *SCpnt)
  919. {
  920. printk ("FC: bus reset!n");
  921. return FAILED;
  922. }
  923. int fcp_scsi_host_reset(Scsi_Cmnd *SCpnt)
  924. {
  925. fc_channel *fc = FC_SCMND(SCpnt);
  926. fcp_cmnd *fcmd = FCP_CMND(SCpnt);
  927. int i;
  928. printk ("FC: host resetn");
  929. for (i=0; i < fc->can_queue; i++) {
  930. if (fc->cmd_slots[i] && SCpnt->result != DID_ABORT) {
  931. SCpnt->result = DID_RESET;
  932. fcmd->done(SCpnt);
  933. fc->cmd_slots[i] = NULL;
  934. }
  935. }
  936. fc->reset(fc);
  937. fc->abort_count = 0;
  938. if (fcp_initialize(fc, 1)) return SUCCESS;
  939. else return FAILED;
  940. }
  941. static int fcp_els_queue_it(fc_channel *fc, fcp_cmnd *fcmd)
  942. {
  943. long i;
  944. i = find_first_zero_bit (fc->scsi_bitmap, fc->scsi_bitmap_end);
  945. set_bit (i, fc->scsi_bitmap);
  946. fcmd->token = i;
  947. fc->scsi_free--;
  948. fc->cmd_slots[fcmd->token] = fcmd;
  949. return fcp_scsi_queue_it(fc, NULL, fcmd, 0);
  950. }
  951. static int fc_do_els(fc_channel *fc, unsigned int alpa, void *data, int len)
  952. {
  953. fcp_cmnd _fcmd, *fcmd;
  954. fc_hdr *fch;
  955. lse l;
  956. int i;
  957. fcmd = &_fcmd;
  958. memset(fcmd, 0, sizeof(fcmd));
  959. FCD(("PLOGI SID %d DID %dn", fc->sid, alpa))
  960. fch = &fcmd->fch;
  961. FILL_FCHDR_RCTL_DID(fch, R_CTL_ELS_REQ, alpa);
  962. FILL_FCHDR_SID(fch, fc->sid);
  963. FILL_FCHDR_TYPE_FCTL(fch, TYPE_EXTENDED_LS, F_CTL_FIRST_SEQ | F_CTL_SEQ_INITIATIVE);
  964. FILL_FCHDR_SEQ_DF_SEQ(fch, 0, 0, 0);
  965. FILL_FCHDR_OXRX(fch, 0xffff, 0xffff);
  966. fch->param = 0;
  967. fcmd->cmd = dma_map_single (fc->dev, data, 2 * len, FC_DMA_BIDIRECTIONAL);
  968. fcmd->rsp = fcmd->cmd + len;
  969. fcmd->cmdlen = len;
  970. fcmd->rsplen = len;
  971. fcmd->data = (dma_addr_t)NULL;
  972. fcmd->fc = fc;
  973. fcmd->class = FC_CLASS_SIMPLE;
  974. fcmd->proto = TYPE_EXTENDED_LS;
  975. memset (&l, 0, sizeof(lse));
  976. l.magic = LSEMAGIC;
  977. init_MUTEX_LOCKED(&l.sem);
  978. l.timer.function = fcp_login_timeout;
  979. l.timer.data = (unsigned long)&l;
  980. l.status = FC_STATUS_TIMED_OUT;
  981. fcmd->ls = (void *)&l;
  982. disable_irq(fc->irq);
  983. fcp_els_queue_it(fc, fcmd);
  984. enable_irq(fc->irq);
  985. for (i = 0;;) {
  986. l.timer.expires = jiffies + 5 * HZ;
  987. add_timer(&l.timer);
  988. down(&l.sem);
  989. del_timer(&l.timer);
  990. if (l.status != FC_STATUS_TIMED_OUT) break;
  991. if (++i == 3) break;
  992. disable_irq(fc->irq);
  993. fcp_scsi_queue_it(fc, NULL, fcmd, 0);
  994. enable_irq(fc->irq);
  995. }
  996. clear_bit(fcmd->token, fc->scsi_bitmap);
  997. fc->scsi_free++;
  998. dma_unmap_single (fc->dev, fcmd->cmd, 2 * len, FC_DMA_BIDIRECTIONAL);
  999. return l.status;
  1000. }
  1001. int fc_do_plogi(fc_channel *fc, unsigned char alpa, fc_wwn *node, fc_wwn *nport)
  1002. {
  1003. logi *l;
  1004. int status;
  1005. l = (logi *)kmalloc(2 * sizeof(logi), GFP_KERNEL);
  1006. if (!l) return -ENOMEM;
  1007. memset(l, 0, 2 * sizeof(logi));
  1008. l->code = LS_PLOGI;
  1009. memcpy (&l->nport_wwn, &fc->wwn_nport, sizeof(fc_wwn));
  1010. memcpy (&l->node_wwn, &fc->wwn_node, sizeof(fc_wwn));
  1011. memcpy (&l->common, fc->common_svc, sizeof(common_svc_parm));
  1012. memcpy (&l->class1, fc->class_svcs, 3*sizeof(svc_parm));
  1013. status = fc_do_els(fc, alpa, l, sizeof(logi));
  1014. if (status == FC_STATUS_OK) {
  1015. if (l[1].code == LS_ACC) {
  1016. #ifdef FCDEBUG
  1017. u32 *u = (u32 *)&l[1].nport_wwn;
  1018. FCD(("AL-PA %02x: Port WWN %08x%08x Node WWN %08x%08xn", alpa, 
  1019. u[0], u[1], u[2], u[3]))
  1020. #endif
  1021. memcpy(nport, &l[1].nport_wwn, sizeof(fc_wwn));
  1022. memcpy(node, &l[1].node_wwn, sizeof(fc_wwn));
  1023. } else
  1024. status = FC_STATUS_BAD_RSP;
  1025. }
  1026. kfree(l);
  1027. return status;
  1028. }
  1029. typedef struct {
  1030. unsigned int code;
  1031. unsigned params[4];
  1032. } prli;
  1033. int fc_do_prli(fc_channel *fc, unsigned char alpa)
  1034. {
  1035. prli *p;
  1036. int status;
  1037. p = (prli *)kmalloc(2 * sizeof(prli), GFP_KERNEL);
  1038. if (!p) return -ENOMEM;
  1039. memset(p, 0, 2 * sizeof(prli));
  1040. p->code = LS_PRLI;
  1041. p->params[0] = 0x08002000;
  1042. p->params[3] = 0x00000022;
  1043. status = fc_do_els(fc, alpa, p, sizeof(prli));
  1044. if (status == FC_STATUS_OK && p[1].code != LS_PRLI_ACC && p[1].code != LS_ACC)
  1045. status = FC_STATUS_BAD_RSP;
  1046. kfree(p);
  1047. return status;
  1048. }