Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /* Copyright (c) 2013 Coraid, Inc.  See COPYING for GPL terms. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * aoeblk.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * block device routines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/hdreg.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/blk-mq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/backing-dev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/ioctl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/ratelimit.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/genhd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/moduleparam.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/debugfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <scsi/sg.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include "aoe.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) static DEFINE_MUTEX(aoeblk_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) static struct kmem_cache *buf_pool_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) static struct dentry *aoe_debugfs_dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) /* GPFS needs a larger value than the default. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) static int aoe_maxsectors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) module_param(aoe_maxsectors, int, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) MODULE_PARM_DESC(aoe_maxsectors,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	"When nonzero, set the maximum number of sectors per I/O request");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) static ssize_t aoedisk_show_state(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 				  struct device_attribute *attr, char *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	struct gendisk *disk = dev_to_disk(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	struct aoedev *d = disk->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	return snprintf(page, PAGE_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 			"%s%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 			(d->flags & DEVFL_UP) ? "up" : "down",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 			(d->flags & DEVFL_KICKME) ? ",kickme" :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 			(d->nopen && !(d->flags & DEVFL_UP)) ? ",closewait" : "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	/* I'd rather see nopen exported so we can ditch closewait */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) static ssize_t aoedisk_show_mac(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 				struct device_attribute *attr, char *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	struct gendisk *disk = dev_to_disk(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	struct aoedev *d = disk->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	struct aoetgt *t = d->targets[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	if (t == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 		return snprintf(page, PAGE_SIZE, "none\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	return snprintf(page, PAGE_SIZE, "%pm\n", t->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) static ssize_t aoedisk_show_netif(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 				  struct device_attribute *attr, char *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	struct gendisk *disk = dev_to_disk(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	struct aoedev *d = disk->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	struct net_device *nds[8], **nd, **nnd, **ne;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	struct aoetgt **t, **te;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	struct aoeif *ifp, *e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	char *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	memset(nds, 0, sizeof nds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	nd = nds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	ne = nd + ARRAY_SIZE(nds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	t = d->targets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	te = t + d->ntargets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	for (; t < te && *t; t++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 		ifp = (*t)->ifs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 		e = ifp + NAOEIFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 		for (; ifp < e && ifp->nd; ifp++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 			for (nnd = nds; nnd < nd; nnd++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 				if (*nnd == ifp->nd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 			if (nnd == nd && nd != ne)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 				*nd++ = ifp->nd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	ne = nd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	nd = nds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	if (*nd == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 		return snprintf(page, PAGE_SIZE, "none\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	for (p = page; nd < ne; nd++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 		p += scnprintf(p, PAGE_SIZE - (p-page), "%s%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 			p == page ? "" : ",", (*nd)->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	p += scnprintf(p, PAGE_SIZE - (p-page), "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	return p-page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) /* firmware version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) static ssize_t aoedisk_show_fwver(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 				  struct device_attribute *attr, char *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	struct gendisk *disk = dev_to_disk(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	struct aoedev *d = disk->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	return snprintf(page, PAGE_SIZE, "0x%04x\n", (unsigned int) d->fw_ver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) static ssize_t aoedisk_show_payload(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 				    struct device_attribute *attr, char *page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	struct gendisk *disk = dev_to_disk(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	struct aoedev *d = disk->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	return snprintf(page, PAGE_SIZE, "%lu\n", d->maxbcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) static int aoedisk_debugfs_show(struct seq_file *s, void *ignored)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	struct aoedev *d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	struct aoetgt **t, **te;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	struct aoeif *ifp, *ife;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	char c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	d = s->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	seq_printf(s, "rttavg: %d rttdev: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 		d->rttavg >> RTTSCALE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 		d->rttdev >> RTTDSCALE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	seq_printf(s, "nskbpool: %d\n", skb_queue_len(&d->skbpool));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	seq_printf(s, "kicked: %ld\n", d->kicked);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	seq_printf(s, "maxbcnt: %ld\n", d->maxbcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	seq_printf(s, "ref: %ld\n", d->ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	spin_lock_irqsave(&d->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	t = d->targets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	te = t + d->ntargets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	for (; t < te && *t; t++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 		c = '\t';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 		seq_printf(s, "falloc: %ld\n", (*t)->falloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 		seq_printf(s, "ffree: %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 			list_empty(&(*t)->ffree) ? NULL : (*t)->ffree.next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 		seq_printf(s, "%pm:%d:%d:%d\n", (*t)->addr, (*t)->nout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 			(*t)->maxout, (*t)->nframes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 		seq_printf(s, "\tssthresh:%d\n", (*t)->ssthresh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 		seq_printf(s, "\ttaint:%d\n", (*t)->taint);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 		seq_printf(s, "\tr:%d\n", (*t)->rpkts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 		seq_printf(s, "\tw:%d\n", (*t)->wpkts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 		ifp = (*t)->ifs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 		ife = ifp + ARRAY_SIZE((*t)->ifs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 		for (; ifp->nd && ifp < ife; ifp++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 			seq_printf(s, "%c%s", c, ifp->nd->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 			c = ',';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 		seq_puts(s, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	spin_unlock_irqrestore(&d->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) static int aoe_debugfs_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	return single_open(file, aoedisk_debugfs_show, inode->i_private);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) static DEVICE_ATTR(state, 0444, aoedisk_show_state, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) static DEVICE_ATTR(mac, 0444, aoedisk_show_mac, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) static DEVICE_ATTR(netif, 0444, aoedisk_show_netif, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) static struct device_attribute dev_attr_firmware_version = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	.attr = { .name = "firmware-version", .mode = 0444 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	.show = aoedisk_show_fwver,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) static DEVICE_ATTR(payload, 0444, aoedisk_show_payload, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) static struct attribute *aoe_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	&dev_attr_state.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	&dev_attr_mac.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	&dev_attr_netif.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	&dev_attr_firmware_version.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	&dev_attr_payload.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) static const struct attribute_group aoe_attr_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	.attrs = aoe_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) static const struct attribute_group *aoe_attr_groups[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	&aoe_attr_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) static const struct file_operations aoe_debugfs_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	.open = aoe_debugfs_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	.read = seq_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	.llseek = seq_lseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	.release = single_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) aoedisk_add_debugfs(struct aoedev *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	char *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	if (aoe_debugfs_dir == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	p = strchr(d->gd->disk_name, '/');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	if (p == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 		p = d->gd->disk_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 		p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	BUG_ON(*p == '\0');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	d->debugfs = debugfs_create_file(p, 0444, aoe_debugfs_dir, d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 					 &aoe_debugfs_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) aoedisk_rm_debugfs(struct aoedev *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	debugfs_remove(d->debugfs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	d->debugfs = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) aoeblk_open(struct block_device *bdev, fmode_t mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	struct aoedev *d = bdev->bd_disk->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	ulong flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	if (!virt_addr_valid(d)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 		pr_crit("aoe: invalid device pointer in %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 			__func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 		WARN_ON(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	if (!(d->flags & DEVFL_UP) || d->flags & DEVFL_TKILL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	mutex_lock(&aoeblk_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	spin_lock_irqsave(&d->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	if (d->flags & DEVFL_UP && !(d->flags & DEVFL_TKILL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 		d->nopen++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 		spin_unlock_irqrestore(&d->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 		mutex_unlock(&aoeblk_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	spin_unlock_irqrestore(&d->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	mutex_unlock(&aoeblk_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) aoeblk_release(struct gendisk *disk, fmode_t mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	struct aoedev *d = disk->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	ulong flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	spin_lock_irqsave(&d->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	if (--d->nopen == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 		spin_unlock_irqrestore(&d->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 		aoecmd_cfg(d->aoemajor, d->aoeminor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	spin_unlock_irqrestore(&d->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) static blk_status_t aoeblk_queue_rq(struct blk_mq_hw_ctx *hctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 				    const struct blk_mq_queue_data *bd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	struct aoedev *d = hctx->queue->queuedata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	spin_lock_irq(&d->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	if ((d->flags & DEVFL_UP) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 		pr_info_ratelimited("aoe: device %ld.%d is not up\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 			d->aoemajor, d->aoeminor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 		spin_unlock_irq(&d->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 		blk_mq_start_request(bd->rq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 		return BLK_STS_IOERR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	list_add_tail(&bd->rq->queuelist, &d->rq_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	aoecmd_work(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	spin_unlock_irq(&d->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	return BLK_STS_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) aoeblk_getgeo(struct block_device *bdev, struct hd_geometry *geo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	struct aoedev *d = bdev->bd_disk->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	if ((d->flags & DEVFL_UP) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 		printk(KERN_ERR "aoe: disk not up\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	geo->cylinders = d->geo.cylinders;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	geo->heads = d->geo.heads;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	geo->sectors = d->geo.sectors;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) aoeblk_ioctl(struct block_device *bdev, fmode_t mode, uint cmd, ulong arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	struct aoedev *d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	if (!arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	d = bdev->bd_disk->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	if ((d->flags & DEVFL_UP) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 		pr_err("aoe: disk not up\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	if (cmd == HDIO_GET_IDENTITY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 		if (!copy_to_user((void __user *) arg, &d->ident,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 			sizeof(d->ident)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	/* udev calls scsi_id, which uses SG_IO, resulting in noise */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	if (cmd != SG_IO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 		pr_info("aoe: unknown ioctl 0x%x\n", cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	return -ENOTTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) static const struct block_device_operations aoe_bdops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	.open = aoeblk_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	.release = aoeblk_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	.ioctl = aoeblk_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	.compat_ioctl = blkdev_compat_ptr_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	.getgeo = aoeblk_getgeo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	.owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) static const struct blk_mq_ops aoeblk_mq_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 	.queue_rq	= aoeblk_queue_rq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) /* alloc_disk and add_disk can sleep */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) aoeblk_gdalloc(void *vp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	struct aoedev *d = vp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	struct gendisk *gd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	mempool_t *mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 	struct request_queue *q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	struct blk_mq_tag_set *set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	ulong flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	int late = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	spin_lock_irqsave(&d->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	if (d->flags & DEVFL_GDALLOC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	&& !(d->flags & DEVFL_TKILL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 	&& !(d->flags & DEVFL_GD_NOW))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 		d->flags |= DEVFL_GD_NOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 		late = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 	spin_unlock_irqrestore(&d->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	if (late)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	gd = alloc_disk(AOE_PARTITIONS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	if (gd == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 		pr_err("aoe: cannot allocate disk structure for %ld.%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 			d->aoemajor, d->aoeminor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	mp = mempool_create(MIN_BUFS, mempool_alloc_slab, mempool_free_slab,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 		buf_pool_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 	if (mp == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 		printk(KERN_ERR "aoe: cannot allocate bufpool for %ld.%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 			d->aoemajor, d->aoeminor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 		goto err_disk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 	set = &d->tag_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 	set->ops = &aoeblk_mq_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 	set->cmd_size = sizeof(struct aoe_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	set->nr_hw_queues = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 	set->queue_depth = 128;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 	set->numa_node = NUMA_NO_NODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	set->flags = BLK_MQ_F_SHOULD_MERGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	err = blk_mq_alloc_tag_set(set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 		pr_err("aoe: cannot allocate tag set for %ld.%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 			d->aoemajor, d->aoeminor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 		goto err_mempool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 	q = blk_mq_init_queue(set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 	if (IS_ERR(q)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 		pr_err("aoe: cannot allocate block queue for %ld.%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 			d->aoemajor, d->aoeminor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 		blk_mq_free_tag_set(set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 		goto err_mempool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 	spin_lock_irqsave(&d->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	WARN_ON(!(d->flags & DEVFL_GD_NOW));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 	WARN_ON(!(d->flags & DEVFL_GDALLOC));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 	WARN_ON(d->flags & DEVFL_TKILL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 	WARN_ON(d->gd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 	WARN_ON(d->flags & DEVFL_UP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 	blk_queue_max_hw_sectors(q, BLK_DEF_MAX_SECTORS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	blk_queue_io_opt(q, SZ_2M);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 	d->bufpool = mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 	d->blkq = gd->queue = q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 	q->queuedata = d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 	d->gd = gd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 	if (aoe_maxsectors)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 		blk_queue_max_hw_sectors(q, aoe_maxsectors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 	gd->major = AOE_MAJOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 	gd->first_minor = d->sysminor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 	gd->fops = &aoe_bdops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 	gd->private_data = d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 	set_capacity(gd, d->ssize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 	snprintf(gd->disk_name, sizeof gd->disk_name, "etherd/e%ld.%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 		d->aoemajor, d->aoeminor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 	d->flags &= ~DEVFL_GDALLOC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	d->flags |= DEVFL_UP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 	spin_unlock_irqrestore(&d->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 	device_add_disk(NULL, gd, aoe_attr_groups);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 	aoedisk_add_debugfs(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 	spin_lock_irqsave(&d->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 	WARN_ON(!(d->flags & DEVFL_GD_NOW));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 	d->flags &= ~DEVFL_GD_NOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	spin_unlock_irqrestore(&d->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) err_mempool:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 	mempool_destroy(mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) err_disk:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 	put_disk(gd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 	spin_lock_irqsave(&d->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 	d->flags &= ~DEVFL_GD_NOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 	schedule_work(&d->work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 	spin_unlock_irqrestore(&d->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) aoeblk_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 	debugfs_remove_recursive(aoe_debugfs_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 	aoe_debugfs_dir = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 	kmem_cache_destroy(buf_pool_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) int __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) aoeblk_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 	buf_pool_cache = kmem_cache_create("aoe_bufs",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 					   sizeof(struct buf),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 					   0, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 	if (buf_pool_cache == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 	aoe_debugfs_dir = debugfs_create_dir("aoe", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)