0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #define KMSG_COMPONENT "dasd-eckd"
0011
0012 #include <linux/init.h>
0013 #include <linux/fs.h>
0014 #include <linux/kernel.h>
0015 #include <linux/miscdevice.h>
0016 #include <linux/module.h>
0017 #include <linux/moduleparam.h>
0018 #include <linux/device.h>
0019 #include <linux/poll.h>
0020 #include <linux/mutex.h>
0021 #include <linux/err.h>
0022 #include <linux/slab.h>
0023
0024 #include <linux/uaccess.h>
0025 #include <linux/atomic.h>
0026 #include <asm/ebcdic.h>
0027
0028 #include "dasd_int.h"
0029 #include "dasd_eckd.h"
0030
0031 #ifdef PRINTK_HEADER
0032 #undef PRINTK_HEADER
0033 #endif
0034 #define PRINTK_HEADER "dasd(eer):"
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083 static int eer_pages = 5;
0084 module_param(eer_pages, int, S_IRUGO|S_IWUSR);
0085
0086 struct eerbuffer {
0087 struct list_head list;
0088 char **buffer;
0089 int buffersize;
0090 int buffer_page_count;
0091 int head;
0092 int tail;
0093 int residual;
0094 };
0095
0096 static LIST_HEAD(bufferlist);
0097 static DEFINE_SPINLOCK(bufferlock);
0098 static DECLARE_WAIT_QUEUE_HEAD(dasd_eer_read_wait_queue);
0099
0100
0101
0102
0103
0104 static int dasd_eer_get_free_bytes(struct eerbuffer *eerb)
0105 {
0106 if (eerb->head < eerb->tail)
0107 return eerb->tail - eerb->head - 1;
0108 return eerb->buffersize - eerb->head + eerb->tail -1;
0109 }
0110
0111
0112
0113
0114
0115 static int dasd_eer_get_filled_bytes(struct eerbuffer *eerb)
0116 {
0117
0118 if (eerb->head >= eerb->tail)
0119 return eerb->head - eerb->tail;
0120 return eerb->buffersize - eerb->tail + eerb->head;
0121 }
0122
0123
0124
0125
0126
0127
0128
0129 static void dasd_eer_write_buffer(struct eerbuffer *eerb,
0130 char *data, int count)
0131 {
0132
0133 unsigned long headindex,localhead;
0134 unsigned long rest, len;
0135 char *nextdata;
0136
0137 nextdata = data;
0138 rest = count;
0139 while (rest > 0) {
0140 headindex = eerb->head / PAGE_SIZE;
0141 localhead = eerb->head % PAGE_SIZE;
0142 len = min(rest, PAGE_SIZE - localhead);
0143 memcpy(eerb->buffer[headindex]+localhead, nextdata, len);
0144 nextdata += len;
0145 rest -= len;
0146 eerb->head += len;
0147 if (eerb->head == eerb->buffersize)
0148 eerb->head = 0;
0149 BUG_ON(eerb->head > eerb->buffersize);
0150 }
0151 }
0152
0153
0154
0155
0156 static int dasd_eer_read_buffer(struct eerbuffer *eerb, char *data, int count)
0157 {
0158
0159 unsigned long tailindex,localtail;
0160 unsigned long rest, len, finalcount;
0161 char *nextdata;
0162
0163 finalcount = min(count, dasd_eer_get_filled_bytes(eerb));
0164 nextdata = data;
0165 rest = finalcount;
0166 while (rest > 0) {
0167 tailindex = eerb->tail / PAGE_SIZE;
0168 localtail = eerb->tail % PAGE_SIZE;
0169 len = min(rest, PAGE_SIZE - localtail);
0170 memcpy(nextdata, eerb->buffer[tailindex] + localtail, len);
0171 nextdata += len;
0172 rest -= len;
0173 eerb->tail += len;
0174 if (eerb->tail == eerb->buffersize)
0175 eerb->tail = 0;
0176 BUG_ON(eerb->tail > eerb->buffersize);
0177 }
0178 return finalcount;
0179 }
0180
0181
0182
0183
0184
0185
0186
0187
0188 static int dasd_eer_start_record(struct eerbuffer *eerb, int count)
0189 {
0190 int tailcount;
0191
0192 if (count + sizeof(count) > eerb->buffersize)
0193 return -ENOMEM;
0194 while (dasd_eer_get_free_bytes(eerb) < count + sizeof(count)) {
0195 if (eerb->residual > 0) {
0196 eerb->tail += eerb->residual;
0197 if (eerb->tail >= eerb->buffersize)
0198 eerb->tail -= eerb->buffersize;
0199 eerb->residual = -1;
0200 }
0201 dasd_eer_read_buffer(eerb, (char *) &tailcount,
0202 sizeof(tailcount));
0203 eerb->tail += tailcount;
0204 if (eerb->tail >= eerb->buffersize)
0205 eerb->tail -= eerb->buffersize;
0206 }
0207 dasd_eer_write_buffer(eerb, (char*) &count, sizeof(count));
0208
0209 return 0;
0210 };
0211
0212
0213
0214
0215 static void dasd_eer_free_buffer_pages(char **buf, int no_pages)
0216 {
0217 int i;
0218
0219 for (i = 0; i < no_pages; i++)
0220 free_page((unsigned long) buf[i]);
0221 }
0222
0223
0224
0225
0226 static int dasd_eer_allocate_buffer_pages(char **buf, int no_pages)
0227 {
0228 int i;
0229
0230 for (i = 0; i < no_pages; i++) {
0231 buf[i] = (char *) get_zeroed_page(GFP_KERNEL);
0232 if (!buf[i]) {
0233 dasd_eer_free_buffer_pages(buf, i);
0234 return -ENOMEM;
0235 }
0236 }
0237 return 0;
0238 }
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275 #define SNSS_DATA_SIZE 44
0276
0277 #define DASD_EER_BUSID_SIZE 10
0278 struct dasd_eer_header {
0279 __u32 total_size;
0280 __u32 trigger;
0281 __u64 tv_sec;
0282 __u64 tv_usec;
0283 char busid[DASD_EER_BUSID_SIZE];
0284 } __attribute__ ((packed));
0285
0286
0287
0288
0289
0290
0291
0292
0293 static void dasd_eer_write_standard_trigger(struct dasd_device *device,
0294 struct dasd_ccw_req *cqr,
0295 int trigger)
0296 {
0297 struct dasd_ccw_req *temp_cqr;
0298 int data_size;
0299 struct timespec64 ts;
0300 struct dasd_eer_header header;
0301 unsigned long flags;
0302 struct eerbuffer *eerb;
0303 char *sense;
0304
0305
0306 data_size = 0;
0307 for (temp_cqr = cqr; temp_cqr; temp_cqr = temp_cqr->refers)
0308 if (dasd_get_sense(&temp_cqr->irb))
0309 data_size += 32;
0310
0311 header.total_size = sizeof(header) + data_size + 4;
0312 header.trigger = trigger;
0313 ktime_get_real_ts64(&ts);
0314 header.tv_sec = ts.tv_sec;
0315 header.tv_usec = ts.tv_nsec / NSEC_PER_USEC;
0316 strlcpy(header.busid, dev_name(&device->cdev->dev),
0317 DASD_EER_BUSID_SIZE);
0318
0319 spin_lock_irqsave(&bufferlock, flags);
0320 list_for_each_entry(eerb, &bufferlist, list) {
0321 dasd_eer_start_record(eerb, header.total_size);
0322 dasd_eer_write_buffer(eerb, (char *) &header, sizeof(header));
0323 for (temp_cqr = cqr; temp_cqr; temp_cqr = temp_cqr->refers) {
0324 sense = dasd_get_sense(&temp_cqr->irb);
0325 if (sense)
0326 dasd_eer_write_buffer(eerb, sense, 32);
0327 }
0328 dasd_eer_write_buffer(eerb, "EOR", 4);
0329 }
0330 spin_unlock_irqrestore(&bufferlock, flags);
0331 wake_up_interruptible(&dasd_eer_read_wait_queue);
0332 }
0333
0334
0335
0336
0337 static void dasd_eer_write_snss_trigger(struct dasd_device *device,
0338 struct dasd_ccw_req *cqr,
0339 int trigger)
0340 {
0341 int data_size;
0342 int snss_rc;
0343 struct timespec64 ts;
0344 struct dasd_eer_header header;
0345 unsigned long flags;
0346 struct eerbuffer *eerb;
0347
0348 snss_rc = (cqr->status == DASD_CQR_DONE) ? 0 : -EIO;
0349 if (snss_rc)
0350 data_size = 0;
0351 else
0352 data_size = SNSS_DATA_SIZE;
0353
0354 header.total_size = sizeof(header) + data_size + 4;
0355 header.trigger = DASD_EER_STATECHANGE;
0356 ktime_get_real_ts64(&ts);
0357 header.tv_sec = ts.tv_sec;
0358 header.tv_usec = ts.tv_nsec / NSEC_PER_USEC;
0359 strlcpy(header.busid, dev_name(&device->cdev->dev),
0360 DASD_EER_BUSID_SIZE);
0361
0362 spin_lock_irqsave(&bufferlock, flags);
0363 list_for_each_entry(eerb, &bufferlist, list) {
0364 dasd_eer_start_record(eerb, header.total_size);
0365 dasd_eer_write_buffer(eerb, (char *) &header , sizeof(header));
0366 if (!snss_rc)
0367 dasd_eer_write_buffer(eerb, cqr->data, SNSS_DATA_SIZE);
0368 dasd_eer_write_buffer(eerb, "EOR", 4);
0369 }
0370 spin_unlock_irqrestore(&bufferlock, flags);
0371 wake_up_interruptible(&dasd_eer_read_wait_queue);
0372 }
0373
0374
0375
0376
0377
0378 void dasd_eer_write(struct dasd_device *device, struct dasd_ccw_req *cqr,
0379 unsigned int id)
0380 {
0381 if (!device->eer_cqr)
0382 return;
0383 switch (id) {
0384 case DASD_EER_FATALERROR:
0385 case DASD_EER_PPRCSUSPEND:
0386 dasd_eer_write_standard_trigger(device, cqr, id);
0387 break;
0388 case DASD_EER_NOPATH:
0389 case DASD_EER_NOSPC:
0390 dasd_eer_write_standard_trigger(device, NULL, id);
0391 break;
0392 case DASD_EER_STATECHANGE:
0393 dasd_eer_write_snss_trigger(device, cqr, id);
0394 break;
0395 default:
0396 dasd_eer_write_standard_trigger(device, NULL, id);
0397 break;
0398 }
0399 }
0400 EXPORT_SYMBOL(dasd_eer_write);
0401
0402
0403
0404
0405
0406 void dasd_eer_snss(struct dasd_device *device)
0407 {
0408 struct dasd_ccw_req *cqr;
0409
0410 cqr = device->eer_cqr;
0411 if (!cqr)
0412 return;
0413 if (test_and_set_bit(DASD_FLAG_EER_IN_USE, &device->flags)) {
0414
0415 set_bit(DASD_FLAG_EER_SNSS, &device->flags);
0416 return;
0417 }
0418
0419 clear_bit(DASD_FLAG_EER_SNSS, &device->flags);
0420 cqr->status = DASD_CQR_QUEUED;
0421 list_add(&cqr->devlist, &device->ccw_queue);
0422 dasd_schedule_device_bh(device);
0423 }
0424
0425
0426
0427
0428 static void dasd_eer_snss_cb(struct dasd_ccw_req *cqr, void *data)
0429 {
0430 struct dasd_device *device = cqr->startdev;
0431 unsigned long flags;
0432
0433 dasd_eer_write(device, cqr, DASD_EER_STATECHANGE);
0434 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
0435 if (device->eer_cqr == cqr) {
0436 clear_bit(DASD_FLAG_EER_IN_USE, &device->flags);
0437 if (test_bit(DASD_FLAG_EER_SNSS, &device->flags))
0438
0439 dasd_eer_snss(device);
0440 cqr = NULL;
0441 }
0442 spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
0443 if (cqr)
0444
0445
0446
0447
0448
0449
0450
0451 dasd_sfree_request(cqr, device);
0452 }
0453
0454
0455
0456
0457 int dasd_eer_enable(struct dasd_device *device)
0458 {
0459 struct dasd_ccw_req *cqr = NULL;
0460 unsigned long flags;
0461 struct ccw1 *ccw;
0462 int rc = 0;
0463
0464 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
0465 if (device->eer_cqr)
0466 goto out;
0467 else if (!device->discipline ||
0468 strcmp(device->discipline->name, "ECKD"))
0469 rc = -EMEDIUMTYPE;
0470 else if (test_bit(DASD_FLAG_OFFLINE, &device->flags))
0471 rc = -EBUSY;
0472
0473 if (rc)
0474 goto out;
0475
0476 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 1 ,
0477 SNSS_DATA_SIZE, device, NULL);
0478 if (IS_ERR(cqr)) {
0479 rc = -ENOMEM;
0480 cqr = NULL;
0481 goto out;
0482 }
0483
0484 cqr->startdev = device;
0485 cqr->retries = 255;
0486 cqr->expires = 10 * HZ;
0487 clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
0488 set_bit(DASD_CQR_ALLOW_SLOCK, &cqr->flags);
0489
0490 ccw = cqr->cpaddr;
0491 ccw->cmd_code = DASD_ECKD_CCW_SNSS;
0492 ccw->count = SNSS_DATA_SIZE;
0493 ccw->flags = 0;
0494 ccw->cda = (__u32)(addr_t) cqr->data;
0495
0496 cqr->buildclk = get_tod_clock();
0497 cqr->status = DASD_CQR_FILLED;
0498 cqr->callback = dasd_eer_snss_cb;
0499
0500 if (!device->eer_cqr) {
0501 device->eer_cqr = cqr;
0502 cqr = NULL;
0503 }
0504
0505 out:
0506 spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
0507
0508 if (cqr)
0509 dasd_sfree_request(cqr, device);
0510
0511 return rc;
0512 }
0513
0514
0515
0516
0517 void dasd_eer_disable(struct dasd_device *device)
0518 {
0519 struct dasd_ccw_req *cqr;
0520 unsigned long flags;
0521 int in_use;
0522
0523 if (!device->eer_cqr)
0524 return;
0525 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
0526 cqr = device->eer_cqr;
0527 device->eer_cqr = NULL;
0528 clear_bit(DASD_FLAG_EER_SNSS, &device->flags);
0529 in_use = test_and_clear_bit(DASD_FLAG_EER_IN_USE, &device->flags);
0530 spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
0531 if (cqr && !in_use)
0532 dasd_sfree_request(cqr, device);
0533 }
0534
0535
0536
0537
0538
0539
0540
0541
0542
0543
0544 static char readbuffer[PAGE_SIZE];
0545 static DEFINE_MUTEX(readbuffer_mutex);
0546
0547 static int dasd_eer_open(struct inode *inp, struct file *filp)
0548 {
0549 struct eerbuffer *eerb;
0550 unsigned long flags;
0551
0552 eerb = kzalloc(sizeof(struct eerbuffer), GFP_KERNEL);
0553 if (!eerb)
0554 return -ENOMEM;
0555 eerb->buffer_page_count = eer_pages;
0556 if (eerb->buffer_page_count < 1 ||
0557 eerb->buffer_page_count > INT_MAX / PAGE_SIZE) {
0558 kfree(eerb);
0559 DBF_EVENT(DBF_WARNING, "can't open device since module "
0560 "parameter eer_pages is smaller than 1 or"
0561 " bigger than %d", (int)(INT_MAX / PAGE_SIZE));
0562 return -EINVAL;
0563 }
0564 eerb->buffersize = eerb->buffer_page_count * PAGE_SIZE;
0565 eerb->buffer = kmalloc_array(eerb->buffer_page_count, sizeof(char *),
0566 GFP_KERNEL);
0567 if (!eerb->buffer) {
0568 kfree(eerb);
0569 return -ENOMEM;
0570 }
0571 if (dasd_eer_allocate_buffer_pages(eerb->buffer,
0572 eerb->buffer_page_count)) {
0573 kfree(eerb->buffer);
0574 kfree(eerb);
0575 return -ENOMEM;
0576 }
0577 filp->private_data = eerb;
0578 spin_lock_irqsave(&bufferlock, flags);
0579 list_add(&eerb->list, &bufferlist);
0580 spin_unlock_irqrestore(&bufferlock, flags);
0581
0582 return nonseekable_open(inp,filp);
0583 }
0584
0585 static int dasd_eer_close(struct inode *inp, struct file *filp)
0586 {
0587 struct eerbuffer *eerb;
0588 unsigned long flags;
0589
0590 eerb = (struct eerbuffer *) filp->private_data;
0591 spin_lock_irqsave(&bufferlock, flags);
0592 list_del(&eerb->list);
0593 spin_unlock_irqrestore(&bufferlock, flags);
0594 dasd_eer_free_buffer_pages(eerb->buffer, eerb->buffer_page_count);
0595 kfree(eerb->buffer);
0596 kfree(eerb);
0597
0598 return 0;
0599 }
0600
0601 static ssize_t dasd_eer_read(struct file *filp, char __user *buf,
0602 size_t count, loff_t *ppos)
0603 {
0604 int tc,rc;
0605 int tailcount,effective_count;
0606 unsigned long flags;
0607 struct eerbuffer *eerb;
0608
0609 eerb = (struct eerbuffer *) filp->private_data;
0610 if (mutex_lock_interruptible(&readbuffer_mutex))
0611 return -ERESTARTSYS;
0612
0613 spin_lock_irqsave(&bufferlock, flags);
0614
0615 if (eerb->residual < 0) {
0616
0617 eerb->residual = 0;
0618 spin_unlock_irqrestore(&bufferlock, flags);
0619 mutex_unlock(&readbuffer_mutex);
0620 return -EIO;
0621 } else if (eerb->residual > 0) {
0622
0623 effective_count = min(eerb->residual, (int) count);
0624 eerb->residual -= effective_count;
0625 } else {
0626 tc = 0;
0627 while (!tc) {
0628 tc = dasd_eer_read_buffer(eerb, (char *) &tailcount,
0629 sizeof(tailcount));
0630 if (!tc) {
0631
0632 spin_unlock_irqrestore(&bufferlock, flags);
0633 mutex_unlock(&readbuffer_mutex);
0634 if (filp->f_flags & O_NONBLOCK)
0635 return -EAGAIN;
0636 rc = wait_event_interruptible(
0637 dasd_eer_read_wait_queue,
0638 eerb->head != eerb->tail);
0639 if (rc)
0640 return rc;
0641 if (mutex_lock_interruptible(&readbuffer_mutex))
0642 return -ERESTARTSYS;
0643 spin_lock_irqsave(&bufferlock, flags);
0644 }
0645 }
0646 WARN_ON(tc != sizeof(tailcount));
0647 effective_count = min(tailcount,(int)count);
0648 eerb->residual = tailcount - effective_count;
0649 }
0650
0651 tc = dasd_eer_read_buffer(eerb, readbuffer, effective_count);
0652 WARN_ON(tc != effective_count);
0653
0654 spin_unlock_irqrestore(&bufferlock, flags);
0655
0656 if (copy_to_user(buf, readbuffer, effective_count)) {
0657 mutex_unlock(&readbuffer_mutex);
0658 return -EFAULT;
0659 }
0660
0661 mutex_unlock(&readbuffer_mutex);
0662 return effective_count;
0663 }
0664
0665 static __poll_t dasd_eer_poll(struct file *filp, poll_table *ptable)
0666 {
0667 __poll_t mask;
0668 unsigned long flags;
0669 struct eerbuffer *eerb;
0670
0671 eerb = (struct eerbuffer *) filp->private_data;
0672 poll_wait(filp, &dasd_eer_read_wait_queue, ptable);
0673 spin_lock_irqsave(&bufferlock, flags);
0674 if (eerb->head != eerb->tail)
0675 mask = EPOLLIN | EPOLLRDNORM ;
0676 else
0677 mask = 0;
0678 spin_unlock_irqrestore(&bufferlock, flags);
0679 return mask;
0680 }
0681
0682 static const struct file_operations dasd_eer_fops = {
0683 .open = &dasd_eer_open,
0684 .release = &dasd_eer_close,
0685 .read = &dasd_eer_read,
0686 .poll = &dasd_eer_poll,
0687 .owner = THIS_MODULE,
0688 .llseek = noop_llseek,
0689 };
0690
0691 static struct miscdevice *dasd_eer_dev = NULL;
0692
0693 int __init dasd_eer_init(void)
0694 {
0695 int rc;
0696
0697 dasd_eer_dev = kzalloc(sizeof(*dasd_eer_dev), GFP_KERNEL);
0698 if (!dasd_eer_dev)
0699 return -ENOMEM;
0700
0701 dasd_eer_dev->minor = MISC_DYNAMIC_MINOR;
0702 dasd_eer_dev->name = "dasd_eer";
0703 dasd_eer_dev->fops = &dasd_eer_fops;
0704
0705 rc = misc_register(dasd_eer_dev);
0706 if (rc) {
0707 kfree(dasd_eer_dev);
0708 dasd_eer_dev = NULL;
0709 DBF_EVENT(DBF_ERR, "%s", "dasd_eer_init could not "
0710 "register misc device");
0711 return rc;
0712 }
0713
0714 return 0;
0715 }
0716
0717 void dasd_eer_exit(void)
0718 {
0719 if (dasd_eer_dev) {
0720 misc_deregister(dasd_eer_dev);
0721 kfree(dasd_eer_dev);
0722 dasd_eer_dev = NULL;
0723 }
0724 }