0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <asm/unaligned.h>
0012
0013 #include <linux/interrupt.h>
0014 #include <linux/pci.h>
0015
0016 #include <scsi/scsi_host.h>
0017 #include <uapi/scsi/cxlflash_ioctl.h>
0018
0019 #include "sislite.h"
0020 #include "common.h"
0021 #include "vlun.h"
0022 #include "superpipe.h"
0023
0024
0025
0026
0027
0028
0029
0030
0031 static struct llun_info *create_local(struct scsi_device *sdev, u8 *wwid)
0032 {
0033 struct cxlflash_cfg *cfg = shost_priv(sdev->host);
0034 struct device *dev = &cfg->dev->dev;
0035 struct llun_info *lli = NULL;
0036
0037 lli = kzalloc(sizeof(*lli), GFP_KERNEL);
0038 if (unlikely(!lli)) {
0039 dev_err(dev, "%s: could not allocate lli\n", __func__);
0040 goto out;
0041 }
0042
0043 lli->sdev = sdev;
0044 lli->host_no = sdev->host->host_no;
0045 lli->in_table = false;
0046
0047 memcpy(lli->wwid, wwid, DK_CXLFLASH_MANAGE_LUN_WWID_LEN);
0048 out:
0049 return lli;
0050 }
0051
0052
0053
0054
0055
0056
0057
0058
0059 static struct glun_info *create_global(struct scsi_device *sdev, u8 *wwid)
0060 {
0061 struct cxlflash_cfg *cfg = shost_priv(sdev->host);
0062 struct device *dev = &cfg->dev->dev;
0063 struct glun_info *gli = NULL;
0064
0065 gli = kzalloc(sizeof(*gli), GFP_KERNEL);
0066 if (unlikely(!gli)) {
0067 dev_err(dev, "%s: could not allocate gli\n", __func__);
0068 goto out;
0069 }
0070
0071 mutex_init(&gli->mutex);
0072 memcpy(gli->wwid, wwid, DK_CXLFLASH_MANAGE_LUN_WWID_LEN);
0073 out:
0074 return gli;
0075 }
0076
0077
0078
0079
0080
0081
0082
0083
0084 static struct llun_info *lookup_local(struct cxlflash_cfg *cfg, u8 *wwid)
0085 {
0086 struct llun_info *lli, *temp;
0087
0088 list_for_each_entry_safe(lli, temp, &cfg->lluns, list)
0089 if (!memcmp(lli->wwid, wwid, DK_CXLFLASH_MANAGE_LUN_WWID_LEN))
0090 return lli;
0091
0092 return NULL;
0093 }
0094
0095
0096
0097
0098
0099
0100
0101 static struct glun_info *lookup_global(u8 *wwid)
0102 {
0103 struct glun_info *gli, *temp;
0104
0105 list_for_each_entry_safe(gli, temp, &global.gluns, list)
0106 if (!memcmp(gli->wwid, wwid, DK_CXLFLASH_MANAGE_LUN_WWID_LEN))
0107 return gli;
0108
0109 return NULL;
0110 }
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132 static struct llun_info *find_and_create_lun(struct scsi_device *sdev, u8 *wwid)
0133 {
0134 struct cxlflash_cfg *cfg = shost_priv(sdev->host);
0135 struct device *dev = &cfg->dev->dev;
0136 struct llun_info *lli = NULL;
0137 struct glun_info *gli = NULL;
0138
0139 if (unlikely(!wwid))
0140 goto out;
0141
0142 lli = lookup_local(cfg, wwid);
0143 if (lli)
0144 goto out;
0145
0146 lli = create_local(sdev, wwid);
0147 if (unlikely(!lli))
0148 goto out;
0149
0150 gli = lookup_global(wwid);
0151 if (gli) {
0152 lli->parent = gli;
0153 list_add(&lli->list, &cfg->lluns);
0154 goto out;
0155 }
0156
0157 gli = create_global(sdev, wwid);
0158 if (unlikely(!gli)) {
0159 kfree(lli);
0160 lli = NULL;
0161 goto out;
0162 }
0163
0164 lli->parent = gli;
0165 list_add(&lli->list, &cfg->lluns);
0166
0167 list_add(&gli->list, &global.gluns);
0168
0169 out:
0170 dev_dbg(dev, "%s: returning lli=%p, gli=%p\n", __func__, lli, gli);
0171 return lli;
0172 }
0173
0174
0175
0176
0177
0178 void cxlflash_term_local_luns(struct cxlflash_cfg *cfg)
0179 {
0180 struct llun_info *lli, *temp;
0181
0182 mutex_lock(&global.mutex);
0183 list_for_each_entry_safe(lli, temp, &cfg->lluns, list) {
0184 list_del(&lli->list);
0185 kfree(lli);
0186 }
0187 mutex_unlock(&global.mutex);
0188 }
0189
0190
0191
0192
0193 void cxlflash_list_init(void)
0194 {
0195 INIT_LIST_HEAD(&global.gluns);
0196 mutex_init(&global.mutex);
0197 global.err_page = NULL;
0198 }
0199
0200
0201
0202
0203 void cxlflash_term_global_luns(void)
0204 {
0205 struct glun_info *gli, *temp;
0206
0207 mutex_lock(&global.mutex);
0208 list_for_each_entry_safe(gli, temp, &global.gluns, list) {
0209 list_del(&gli->list);
0210 cxlflash_ba_terminate(&gli->blka.ba_lun);
0211 kfree(gli);
0212 }
0213 mutex_unlock(&global.mutex);
0214 }
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225
0226
0227 int cxlflash_manage_lun(struct scsi_device *sdev,
0228 struct dk_cxlflash_manage_lun *manage)
0229 {
0230 struct cxlflash_cfg *cfg = shost_priv(sdev->host);
0231 struct device *dev = &cfg->dev->dev;
0232 struct llun_info *lli = NULL;
0233 int rc = 0;
0234 u64 flags = manage->hdr.flags;
0235 u32 chan = sdev->channel;
0236
0237 mutex_lock(&global.mutex);
0238 lli = find_and_create_lun(sdev, manage->wwid);
0239 dev_dbg(dev, "%s: WWID=%016llx%016llx, flags=%016llx lli=%p\n",
0240 __func__, get_unaligned_be64(&manage->wwid[0]),
0241 get_unaligned_be64(&manage->wwid[8]), manage->hdr.flags, lli);
0242 if (unlikely(!lli)) {
0243 rc = -ENOMEM;
0244 goto out;
0245 }
0246
0247 if (flags & DK_CXLFLASH_MANAGE_LUN_ENABLE_SUPERPIPE) {
0248
0249
0250
0251
0252
0253 lli->port_sel |= CHAN2PORTMASK(chan);
0254 lli->lun_id[chan] = lun_to_lunid(sdev->lun);
0255 sdev->hostdata = lli;
0256 } else if (flags & DK_CXLFLASH_MANAGE_LUN_DISABLE_SUPERPIPE) {
0257 if (lli->parent->mode != MODE_NONE)
0258 rc = -EBUSY;
0259 else {
0260
0261
0262
0263
0264 sdev->hostdata = NULL;
0265 lli->port_sel &= ~CHAN2PORTMASK(chan);
0266 if (lli->port_sel == 0U)
0267 lli->in_table = false;
0268 }
0269 }
0270
0271 dev_dbg(dev, "%s: port_sel=%08x chan=%u lun_id=%016llx\n",
0272 __func__, lli->port_sel, chan, lli->lun_id[chan]);
0273
0274 out:
0275 mutex_unlock(&global.mutex);
0276 dev_dbg(dev, "%s: returning rc=%d\n", __func__, rc);
0277 return rc;
0278 }