aoecmd.c
上传用户:ajay2009
上传日期:2009-05-22
资源大小:495k
文件大小:14k
源码类别:

驱动编程

开发平台:

Unix_Linux

  1. /* Copyright (c) 2004 Coraid, Inc.  See COPYING for GPL terms. */
  2. /*
  3.  * aoecmd.c
  4.  * Filesystem request handling methods
  5.  */
  6. #include <linux/hdreg.h>
  7. #include <linux/blkdev.h>
  8. #include <linux/skbuff.h>
  9. #include <linux/netdevice.h>
  10. #include "aoe.h"
  11. #define TIMERTICK (HZ / 10)
  12. #define MINTIMER (2 * TIMERTICK)
  13. #define MAXTIMER (HZ << 1)
  14. #define MAXWAIT (60 * 3) /* After MAXWAIT seconds, give up and fail dev */
  15. static struct sk_buff *
  16. new_skb(struct net_device *if_dev, ulong len)
  17. {
  18. struct sk_buff *skb;
  19. skb = alloc_skb(len, GFP_ATOMIC);
  20. if (skb) {
  21. skb->nh.raw = skb->mac.raw = skb->data;
  22. skb->dev = if_dev;
  23. skb->protocol = __constant_htons(ETH_P_AOE);
  24. skb->priority = 0;
  25. skb_put(skb, len);
  26. skb->next = skb->prev = NULL;
  27. /* tell the network layer not to perform IP checksums
  28.  * or to get the NIC to do it
  29.  */
  30. skb->ip_summed = CHECKSUM_NONE;
  31. }
  32. return skb;
  33. }
  34. static struct sk_buff *
  35. skb_prepare(struct aoedev *d, struct frame *f)
  36. {
  37. struct sk_buff *skb;
  38. char *p;
  39. skb = new_skb(d->ifp, f->ndata + f->writedatalen);
  40. if (!skb) {
  41. printk(KERN_INFO "aoe: skb_prepare: failure to allocate skbn");
  42. return NULL;
  43. }
  44. p = skb->mac.raw;
  45. memcpy(p, f->data, f->ndata);
  46. if (f->writedatalen) {
  47. p += sizeof(struct aoe_hdr) + sizeof(struct aoe_atahdr);
  48. memcpy(p, f->bufaddr, f->writedatalen);
  49. }
  50. return skb;
  51. }
  52. static struct frame *
  53. getframe(struct aoedev *d, int tag)
  54. {
  55. struct frame *f, *e;
  56. f = d->frames;
  57. e = f + d->nframes;
  58. for (; f<e; f++)
  59. if (f->tag == tag)
  60. return f;
  61. return NULL;
  62. }
  63. /*
  64.  * Leave the top bit clear so we have tagspace for userland.
  65.  * The bottom 16 bits are the xmit tick for rexmit/rttavg processing.
  66.  * This driver reserves tag -1 to mean "unused frame."
  67.  */
  68. static int
  69. newtag(struct aoedev *d)
  70. {
  71. register ulong n;
  72. n = jiffies & 0xffff;
  73. return n |= (++d->lasttag & 0x7fff) << 16;
  74. }
  75. static int
  76. aoehdr_atainit(struct aoedev *d, struct aoe_hdr *h)
  77. {
  78. u32 host_tag = newtag(d);
  79. memcpy(h->src, d->ifp->dev_addr, sizeof h->src);
  80. memcpy(h->dst, d->addr, sizeof h->dst);
  81. h->type = __constant_cpu_to_be16(ETH_P_AOE);
  82. h->verfl = AOE_HVER;
  83. h->major = cpu_to_be16(d->aoemajor);
  84. h->minor = d->aoeminor;
  85. h->cmd = AOECMD_ATA;
  86. h->tag = cpu_to_be32(host_tag);
  87. return host_tag;
  88. }
  89. static void
  90. aoecmd_ata_rw(struct aoedev *d, struct frame *f)
  91. {
  92. struct aoe_hdr *h;
  93. struct aoe_atahdr *ah;
  94. struct buf *buf;
  95. struct sk_buff *skb;
  96. ulong bcnt;
  97. register sector_t sector;
  98. char writebit, extbit;
  99. writebit = 0x10;
  100. extbit = 0x4;
  101. buf = d->inprocess;
  102. sector = buf->sector;
  103. bcnt = buf->bv_resid;
  104. if (bcnt > MAXATADATA)
  105. bcnt = MAXATADATA;
  106. /* initialize the headers & frame */
  107. h = (struct aoe_hdr *) f->data;
  108. ah = (struct aoe_atahdr *) (h+1);
  109. f->ndata = sizeof *h + sizeof *ah;
  110. memset(h, 0, f->ndata);
  111. f->tag = aoehdr_atainit(d, h);
  112. f->waited = 0;
  113. f->buf = buf;
  114. f->bufaddr = buf->bufaddr;
  115. /* set up ata header */
  116. ah->scnt = bcnt >> 9;
  117. ah->lba0 = sector;
  118. ah->lba1 = sector >>= 8;
  119. ah->lba2 = sector >>= 8;
  120. ah->lba3 = sector >>= 8;
  121. if (d->flags & DEVFL_EXT) {
  122. ah->aflags |= AOEAFL_EXT;
  123. ah->lba4 = sector >>= 8;
  124. ah->lba5 = sector >>= 8;
  125. } else {
  126. extbit = 0;
  127. ah->lba3 &= 0x0f;
  128. ah->lba3 |= 0xe0; /* LBA bit + obsolete 0xa0 */
  129. }
  130. if (bio_data_dir(buf->bio) == WRITE) {
  131. ah->aflags |= AOEAFL_WRITE;
  132. f->writedatalen = bcnt;
  133. } else {
  134. writebit = 0;
  135. f->writedatalen = 0;
  136. }
  137. ah->cmdstat = WIN_READ | writebit | extbit;
  138. /* mark all tracking fields and load out */
  139. buf->nframesout += 1;
  140. buf->bufaddr += bcnt;
  141. buf->bv_resid -= bcnt;
  142. /* printk(KERN_INFO "aoe: bv_resid=%ldn", buf->bv_resid); */
  143. buf->resid -= bcnt;
  144. buf->sector += bcnt >> 9;
  145. if (buf->resid == 0) {
  146. d->inprocess = NULL;
  147. } else if (buf->bv_resid == 0) {
  148. buf->bv++;
  149. buf->bv_resid = buf->bv->bv_len;
  150. buf->bufaddr = page_address(buf->bv->bv_page) + buf->bv->bv_offset;
  151. }
  152. skb = skb_prepare(d, f);
  153. if (skb) {
  154. skb->next = NULL;
  155. if (d->sendq_hd)
  156. d->sendq_tl->next = skb;
  157. else
  158. d->sendq_hd = skb;
  159. d->sendq_tl = skb;
  160. }
  161. }
  162. /* enters with d->lock held */
  163. void
  164. aoecmd_work(struct aoedev *d)
  165. {
  166. struct frame *f;
  167. struct buf *buf;
  168. loop:
  169. f = getframe(d, FREETAG);
  170. if (f == NULL)
  171. return;
  172. if (d->inprocess == NULL) {
  173. if (list_empty(&d->bufq))
  174. return;
  175. buf = container_of(d->bufq.next, struct buf, bufs);
  176. list_del(d->bufq.next);
  177. /*printk(KERN_INFO "aoecmd_work: bi_size=%ldn", buf->bio->bi_size); */
  178. d->inprocess = buf;
  179. }
  180. aoecmd_ata_rw(d, f);
  181. goto loop;
  182. }
  183. static void
  184. rexmit(struct aoedev *d, struct frame *f)
  185. {
  186. struct sk_buff *skb;
  187. struct aoe_hdr *h;
  188. char buf[128];
  189. u32 n;
  190. n = newtag(d);
  191. snprintf(buf, sizeof buf,
  192. "%15s e%ld.%ld oldtag=%08x@%08lx newtag=%08xn",
  193. "retransmit",
  194. d->aoemajor, d->aoeminor, f->tag, jiffies, n);
  195. aoechr_error(buf);
  196. h = (struct aoe_hdr *) f->data;
  197. f->tag = n;
  198. h->tag = cpu_to_be32(n);
  199. skb = skb_prepare(d, f);
  200. if (skb) {
  201. skb->next = NULL;
  202. if (d->sendq_hd)
  203. d->sendq_tl->next = skb;
  204. else
  205. d->sendq_hd = skb;
  206. d->sendq_tl = skb;
  207. }
  208. }
  209. static int
  210. tsince(int tag)
  211. {
  212. int n;
  213. n = jiffies & 0xffff;
  214. n -= tag & 0xffff;
  215. if (n < 0)
  216. n += 1<<16;
  217. return n;
  218. }
  219. static void
  220. rexmit_timer(ulong vp)
  221. {
  222. struct aoedev *d;
  223. struct frame *f, *e;
  224. struct sk_buff *sl;
  225. register long timeout;
  226. ulong flags, n;
  227. d = (struct aoedev *) vp;
  228. sl = NULL;
  229. /* timeout is always ~150% of the moving average */
  230. timeout = d->rttavg;
  231. timeout += timeout >> 1;
  232. spin_lock_irqsave(&d->lock, flags);
  233. if (d->flags & DEVFL_TKILL) {
  234. tdie: spin_unlock_irqrestore(&d->lock, flags);
  235. return;
  236. }
  237. f = d->frames;
  238. e = f + d->nframes;
  239. for (; f<e; f++) {
  240. if (f->tag != FREETAG && tsince(f->tag) >= timeout) {
  241. n = f->waited += timeout;
  242. n /= HZ;
  243. if (n > MAXWAIT) { /* waited too long.  device failure. */
  244. aoedev_downdev(d);
  245. goto tdie;
  246. }
  247. rexmit(d, f);
  248. }
  249. }
  250. sl = d->sendq_hd;
  251. d->sendq_hd = d->sendq_tl = NULL;
  252. if (sl) {
  253. n = d->rttavg <<= 1;
  254. if (n > MAXTIMER)
  255. d->rttavg = MAXTIMER;
  256. }
  257. d->timer.expires = jiffies + TIMERTICK;
  258. add_timer(&d->timer);
  259. spin_unlock_irqrestore(&d->lock, flags);
  260. aoenet_xmit(sl);
  261. }
  262. static void
  263. ataid_complete(struct aoedev *d, unsigned char *id)
  264. {
  265. u64 ssize;
  266. u16 n;
  267. /* word 83: command set supported */
  268. n = le16_to_cpup((__le16 *) &id[83<<1]);
  269. /* word 86: command set/feature enabled */
  270. n |= le16_to_cpup((__le16 *) &id[86<<1]);
  271. if (n & (1<<10)) { /* bit 10: LBA 48 */
  272. d->flags |= DEVFL_EXT;
  273. /* word 100: number lba48 sectors */
  274. ssize = le64_to_cpup((__le64 *) &id[100<<1]);
  275. /* set as in ide-disk.c:init_idedisk_capacity */
  276. d->geo.cylinders = ssize;
  277. d->geo.cylinders /= (255 * 63);
  278. d->geo.heads = 255;
  279. d->geo.sectors = 63;
  280. } else {
  281. d->flags &= ~DEVFL_EXT;
  282. /* number lba28 sectors */
  283. ssize = le32_to_cpup((__le32 *) &id[60<<1]);
  284. /* NOTE: obsolete in ATA 6 */
  285. d->geo.cylinders = le16_to_cpup((__le16 *) &id[54<<1]);
  286. d->geo.heads = le16_to_cpup((__le16 *) &id[55<<1]);
  287. d->geo.sectors = le16_to_cpup((__le16 *) &id[56<<1]);
  288. }
  289. d->ssize = ssize;
  290. d->geo.start = 0;
  291. if (d->gd != NULL) {
  292. d->gd->capacity = ssize;
  293. d->flags |= DEVFL_UP;
  294. return;
  295. }
  296. if (d->flags & DEVFL_WORKON) {
  297. printk(KERN_INFO "aoe: ataid_complete: can't schedule work, it's already on!  "
  298. "(This really shouldn't happen).n");
  299. return;
  300. }
  301. INIT_WORK(&d->work, aoeblk_gdalloc, d);
  302. schedule_work(&d->work);
  303. d->flags |= DEVFL_WORKON;
  304. }
  305. static void
  306. calc_rttavg(struct aoedev *d, int rtt)
  307. {
  308. register long n;
  309. n = rtt;
  310. if (n < MINTIMER)
  311. n = MINTIMER;
  312. else if (n > MAXTIMER)
  313. n = MAXTIMER;
  314. /* g == .25; cf. Congestion Avoidance and Control, Jacobson & Karels; 1988 */
  315. n -= d->rttavg;
  316. d->rttavg += n >> 2;
  317. }
  318. void
  319. aoecmd_ata_rsp(struct sk_buff *skb)
  320. {
  321. struct aoedev *d;
  322. struct aoe_hdr *hin;
  323. struct aoe_atahdr *ahin, *ahout;
  324. struct frame *f;
  325. struct buf *buf;
  326. struct sk_buff *sl;
  327. register long n;
  328. ulong flags;
  329. char ebuf[128];
  330. u16 aoemajor;
  331. hin = (struct aoe_hdr *) skb->mac.raw;
  332. aoemajor = be16_to_cpu(hin->major);
  333. d = aoedev_by_aoeaddr(aoemajor, hin->minor);
  334. if (d == NULL) {
  335. snprintf(ebuf, sizeof ebuf, "aoecmd_ata_rsp: ata response "
  336. "for unknown device %d.%dn",
  337.  aoemajor, hin->minor);
  338. aoechr_error(ebuf);
  339. return;
  340. }
  341. spin_lock_irqsave(&d->lock, flags);
  342. f = getframe(d, be32_to_cpu(hin->tag));
  343. if (f == NULL) {
  344. spin_unlock_irqrestore(&d->lock, flags);
  345. snprintf(ebuf, sizeof ebuf,
  346. "%15s e%d.%d    tag=%08x@%08lxn",
  347. "unexpected rsp",
  348. be16_to_cpu(hin->major),
  349. hin->minor,
  350. be32_to_cpu(hin->tag),
  351. jiffies);
  352. aoechr_error(ebuf);
  353. return;
  354. }
  355. calc_rttavg(d, tsince(f->tag));
  356. ahin = (struct aoe_atahdr *) (hin+1);
  357. ahout = (struct aoe_atahdr *) (f->data + sizeof(struct aoe_hdr));
  358. buf = f->buf;
  359. if (ahin->cmdstat & 0xa9) { /* these bits cleared on success */
  360. printk(KERN_CRIT "aoe: aoecmd_ata_rsp: ata error cmd=%2.2Xh "
  361. "stat=%2.2Xh from e%ld.%ldn", 
  362. ahout->cmdstat, ahin->cmdstat,
  363. d->aoemajor, d->aoeminor);
  364. if (buf)
  365. buf->flags |= BUFFL_FAIL;
  366. } else {
  367. switch (ahout->cmdstat) {
  368. case WIN_READ:
  369. case WIN_READ_EXT:
  370. n = ahout->scnt << 9;
  371. if (skb->len - sizeof *hin - sizeof *ahin < n) {
  372. printk(KERN_CRIT "aoe: aoecmd_ata_rsp: runt "
  373. "ata data size in read.  skb->len=%dn",
  374. skb->len);
  375. /* fail frame f?  just returning will rexmit. */
  376. spin_unlock_irqrestore(&d->lock, flags);
  377. return;
  378. }
  379. memcpy(f->bufaddr, ahin+1, n);
  380. case WIN_WRITE:
  381. case WIN_WRITE_EXT:
  382. break;
  383. case WIN_IDENTIFY:
  384. if (skb->len - sizeof *hin - sizeof *ahin < 512) {
  385. printk(KERN_INFO "aoe: aoecmd_ata_rsp: runt data size "
  386. "in ataid.  skb->len=%dn", skb->len);
  387. spin_unlock_irqrestore(&d->lock, flags);
  388. return;
  389. }
  390. ataid_complete(d, (char *) (ahin+1));
  391. /* d->flags |= DEVFL_WC_UPDATE; */
  392. break;
  393. default:
  394. printk(KERN_INFO "aoe: aoecmd_ata_rsp: unrecognized "
  395.        "outbound ata command %2.2Xh for %d.%dn", 
  396.        ahout->cmdstat,
  397.        be16_to_cpu(hin->major),
  398.        hin->minor);
  399. }
  400. }
  401. if (buf) {
  402. buf->nframesout -= 1;
  403. if (buf->nframesout == 0 && buf->resid == 0) {
  404. unsigned long duration = jiffies - buf->start_time;
  405. unsigned long n_sect = buf->bio->bi_size >> 9;
  406. struct gendisk *disk = d->gd;
  407. if (bio_data_dir(buf->bio) == WRITE) {
  408. disk_stat_inc(disk, writes);
  409. disk_stat_add(disk, write_ticks, duration);
  410. disk_stat_add(disk, write_sectors, n_sect);
  411. } else {
  412. disk_stat_inc(disk, reads);
  413. disk_stat_add(disk, read_ticks, duration);
  414. disk_stat_add(disk, read_sectors, n_sect);
  415. }
  416. disk_stat_add(disk, io_ticks, duration);
  417. n = (buf->flags & BUFFL_FAIL) ? -EIO : 0;
  418. bio_endio(buf->bio, buf->bio->bi_size, n);
  419. mempool_free(buf, d->bufpool);
  420. }
  421. }
  422. f->buf = NULL;
  423. f->tag = FREETAG;
  424. aoecmd_work(d);
  425. sl = d->sendq_hd;
  426. d->sendq_hd = d->sendq_tl = NULL;
  427. spin_unlock_irqrestore(&d->lock, flags);
  428. aoenet_xmit(sl);
  429. }
  430. void
  431. aoecmd_cfg(ushort aoemajor, unsigned char aoeminor)
  432. {
  433. struct aoe_hdr *h;
  434. struct aoe_cfghdr *ch;
  435. struct sk_buff *skb, *sl;
  436. struct net_device *ifp;
  437. sl = NULL;
  438. read_lock(&dev_base_lock);
  439. for (ifp = dev_base; ifp; dev_put(ifp), ifp = ifp->next) {
  440. dev_hold(ifp);
  441. if (!is_aoe_netif(ifp))
  442. continue;
  443. skb = new_skb(ifp, sizeof *h + sizeof *ch);
  444. if (skb == NULL) {
  445. printk(KERN_INFO "aoe: aoecmd_cfg: skb alloc failuren");
  446. continue;
  447. }
  448. h = (struct aoe_hdr *) skb->mac.raw;
  449. memset(h, 0, sizeof *h + sizeof *ch);
  450. memset(h->dst, 0xff, sizeof h->dst);
  451. memcpy(h->src, ifp->dev_addr, sizeof h->src);
  452. h->type = __constant_cpu_to_be16(ETH_P_AOE);
  453. h->verfl = AOE_HVER;
  454. h->major = cpu_to_be16(aoemajor);
  455. h->minor = aoeminor;
  456. h->cmd = AOECMD_CFG;
  457. skb->next = sl;
  458. sl = skb;
  459. }
  460. read_unlock(&dev_base_lock);
  461. aoenet_xmit(sl);
  462. }
  463.  
  464. /*
  465.  * Since we only call this in one place (and it only prepares one frame)
  466.  * we just return the skb.  Usually we'd chain it up to the aoedev sendq.
  467.  */
  468. static struct sk_buff *
  469. aoecmd_ata_id(struct aoedev *d)
  470. {
  471. struct aoe_hdr *h;
  472. struct aoe_atahdr *ah;
  473. struct frame *f;
  474. struct sk_buff *skb;
  475. f = getframe(d, FREETAG);
  476. if (f == NULL) {
  477. printk(KERN_CRIT "aoe: aoecmd_ata_id: can't get a frame.  "
  478. "This shouldn't happen.n");
  479. return NULL;
  480. }
  481. /* initialize the headers & frame */
  482. h = (struct aoe_hdr *) f->data;
  483. ah = (struct aoe_atahdr *) (h+1);
  484. f->ndata = sizeof *h + sizeof *ah;
  485. memset(h, 0, f->ndata);
  486. f->tag = aoehdr_atainit(d, h);
  487. f->waited = 0;
  488. f->writedatalen = 0;
  489. /* this message initializes the device, so we reset the rttavg */
  490. d->rttavg = MAXTIMER;
  491. /* set up ata header */
  492. ah->scnt = 1;
  493. ah->cmdstat = WIN_IDENTIFY;
  494. ah->lba3 = 0xa0;
  495. skb = skb_prepare(d, f);
  496. /* we now want to start the rexmit tracking */
  497. d->flags &= ~DEVFL_TKILL;
  498. d->timer.data = (ulong) d;
  499. d->timer.function = rexmit_timer;
  500. d->timer.expires = jiffies + TIMERTICK;
  501. add_timer(&d->timer);
  502. return skb;
  503. }
  504.  
  505. void
  506. aoecmd_cfg_rsp(struct sk_buff *skb)
  507. {
  508. struct aoedev *d;
  509. struct aoe_hdr *h;
  510. struct aoe_cfghdr *ch;
  511. ulong flags, sysminor, aoemajor;
  512. u16 bufcnt;
  513. struct sk_buff *sl;
  514. enum { MAXFRAMES = 8 };
  515. h = (struct aoe_hdr *) skb->mac.raw;
  516. ch = (struct aoe_cfghdr *) (h+1);
  517. /*
  518.  * Enough people have their dip switches set backwards to
  519.  * warrant a loud message for this special case.
  520.  */
  521. aoemajor = be16_to_cpu(h->major);
  522. if (aoemajor == 0xfff) {
  523. printk(KERN_CRIT "aoe: aoecmd_cfg_rsp: Warning: shelf "
  524. "address is all ones.  Check shelf dip switchesn");
  525. return;
  526. }
  527. sysminor = SYSMINOR(aoemajor, h->minor);
  528. if (sysminor * AOE_PARTITIONS + AOE_PARTITIONS > MINORMASK) {
  529. printk(KERN_INFO
  530. "aoe: e%ld.%d: minor number too largen", 
  531. aoemajor, (int) h->minor);
  532. return;
  533. }
  534. bufcnt = be16_to_cpu(ch->bufcnt);
  535. if (bufcnt > MAXFRAMES) /* keep it reasonable */
  536. bufcnt = MAXFRAMES;
  537. d = aoedev_set(sysminor, h->src, skb->dev, bufcnt);
  538. if (d == NULL) {
  539. printk(KERN_INFO "aoe: aoecmd_cfg_rsp: device set failuren");
  540. return;
  541. }
  542. spin_lock_irqsave(&d->lock, flags);
  543. if (d->flags & (DEVFL_UP | DEVFL_CLOSEWAIT)) {
  544. spin_unlock_irqrestore(&d->lock, flags);
  545. return;
  546. }
  547. d->fw_ver = be16_to_cpu(ch->fwver);
  548. /* we get here only if the device is new */
  549. sl = aoecmd_ata_id(d);
  550. spin_unlock_irqrestore(&d->lock, flags);
  551. aoenet_xmit(sl);
  552. }