xref: /linux/drivers/block/aoe/aoecmd.c (revision f3d9478b2ce468c3115b02ecae7e975990697f15)
1 /* Copyright (c) 2004 Coraid, Inc.  See COPYING for GPL terms. */
2 /*
3  * aoecmd.c
4  * Filesystem request handling methods
5  */
6 
7 #include <linux/hdreg.h>
8 #include <linux/blkdev.h>
9 #include <linux/skbuff.h>
10 #include <linux/netdevice.h>
11 #include <linux/genhd.h>
12 #include <asm/unaligned.h>
13 #include "aoe.h"
14 
15 #define TIMERTICK (HZ / 10)
16 #define MINTIMER (2 * TIMERTICK)
17 #define MAXTIMER (HZ << 1)
18 #define MAXWAIT (60 * 3)	/* After MAXWAIT seconds, give up and fail dev */
19 
20 static struct sk_buff *
21 new_skb(struct net_device *if_dev, ulong len)
22 {
23 	struct sk_buff *skb;
24 
25 	skb = alloc_skb(len, GFP_ATOMIC);
26 	if (skb) {
27 		skb->nh.raw = skb->mac.raw = skb->data;
28 		skb->dev = if_dev;
29 		skb->protocol = __constant_htons(ETH_P_AOE);
30 		skb->priority = 0;
31 		skb_put(skb, len);
32 		memset(skb->head, 0, len);
33 		skb->next = skb->prev = NULL;
34 
35 		/* tell the network layer not to perform IP checksums
36 		 * or to get the NIC to do it
37 		 */
38 		skb->ip_summed = CHECKSUM_NONE;
39 	}
40 	return skb;
41 }
42 
43 static struct sk_buff *
44 skb_prepare(struct aoedev *d, struct frame *f)
45 {
46 	struct sk_buff *skb;
47 	char *p;
48 
49 	skb = new_skb(d->ifp, f->ndata + f->writedatalen);
50 	if (!skb) {
51 		printk(KERN_INFO "aoe: skb_prepare: failure to allocate skb\n");
52 		return NULL;
53 	}
54 
55 	p = skb->mac.raw;
56 	memcpy(p, f->data, f->ndata);
57 
58 	if (f->writedatalen) {
59 		p += sizeof(struct aoe_hdr) + sizeof(struct aoe_atahdr);
60 		memcpy(p, f->bufaddr, f->writedatalen);
61 	}
62 
63 	return skb;
64 }
65 
66 static struct frame *
67 getframe(struct aoedev *d, int tag)
68 {
69 	struct frame *f, *e;
70 
71 	f = d->frames;
72 	e = f + d->nframes;
73 	for (; f<e; f++)
74 		if (f->tag == tag)
75 			return f;
76 	return NULL;
77 }
78 
79 /*
80  * Leave the top bit clear so we have tagspace for userland.
81  * The bottom 16 bits are the xmit tick for rexmit/rttavg processing.
82  * This driver reserves tag -1 to mean "unused frame."
83  */
84 static int
85 newtag(struct aoedev *d)
86 {
87 	register ulong n;
88 
89 	n = jiffies & 0xffff;
90 	return n |= (++d->lasttag & 0x7fff) << 16;
91 }
92 
93 static int
94 aoehdr_atainit(struct aoedev *d, struct aoe_hdr *h)
95 {
96 	u32 host_tag = newtag(d);
97 
98 	memcpy(h->src, d->ifp->dev_addr, sizeof h->src);
99 	memcpy(h->dst, d->addr, sizeof h->dst);
100 	h->type = __constant_cpu_to_be16(ETH_P_AOE);
101 	h->verfl = AOE_HVER;
102 	h->major = cpu_to_be16(d->aoemajor);
103 	h->minor = d->aoeminor;
104 	h->cmd = AOECMD_ATA;
105 	h->tag = cpu_to_be32(host_tag);
106 
107 	return host_tag;
108 }
109 
110 static void
111 aoecmd_ata_rw(struct aoedev *d, struct frame *f)
112 {
113 	struct aoe_hdr *h;
114 	struct aoe_atahdr *ah;
115 	struct buf *buf;
116 	struct sk_buff *skb;
117 	ulong bcnt;
118 	register sector_t sector;
119 	char writebit, extbit;
120 
121 	writebit = 0x10;
122 	extbit = 0x4;
123 
124 	buf = d->inprocess;
125 
126 	sector = buf->sector;
127 	bcnt = buf->bv_resid;
128 	if (bcnt > MAXATADATA)
129 		bcnt = MAXATADATA;
130 
131 	/* initialize the headers & frame */
132 	h = (struct aoe_hdr *) f->data;
133 	ah = (struct aoe_atahdr *) (h+1);
134 	f->ndata = sizeof *h + sizeof *ah;
135 	memset(h, 0, f->ndata);
136 	f->tag = aoehdr_atainit(d, h);
137 	f->waited = 0;
138 	f->buf = buf;
139 	f->bufaddr = buf->bufaddr;
140 
141 	/* set up ata header */
142 	ah->scnt = bcnt >> 9;
143 	ah->lba0 = sector;
144 	ah->lba1 = sector >>= 8;
145 	ah->lba2 = sector >>= 8;
146 	ah->lba3 = sector >>= 8;
147 	if (d->flags & DEVFL_EXT) {
148 		ah->aflags |= AOEAFL_EXT;
149 		ah->lba4 = sector >>= 8;
150 		ah->lba5 = sector >>= 8;
151 	} else {
152 		extbit = 0;
153 		ah->lba3 &= 0x0f;
154 		ah->lba3 |= 0xe0;	/* LBA bit + obsolete 0xa0 */
155 	}
156 
157 	if (bio_data_dir(buf->bio) == WRITE) {
158 		ah->aflags |= AOEAFL_WRITE;
159 		f->writedatalen = bcnt;
160 	} else {
161 		writebit = 0;
162 		f->writedatalen = 0;
163 	}
164 
165 	ah->cmdstat = WIN_READ | writebit | extbit;
166 
167 	/* mark all tracking fields and load out */
168 	buf->nframesout += 1;
169 	buf->bufaddr += bcnt;
170 	buf->bv_resid -= bcnt;
171 /* printk(KERN_INFO "aoe: bv_resid=%ld\n", buf->bv_resid); */
172 	buf->resid -= bcnt;
173 	buf->sector += bcnt >> 9;
174 	if (buf->resid == 0) {
175 		d->inprocess = NULL;
176 	} else if (buf->bv_resid == 0) {
177 		buf->bv++;
178 		buf->bv_resid = buf->bv->bv_len;
179 		buf->bufaddr = page_address(buf->bv->bv_page) + buf->bv->bv_offset;
180 	}
181 
182 	skb = skb_prepare(d, f);
183 	if (skb) {
184 		skb->next = NULL;
185 		if (d->sendq_hd)
186 			d->sendq_tl->next = skb;
187 		else
188 			d->sendq_hd = skb;
189 		d->sendq_tl = skb;
190 	}
191 }
192 
193 /* some callers cannot sleep, and they can call this function,
194  * transmitting the packets later, when interrupts are on
195  */
196 static struct sk_buff *
197 aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff **tail)
198 {
199 	struct aoe_hdr *h;
200 	struct aoe_cfghdr *ch;
201 	struct sk_buff *skb, *sl, *sl_tail;
202 	struct net_device *ifp;
203 
204 	sl = sl_tail = NULL;
205 
206 	read_lock(&dev_base_lock);
207 	for (ifp = dev_base; ifp; dev_put(ifp), ifp = ifp->next) {
208 		dev_hold(ifp);
209 		if (!is_aoe_netif(ifp))
210 			continue;
211 
212 		skb = new_skb(ifp, sizeof *h + sizeof *ch);
213 		if (skb == NULL) {
214 			printk(KERN_INFO "aoe: aoecmd_cfg: skb alloc failure\n");
215 			continue;
216 		}
217 		if (sl_tail == NULL)
218 			sl_tail = skb;
219 		h = (struct aoe_hdr *) skb->mac.raw;
220 		memset(h, 0, sizeof *h + sizeof *ch);
221 
222 		memset(h->dst, 0xff, sizeof h->dst);
223 		memcpy(h->src, ifp->dev_addr, sizeof h->src);
224 		h->type = __constant_cpu_to_be16(ETH_P_AOE);
225 		h->verfl = AOE_HVER;
226 		h->major = cpu_to_be16(aoemajor);
227 		h->minor = aoeminor;
228 		h->cmd = AOECMD_CFG;
229 
230 		skb->next = sl;
231 		sl = skb;
232 	}
233 	read_unlock(&dev_base_lock);
234 
235 	if (tail != NULL)
236 		*tail = sl_tail;
237 	return sl;
238 }
239 
240 /* enters with d->lock held */
241 void
242 aoecmd_work(struct aoedev *d)
243 {
244 	struct frame *f;
245 	struct buf *buf;
246 
247 	if (d->flags & DEVFL_PAUSE) {
248 		if (!aoedev_isbusy(d))
249 			d->sendq_hd = aoecmd_cfg_pkts(d->aoemajor,
250 						d->aoeminor, &d->sendq_tl);
251 		return;
252 	}
253 
254 loop:
255 	f = getframe(d, FREETAG);
256 	if (f == NULL)
257 		return;
258 	if (d->inprocess == NULL) {
259 		if (list_empty(&d->bufq))
260 			return;
261 		buf = container_of(d->bufq.next, struct buf, bufs);
262 		list_del(d->bufq.next);
263 /*printk(KERN_INFO "aoecmd_work: bi_size=%ld\n", buf->bio->bi_size); */
264 		d->inprocess = buf;
265 	}
266 	aoecmd_ata_rw(d, f);
267 	goto loop;
268 }
269 
270 static void
271 rexmit(struct aoedev *d, struct frame *f)
272 {
273 	struct sk_buff *skb;
274 	struct aoe_hdr *h;
275 	char buf[128];
276 	u32 n;
277 
278 	n = newtag(d);
279 
280 	snprintf(buf, sizeof buf,
281 		"%15s e%ld.%ld oldtag=%08x@%08lx newtag=%08x\n",
282 		"retransmit",
283 		d->aoemajor, d->aoeminor, f->tag, jiffies, n);
284 	aoechr_error(buf);
285 
286 	h = (struct aoe_hdr *) f->data;
287 	f->tag = n;
288 	h->tag = cpu_to_be32(n);
289 	memcpy(h->dst, d->addr, sizeof h->dst);
290 	memcpy(h->src, d->ifp->dev_addr, sizeof h->src);
291 
292 	skb = skb_prepare(d, f);
293 	if (skb) {
294 		skb->next = NULL;
295 		if (d->sendq_hd)
296 			d->sendq_tl->next = skb;
297 		else
298 			d->sendq_hd = skb;
299 		d->sendq_tl = skb;
300 	}
301 }
302 
303 static int
304 tsince(int tag)
305 {
306 	int n;
307 
308 	n = jiffies & 0xffff;
309 	n -= tag & 0xffff;
310 	if (n < 0)
311 		n += 1<<16;
312 	return n;
313 }
314 
315 static void
316 rexmit_timer(ulong vp)
317 {
318 	struct aoedev *d;
319 	struct frame *f, *e;
320 	struct sk_buff *sl;
321 	register long timeout;
322 	ulong flags, n;
323 
324 	d = (struct aoedev *) vp;
325 	sl = NULL;
326 
327 	/* timeout is always ~150% of the moving average */
328 	timeout = d->rttavg;
329 	timeout += timeout >> 1;
330 
331 	spin_lock_irqsave(&d->lock, flags);
332 
333 	if (d->flags & DEVFL_TKILL) {
334 		spin_unlock_irqrestore(&d->lock, flags);
335 		return;
336 	}
337 	f = d->frames;
338 	e = f + d->nframes;
339 	for (; f<e; f++) {
340 		if (f->tag != FREETAG && tsince(f->tag) >= timeout) {
341 			n = f->waited += timeout;
342 			n /= HZ;
343 			if (n > MAXWAIT) { /* waited too long.  device failure. */
344 				aoedev_downdev(d);
345 				break;
346 			}
347 			rexmit(d, f);
348 		}
349 	}
350 
351 	sl = d->sendq_hd;
352 	d->sendq_hd = d->sendq_tl = NULL;
353 	if (sl) {
354 		n = d->rttavg <<= 1;
355 		if (n > MAXTIMER)
356 			d->rttavg = MAXTIMER;
357 	}
358 
359 	d->timer.expires = jiffies + TIMERTICK;
360 	add_timer(&d->timer);
361 
362 	spin_unlock_irqrestore(&d->lock, flags);
363 
364 	aoenet_xmit(sl);
365 }
366 
367 /* this function performs work that has been deferred until sleeping is OK
368  */
369 void
370 aoecmd_sleepwork(void *vp)
371 {
372 	struct aoedev *d = (struct aoedev *) vp;
373 
374 	if (d->flags & DEVFL_GDALLOC)
375 		aoeblk_gdalloc(d);
376 
377 	if (d->flags & DEVFL_NEWSIZE) {
378 		struct block_device *bd;
379 		unsigned long flags;
380 		u64 ssize;
381 
382 		ssize = d->gd->capacity;
383 		bd = bdget_disk(d->gd, 0);
384 
385 		if (bd) {
386 			mutex_lock(&bd->bd_inode->i_mutex);
387 			i_size_write(bd->bd_inode, (loff_t)ssize<<9);
388 			mutex_unlock(&bd->bd_inode->i_mutex);
389 			bdput(bd);
390 		}
391 		spin_lock_irqsave(&d->lock, flags);
392 		d->flags |= DEVFL_UP;
393 		d->flags &= ~DEVFL_NEWSIZE;
394 		spin_unlock_irqrestore(&d->lock, flags);
395 	}
396 }
397 
398 static void
399 ataid_complete(struct aoedev *d, unsigned char *id)
400 {
401 	u64 ssize;
402 	u16 n;
403 
404 	/* word 83: command set supported */
405 	n = le16_to_cpu(get_unaligned((__le16 *) &id[83<<1]));
406 
407 	/* word 86: command set/feature enabled */
408 	n |= le16_to_cpu(get_unaligned((__le16 *) &id[86<<1]));
409 
410 	if (n & (1<<10)) {	/* bit 10: LBA 48 */
411 		d->flags |= DEVFL_EXT;
412 
413 		/* word 100: number lba48 sectors */
414 		ssize = le64_to_cpu(get_unaligned((__le64 *) &id[100<<1]));
415 
416 		/* set as in ide-disk.c:init_idedisk_capacity */
417 		d->geo.cylinders = ssize;
418 		d->geo.cylinders /= (255 * 63);
419 		d->geo.heads = 255;
420 		d->geo.sectors = 63;
421 	} else {
422 		d->flags &= ~DEVFL_EXT;
423 
424 		/* number lba28 sectors */
425 		ssize = le32_to_cpu(get_unaligned((__le32 *) &id[60<<1]));
426 
427 		/* NOTE: obsolete in ATA 6 */
428 		d->geo.cylinders = le16_to_cpu(get_unaligned((__le16 *) &id[54<<1]));
429 		d->geo.heads = le16_to_cpu(get_unaligned((__le16 *) &id[55<<1]));
430 		d->geo.sectors = le16_to_cpu(get_unaligned((__le16 *) &id[56<<1]));
431 	}
432 
433 	if (d->ssize != ssize)
434 		printk(KERN_INFO "aoe: %012llx e%lu.%lu v%04x has %llu "
435 			"sectors\n", (unsigned long long)mac_addr(d->addr),
436 			d->aoemajor, d->aoeminor,
437 			d->fw_ver, (long long)ssize);
438 	d->ssize = ssize;
439 	d->geo.start = 0;
440 	if (d->gd != NULL) {
441 		d->gd->capacity = ssize;
442 		d->flags |= DEVFL_NEWSIZE;
443 	} else {
444 		if (d->flags & DEVFL_GDALLOC) {
445 			printk(KERN_INFO "aoe: %s: %s e%lu.%lu, %s\n",
446 			       __FUNCTION__,
447 			       "can't schedule work for",
448 			       d->aoemajor, d->aoeminor,
449 			       "it's already on! (This really shouldn't happen).\n");
450 			return;
451 		}
452 		d->flags |= DEVFL_GDALLOC;
453 	}
454 	schedule_work(&d->work);
455 }
456 
457 static void
458 calc_rttavg(struct aoedev *d, int rtt)
459 {
460 	register long n;
461 
462 	n = rtt;
463 	if (n < MINTIMER)
464 		n = MINTIMER;
465 	else if (n > MAXTIMER)
466 		n = MAXTIMER;
467 
468 	/* g == .25; cf. Congestion Avoidance and Control, Jacobson & Karels; 1988 */
469 	n -= d->rttavg;
470 	d->rttavg += n >> 2;
471 }
472 
473 void
474 aoecmd_ata_rsp(struct sk_buff *skb)
475 {
476 	struct aoedev *d;
477 	struct aoe_hdr *hin;
478 	struct aoe_atahdr *ahin, *ahout;
479 	struct frame *f;
480 	struct buf *buf;
481 	struct sk_buff *sl;
482 	register long n;
483 	ulong flags;
484 	char ebuf[128];
485 	u16 aoemajor;
486 
487 	hin = (struct aoe_hdr *) skb->mac.raw;
488 	aoemajor = be16_to_cpu(hin->major);
489 	d = aoedev_by_aoeaddr(aoemajor, hin->minor);
490 	if (d == NULL) {
491 		snprintf(ebuf, sizeof ebuf, "aoecmd_ata_rsp: ata response "
492 			"for unknown device %d.%d\n",
493 			 aoemajor, hin->minor);
494 		aoechr_error(ebuf);
495 		return;
496 	}
497 
498 	spin_lock_irqsave(&d->lock, flags);
499 
500 	f = getframe(d, be32_to_cpu(hin->tag));
501 	if (f == NULL) {
502 		spin_unlock_irqrestore(&d->lock, flags);
503 		snprintf(ebuf, sizeof ebuf,
504 			"%15s e%d.%d    tag=%08x@%08lx\n",
505 			"unexpected rsp",
506 			be16_to_cpu(hin->major),
507 			hin->minor,
508 			be32_to_cpu(hin->tag),
509 			jiffies);
510 		aoechr_error(ebuf);
511 		return;
512 	}
513 
514 	calc_rttavg(d, tsince(f->tag));
515 
516 	ahin = (struct aoe_atahdr *) (hin+1);
517 	ahout = (struct aoe_atahdr *) (f->data + sizeof(struct aoe_hdr));
518 	buf = f->buf;
519 
520 	if (ahout->cmdstat == WIN_IDENTIFY)
521 		d->flags &= ~DEVFL_PAUSE;
522 	if (ahin->cmdstat & 0xa9) {	/* these bits cleared on success */
523 		printk(KERN_CRIT "aoe: aoecmd_ata_rsp: ata error cmd=%2.2Xh "
524 			"stat=%2.2Xh from e%ld.%ld\n",
525 			ahout->cmdstat, ahin->cmdstat,
526 			d->aoemajor, d->aoeminor);
527 		if (buf)
528 			buf->flags |= BUFFL_FAIL;
529 	} else {
530 		switch (ahout->cmdstat) {
531 		case WIN_READ:
532 		case WIN_READ_EXT:
533 			n = ahout->scnt << 9;
534 			if (skb->len - sizeof *hin - sizeof *ahin < n) {
535 				printk(KERN_CRIT "aoe: aoecmd_ata_rsp: runt "
536 					"ata data size in read.  skb->len=%d\n",
537 					skb->len);
538 				/* fail frame f?  just returning will rexmit. */
539 				spin_unlock_irqrestore(&d->lock, flags);
540 				return;
541 			}
542 			memcpy(f->bufaddr, ahin+1, n);
543 		case WIN_WRITE:
544 		case WIN_WRITE_EXT:
545 			break;
546 		case WIN_IDENTIFY:
547 			if (skb->len - sizeof *hin - sizeof *ahin < 512) {
548 				printk(KERN_INFO "aoe: aoecmd_ata_rsp: runt data size "
549 					"in ataid.  skb->len=%d\n", skb->len);
550 				spin_unlock_irqrestore(&d->lock, flags);
551 				return;
552 			}
553 			ataid_complete(d, (char *) (ahin+1));
554 			break;
555 		default:
556 			printk(KERN_INFO "aoe: aoecmd_ata_rsp: unrecognized "
557 			       "outbound ata command %2.2Xh for %d.%d\n",
558 			       ahout->cmdstat,
559 			       be16_to_cpu(hin->major),
560 			       hin->minor);
561 		}
562 	}
563 
564 	if (buf) {
565 		buf->nframesout -= 1;
566 		if (buf->nframesout == 0 && buf->resid == 0) {
567 			unsigned long duration = jiffies - buf->start_time;
568 			unsigned long n_sect = buf->bio->bi_size >> 9;
569 			struct gendisk *disk = d->gd;
570 			const int rw = bio_data_dir(buf->bio);
571 
572 			disk_stat_inc(disk, ios[rw]);
573 			disk_stat_add(disk, ticks[rw], duration);
574 			disk_stat_add(disk, sectors[rw], n_sect);
575 			disk_stat_add(disk, io_ticks, duration);
576 			n = (buf->flags & BUFFL_FAIL) ? -EIO : 0;
577 			bio_endio(buf->bio, buf->bio->bi_size, n);
578 			mempool_free(buf, d->bufpool);
579 		}
580 	}
581 
582 	f->buf = NULL;
583 	f->tag = FREETAG;
584 
585 	aoecmd_work(d);
586 	sl = d->sendq_hd;
587 	d->sendq_hd = d->sendq_tl = NULL;
588 
589 	spin_unlock_irqrestore(&d->lock, flags);
590 	aoenet_xmit(sl);
591 }
592 
593 void
594 aoecmd_cfg(ushort aoemajor, unsigned char aoeminor)
595 {
596 	struct sk_buff *sl;
597 
598 	sl = aoecmd_cfg_pkts(aoemajor, aoeminor, NULL);
599 
600 	aoenet_xmit(sl);
601 }
602 
603 /*
604  * Since we only call this in one place (and it only prepares one frame)
605  * we just return the skb.  Usually we'd chain it up to the aoedev sendq.
606  */
607 static struct sk_buff *
608 aoecmd_ata_id(struct aoedev *d)
609 {
610 	struct aoe_hdr *h;
611 	struct aoe_atahdr *ah;
612 	struct frame *f;
613 	struct sk_buff *skb;
614 
615 	f = getframe(d, FREETAG);
616 	if (f == NULL) {
617 		printk(KERN_CRIT "aoe: aoecmd_ata_id: can't get a frame.  "
618 			"This shouldn't happen.\n");
619 		return NULL;
620 	}
621 
622 	/* initialize the headers & frame */
623 	h = (struct aoe_hdr *) f->data;
624 	ah = (struct aoe_atahdr *) (h+1);
625 	f->ndata = sizeof *h + sizeof *ah;
626 	memset(h, 0, f->ndata);
627 	f->tag = aoehdr_atainit(d, h);
628 	f->waited = 0;
629 	f->writedatalen = 0;
630 
631 	/* set up ata header */
632 	ah->scnt = 1;
633 	ah->cmdstat = WIN_IDENTIFY;
634 	ah->lba3 = 0xa0;
635 
636 	skb = skb_prepare(d, f);
637 
638 	d->rttavg = MAXTIMER;
639 	d->timer.function = rexmit_timer;
640 
641 	return skb;
642 }
643 
644 void
645 aoecmd_cfg_rsp(struct sk_buff *skb)
646 {
647 	struct aoedev *d;
648 	struct aoe_hdr *h;
649 	struct aoe_cfghdr *ch;
650 	ulong flags, sysminor, aoemajor;
651 	u16 bufcnt;
652 	struct sk_buff *sl;
653 	enum { MAXFRAMES = 16 };
654 
655 	h = (struct aoe_hdr *) skb->mac.raw;
656 	ch = (struct aoe_cfghdr *) (h+1);
657 
658 	/*
659 	 * Enough people have their dip switches set backwards to
660 	 * warrant a loud message for this special case.
661 	 */
662 	aoemajor = be16_to_cpu(h->major);
663 	if (aoemajor == 0xfff) {
664 		printk(KERN_CRIT "aoe: aoecmd_cfg_rsp: Warning: shelf "
665 			"address is all ones.  Check shelf dip switches\n");
666 		return;
667 	}
668 
669 	sysminor = SYSMINOR(aoemajor, h->minor);
670 	if (sysminor * AOE_PARTITIONS + AOE_PARTITIONS > MINORMASK) {
671 		printk(KERN_INFO
672 			"aoe: e%ld.%d: minor number too large\n",
673 			aoemajor, (int) h->minor);
674 		return;
675 	}
676 
677 	bufcnt = be16_to_cpu(ch->bufcnt);
678 	if (bufcnt > MAXFRAMES)	/* keep it reasonable */
679 		bufcnt = MAXFRAMES;
680 
681 	d = aoedev_by_sysminor_m(sysminor, bufcnt);
682 	if (d == NULL) {
683 		printk(KERN_INFO "aoe: aoecmd_cfg_rsp: device sysminor_m failure\n");
684 		return;
685 	}
686 
687 	spin_lock_irqsave(&d->lock, flags);
688 
689 	/* permit device to migrate mac and network interface */
690 	d->ifp = skb->dev;
691 	memcpy(d->addr, h->src, sizeof d->addr);
692 
693 	/* don't change users' perspective */
694 	if (d->nopen && !(d->flags & DEVFL_PAUSE)) {
695 		spin_unlock_irqrestore(&d->lock, flags);
696 		return;
697 	}
698 	d->flags |= DEVFL_PAUSE;	/* force pause */
699 	d->fw_ver = be16_to_cpu(ch->fwver);
700 
701 	/* check for already outstanding ataid */
702 	sl = aoedev_isbusy(d) == 0 ? aoecmd_ata_id(d) : NULL;
703 
704 	spin_unlock_irqrestore(&d->lock, flags);
705 
706 	aoenet_xmit(sl);
707 }
708 
709