fc.c 31 KB

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