2 * character device driver for extended error reporting
5 * Copyright (C) 2005 IBM Corporation
6 * extended error reporting for DASD ECKD devices
7 * Author(s): Stefan Weinhuber <wein@de.ibm.com>
11 #include <linux/init.h>
13 #include <linux/kernel.h>
14 #include <linux/miscdevice.h>
15 #include <linux/module.h>
16 #include <linux/moduleparam.h>
17 #include <linux/device.h>
18 #include <linux/workqueue.h>
19 #include <linux/poll.h>
20 #include <linux/notifier.h>
22 #include <asm/uaccess.h>
23 #include <asm/semaphore.h>
24 #include <asm/atomic.h>
25 #include <asm/ebcdic.h>
28 #include "dasd_eckd.h"
31 MODULE_LICENSE("GPL");
33 MODULE_AUTHOR("Stefan Weinhuber <wein@de.ibm.com>");
34 MODULE_DESCRIPTION("DASD extended error reporting module");
39 #endif /* PRINTK_HEADER */
40 #define PRINTK_HEADER "dasd(eer):"
46 /*****************************************************************************/
47 /* the internal buffer */
48 /*****************************************************************************/
51 * The internal buffer is meant to store obaque blobs of data, so it doesn't
52 * know of higher level concepts like triggers.
53 * It consists of a number of pages that are used as a ringbuffer. Each data
54 * blob is stored in a simple record that consists of an integer, which
55 * contains the size of the following data, and the data bytes themselfes.
57 * To allow for multiple independent readers we create one internal buffer
58 * each time the device is opened and destroy the buffer when the file is
61 * One record can be written to a buffer by using the functions
62 * - dasd_eer_start_record (one time per record to write the size to the buffer
63 * and reserve the space for the data)
64 * - dasd_eer_write_buffer (one or more times per record to write the data)
65 * The data can be written in several steps but you will have to compute
66 * the total size up front for the invocation of dasd_eer_start_record.
67 * If the ringbuffer is full, dasd_eer_start_record will remove the required
68 * number of old records.
70 * A record is typically read in two steps, first read the integer that
71 * specifies the size of the following data, then read the data.
73 * - dasd_eer_read_buffer
75 * For all mentioned functions you need to get the bufferlock first and keep it
76 * until a complete record is written or read.
81 * Alle information necessary to keep track of an internal buffer is kept in
82 * a struct eerbuffer. The buffer specific to a file pointer is strored in
83 * the private_data field of that file. To be able to write data to all
84 * existing buffers, each buffer is also added to the bufferlist.
85 * If the user doesn't want to read a complete record in one go, we have to
86 * keep track of the rest of the record. residual stores the number of bytes
87 * that are still to deliver. If the rest of the record is invalidated between
88 * two reads then residual will be set to -1 so that the next read will fail.
89 * All entries in the eerbuffer structure are protected with the bufferlock.
90 * To avoid races between writing to a buffer on the one side and creating
91 * and destroying buffers on the other side, the bufferlock must also be used
92 * to protect the bufferlist.
96 struct list_head list;
99 int buffer_page_count;
105 LIST_HEAD(bufferlist);
107 static spinlock_t bufferlock = SPIN_LOCK_UNLOCKED;
109 DECLARE_WAIT_QUEUE_HEAD(dasd_eer_read_wait_queue);
112 * How many free bytes are available on the buffer.
113 * needs to be called with bufferlock held
116 dasd_eer_get_free_bytes(struct eerbuffer *eerb)
118 if (eerb->head < eerb->tail) {
119 return eerb->tail - eerb->head - 1;
121 return eerb->buffersize - eerb->head + eerb->tail -1;
125 * How many bytes of buffer space are used.
126 * needs to be called with bufferlock held
129 dasd_eer_get_filled_bytes(struct eerbuffer *eerb)
132 if (eerb->head >= eerb->tail) {
133 return eerb->head - eerb->tail;
135 return eerb->buffersize - eerb->tail + eerb->head;
139 * The dasd_eer_write_buffer function just copies count bytes of data
140 * to the buffer. Make sure to call dasd_eer_start_record first, to
141 * make sure that enough free space is available.
142 * needs to be called with bufferlock held
145 dasd_eer_write_buffer(struct eerbuffer *eerb, int count, char *data)
148 unsigned long headindex,localhead;
149 unsigned long rest, len;
155 headindex = eerb->head / PAGE_SIZE;
156 localhead = eerb->head % PAGE_SIZE;
157 len = min(rest, (PAGE_SIZE - localhead));
158 memcpy(eerb->buffer[headindex]+localhead, nextdata, len);
162 if ( eerb->head == eerb->buffersize )
163 eerb->head = 0; /* wrap around */
164 if (eerb->head > eerb->buffersize) {
165 MESSAGE(KERN_ERR, "%s", "runaway buffer head.");
172 * needs to be called with bufferlock held
175 dasd_eer_read_buffer(struct eerbuffer *eerb, int count, char *data)
178 unsigned long tailindex,localtail;
179 unsigned long rest, len, finalcount;
182 finalcount = min(count, dasd_eer_get_filled_bytes(eerb));
186 tailindex = eerb->tail / PAGE_SIZE;
187 localtail = eerb->tail % PAGE_SIZE;
188 len = min(rest, (PAGE_SIZE - localtail));
189 memcpy(nextdata, eerb->buffer[tailindex]+localtail, len);
193 if ( eerb->tail == eerb->buffersize )
194 eerb->tail = 0; /* wrap around */
195 if (eerb->tail > eerb->buffersize) {
196 MESSAGE(KERN_ERR, "%s", "runaway buffer tail.");
204 * Whenever you want to write a blob of data to the internal buffer you
205 * have to start by using this function first. It will write the number
206 * of bytes that will be written to the buffer. If necessary it will remove
207 * old records to make room for the new one.
208 * needs to be called with bufferlock held
211 dasd_eer_start_record(struct eerbuffer *eerb, int count)
214 if (count + sizeof(count) > eerb->buffersize)
216 while (dasd_eer_get_free_bytes(eerb) < count + sizeof(count)) {
217 if (eerb->residual > 0) {
218 eerb->tail += eerb->residual;
219 if (eerb->tail >= eerb->buffersize)
220 eerb->tail -= eerb->buffersize;
223 dasd_eer_read_buffer(eerb, sizeof(tailcount),
224 (char*)(&tailcount));
225 eerb->tail += tailcount;
226 if (eerb->tail >= eerb->buffersize)
227 eerb->tail -= eerb->buffersize;
229 dasd_eer_write_buffer(eerb, sizeof(count), (char*)(&count));
235 * release pages that are not used anymore
238 dasd_eer_free_buffer_pages(char **buf, int no_pages)
242 for (i = 0; i < no_pages; ++i) {
243 free_page((unsigned long)buf[i]);
248 * allocate a new set of memory pages
251 dasd_eer_allocate_buffer_pages(char **buf, int no_pages)
255 for (i = 0; i < no_pages; ++i) {
256 buf[i] = (char *) get_zeroed_page(GFP_KERNEL);
258 dasd_eer_free_buffer_pages(buf, i);
266 * empty the buffer by resetting head and tail
267 * In case there is a half read data blob in the buffer, we set residual
268 * to -1 to indicate that the remainder of the blob is lost.
271 dasd_eer_purge_buffer(struct eerbuffer *eerb)
275 spin_lock_irqsave(&bufferlock, flags);
276 if (eerb->residual > 0)
280 spin_unlock_irqrestore(&bufferlock, flags);
284 * set the size of the buffer, newsize is the new number of pages to be used
285 * we don't try to copy any data back an forth, so any resize will also purge
289 dasd_eer_resize_buffer(struct eerbuffer *eerb, int newsize)
291 int i, oldcount, reuse;
298 if (eerb->buffer_page_count == newsize) {
299 /* documented behaviour is that any successfull invocation
300 * will purge all records */
301 dasd_eer_purge_buffer(eerb);
304 new = kmalloc(newsize*sizeof(char*), GFP_KERNEL);
308 reuse=min(eerb->buffer_page_count, newsize);
309 for (i = 0; i < reuse; ++i) {
310 new[i] = eerb->buffer[i];
312 if (eerb->buffer_page_count < newsize) {
313 if (dasd_eer_allocate_buffer_pages(
314 &new[eerb->buffer_page_count],
315 newsize - eerb->buffer_page_count)) {
321 spin_lock_irqsave(&bufferlock, flags);
324 if (eerb->residual > 0)
328 oldcount = eerb->buffer_page_count;
329 eerb->buffer_page_count = newsize;
330 spin_unlock_irqrestore(&bufferlock, flags);
332 if (oldcount > newsize) {
333 for (i = newsize; i < oldcount; ++i) {
334 free_page((unsigned long)old[i]);
343 /*****************************************************************************/
344 /* The extended error reporting functionality */
345 /*****************************************************************************/
348 * When a DASD device driver wants to report an error, it calls the
349 * function dasd_eer_write_trigger (via a notifier mechanism) and gives the
350 * respective trigger ID as parameter.
351 * Currently there are four kinds of triggers:
353 * DASD_EER_FATALERROR: all kinds of unrecoverable I/O problems
354 * DASD_EER_PPRCSUSPEND: PPRC was suspended
355 * DASD_EER_NOPATH: There is no path to the device left.
356 * DASD_EER_STATECHANGE: The state of the device has changed.
358 * For the first three triggers all required information can be supplied by
359 * the caller. For these triggers a record is written by the function
360 * dasd_eer_write_standard_trigger.
362 * When dasd_eer_write_trigger is called to write a DASD_EER_STATECHANGE
363 * trigger, we have to gather the necessary sense data first. We cannot queue
364 * the necessary SNSS (sense subsystem status) request immediatly, since we
365 * are likely to run in a deadlock situation. Instead, we schedule a
366 * work_struct that calls the function dasd_eer_sense_subsystem_status to
367 * create and start an SNSS request asynchronously.
369 * To avoid memory allocations at runtime, the necessary memory is allocated
370 * when the extended error reporting is enabled for a device (by
371 * dasd_eer_probe). There is one private eer data structure for each eer
372 * enabled DASD device. It contains memory for the work_struct, one SNSS cqr
373 * and a flags field that is used to coordinate the use of the cqr. The call
374 * to write a state change trigger can come in at any time, so we have one flag
375 * CQR_IN_USE that protects the cqr itself. When this flag indicates that the
376 * cqr is currently in use, dasd_eer_sense_subsystem_status cannot start a
377 * second request but sets the SNSS_REQUESTED flag instead.
379 * When the request is finished, the callback function dasd_eer_SNSS_cb
380 * is called. This function will invoke the function
381 * dasd_eer_write_SNSS_trigger to finally write the trigger. It will also
382 * check the SNSS_REQUESTED flag and if it is set it will call
383 * dasd_eer_sense_subsystem_status again.
385 * To avoid race conditions during the handling of the lock, the flags must
386 * be protected by the snsslock.
389 struct dasd_eer_private {
390 struct dasd_ccw_req *cqr;
392 struct work_struct worker;
395 static void dasd_eer_destroy(struct dasd_device *device,
396 struct dasd_eer_private *eer);
398 dasd_eer_write_trigger(struct dasd_eer_trigger *trigger);
399 static void dasd_eer_sense_subsystem_status(void *data);
400 static int dasd_eer_notify(struct notifier_block *self,
401 unsigned long action, void *data);
403 struct workqueue_struct *dasd_eer_workqueue;
405 #define SNSS_DATA_SIZE 44
406 static spinlock_t snsslock = SPIN_LOCK_UNLOCKED;
408 #define DASD_EER_BUSID_SIZE 10
409 struct dasd_eer_header {
414 char busid[DASD_EER_BUSID_SIZE];
415 } __attribute__ ((packed));
417 static struct notifier_block dasd_eer_nb = {
418 .notifier_call = dasd_eer_notify,
422 * flags for use with dasd_eer_private
425 #define SNSS_REQUESTED 1
428 * This function checks if extended error reporting is available for a given
429 * dasd_device. If yes, then it creates and returns a struct dasd_eer,
430 * otherwise it returns an -EPERM error pointer.
432 struct dasd_eer_private *
433 dasd_eer_probe(struct dasd_device *device)
435 struct dasd_eer_private *private;
437 if (!(device && device->discipline
438 && !strcmp(device->discipline->name, "ECKD"))) {
439 return ERR_PTR(-EPERM);
441 /* allocate the private data structure */
442 private = (struct dasd_eer_private *)kmalloc(
443 sizeof(struct dasd_eer_private), GFP_KERNEL);
445 return ERR_PTR(-ENOMEM);
447 INIT_WORK(&private->worker, dasd_eer_sense_subsystem_status,
449 private->cqr = dasd_kmalloc_request("ECKD",
455 return ERR_PTR(-ENOMEM);
462 * If our private SNSS request is queued, remove it from the
463 * dasd ccw queue so we can free the requests memory.
466 dasd_eer_dequeue_SNSS_request(struct dasd_device *device,
467 struct dasd_eer_private *eer)
469 struct list_head *lst, *nxt;
470 struct dasd_ccw_req *cqr, *erpcqr;
471 dasd_erp_fn_t erp_fn;
473 spin_lock_irq(get_ccwdev_lock(device->cdev));
474 list_for_each_safe(lst, nxt, &device->ccw_queue) {
475 cqr = list_entry(lst, struct dasd_ccw_req, list);
476 /* we are looking for two kinds or requests */
477 /* first kind: our SNSS request: */
478 if (cqr == eer->cqr) {
479 if (cqr->status == DASD_CQR_IN_IO)
480 device->discipline->term_IO(cqr);
481 list_del(&cqr->list);
484 /* second kind: ERP requests for our SNSS request */
486 /* If this erp request chain ends in our cqr, then */
487 /* cal the erp_postaction to clean it up */
489 while (erpcqr->refers) {
490 erpcqr = erpcqr->refers;
492 if (erpcqr == eer->cqr) {
493 erp_fn = device->discipline->erp_postaction(
500 spin_unlock_irq(get_ccwdev_lock(device->cdev));
504 * This function dismantles a struct dasd_eer that was created by
505 * dasd_eer_probe. Since we want to free our private data structure,
506 * we must make sure that the memory is not in use anymore.
507 * We have to flush the work queue and remove a possible SNSS request
508 * from the dasd queue.
511 dasd_eer_destroy(struct dasd_device *device, struct dasd_eer_private *eer)
513 flush_workqueue(dasd_eer_workqueue);
514 dasd_eer_dequeue_SNSS_request(device, eer);
515 dasd_kfree_request(eer->cqr, device);
520 * enable the extended error reporting for a particular device
523 dasd_eer_enable_on_device(struct dasd_device *device)
530 if (!try_module_get(THIS_MODULE)) {
533 eer = (void *)dasd_eer_probe(device);
535 module_put(THIS_MODULE);
543 * enable the extended error reporting for a particular device
546 dasd_eer_disable_on_device(struct dasd_device *device)
548 struct dasd_eer_private *eer = device->eer;
555 dasd_eer_destroy(device,eer);
556 module_put(THIS_MODULE);
562 * Set extended error reporting (eer)
563 * Note: This will be registered as a DASD ioctl, to be called on DASD devices.
566 dasd_ioctl_set_eer(struct block_device *bdev, int no, long args)
568 struct dasd_device *device;
571 if (!capable(CAP_SYS_ADMIN))
573 if (bdev != bdev->bd_contains)
574 /* Error-reporting is not allowed for partitions */
576 if (get_user(intval, (int __user *) args))
578 device = bdev->bd_disk->private_data;
582 intval = (intval != 0);
583 DEV_MESSAGE (KERN_DEBUG, device,
584 "set eer on device to %d", intval);
586 return dasd_eer_enable_on_device(device);
588 return dasd_eer_disable_on_device(device);
592 * Get value of extended error reporting.
593 * Note: This will be registered as a DASD ioctl, to be called on DASD devices.
596 dasd_ioctl_get_eer(struct block_device *bdev, int no, long args)
598 struct dasd_device *device;
600 device = bdev->bd_disk->private_data;
603 return put_user((device->eer != NULL), (int __user *) args);
607 * The following function can be used for those triggers that have
608 * all necessary data available when the function is called.
609 * If the parameter cqr is not NULL, the chain of requests will be searched
610 * for valid sense data, and all valid sense data sets will be added to
614 dasd_eer_write_standard_trigger(int trigger, struct dasd_device *device,
615 struct dasd_ccw_req *cqr)
617 struct dasd_ccw_req *temp_cqr;
620 struct dasd_eer_header header;
622 struct eerbuffer *eerb;
624 /* go through cqr chain and count the valid sense data sets */
628 if (temp_cqr->irb.esw.esw0.erw.cons)
630 temp_cqr = temp_cqr->refers;
633 header.total_size = sizeof(header) + data_size + 4; /* "EOR" */
634 header.trigger = trigger;
635 do_gettimeofday(&tv);
636 header.tv_sec = tv.tv_sec;
637 header.tv_usec = tv.tv_usec;
638 strncpy(header.busid, device->cdev->dev.bus_id, DASD_EER_BUSID_SIZE);
640 spin_lock_irqsave(&bufferlock, flags);
641 list_for_each_entry(eerb, &bufferlist, list) {
642 dasd_eer_start_record(eerb, header.total_size);
643 dasd_eer_write_buffer(eerb, sizeof(header), (char*)(&header));
646 if (temp_cqr->irb.esw.esw0.erw.cons)
647 dasd_eer_write_buffer(eerb, 32, cqr->irb.ecw);
648 temp_cqr = temp_cqr->refers;
650 dasd_eer_write_buffer(eerb, 4,"EOR");
652 spin_unlock_irqrestore(&bufferlock, flags);
654 wake_up_interruptible(&dasd_eer_read_wait_queue);
660 * This function writes a DASD_EER_STATECHANGE trigger.
663 dasd_eer_write_SNSS_trigger(struct dasd_device *device,
664 struct dasd_ccw_req *cqr)
669 struct dasd_eer_header header;
671 struct eerbuffer *eerb;
673 snss_rc = (cqr->status == DASD_CQR_FAILED) ? -EIO : 0;
677 data_size = SNSS_DATA_SIZE;
679 header.total_size = sizeof(header) + data_size + 4; /* "EOR" */
680 header.trigger = DASD_EER_STATECHANGE;
681 do_gettimeofday(&tv);
682 header.tv_sec = tv.tv_sec;
683 header.tv_usec = tv.tv_usec;
684 strncpy(header.busid, device->cdev->dev.bus_id, DASD_EER_BUSID_SIZE);
686 spin_lock_irqsave(&bufferlock, flags);
687 list_for_each_entry(eerb, &bufferlist, list) {
688 dasd_eer_start_record(eerb, header.total_size);
689 dasd_eer_write_buffer(eerb, sizeof(header),(char*)(&header));
691 dasd_eer_write_buffer(eerb, SNSS_DATA_SIZE, cqr->data);
692 dasd_eer_write_buffer(eerb, 4,"EOR");
694 spin_unlock_irqrestore(&bufferlock, flags);
696 wake_up_interruptible(&dasd_eer_read_wait_queue);
700 * callback function for use with SNSS request
703 dasd_eer_SNSS_cb(struct dasd_ccw_req *cqr, void *data)
705 struct dasd_device *device;
706 struct dasd_eer_private *private;
707 unsigned long irqflags;
709 device = (struct dasd_device *)data;
710 private = (struct dasd_eer_private *)device->eer;
711 dasd_eer_write_SNSS_trigger(device, cqr);
712 spin_lock_irqsave(&snsslock, irqflags);
713 if(!test_and_clear_bit(SNSS_REQUESTED, &private->flags)) {
714 clear_bit(CQR_IN_USE, &private->flags);
715 spin_unlock_irqrestore(&snsslock, irqflags);
718 clear_bit(CQR_IN_USE, &private->flags);
719 spin_unlock_irqrestore(&snsslock, irqflags);
720 dasd_eer_sense_subsystem_status(device);
725 * clean a used cqr before using it again
728 dasd_eer_clean_SNSS_request(struct dasd_ccw_req *cqr)
730 struct ccw1 *cpaddr = cqr->cpaddr;
731 void *data = cqr->data;
733 memset(cqr, 0, sizeof(struct dasd_ccw_req));
734 memset(cpaddr, 0, sizeof(struct ccw1));
735 memset(data, 0, SNSS_DATA_SIZE);
736 cqr->cpaddr = cpaddr;
738 strncpy((char *) &cqr->magic, "ECKD", 4);
739 ASCEBC((char *) &cqr->magic, 4);
740 set_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
744 * build and start an SNSS request
745 * This function is called from a work queue so we have to
746 * pass the dasd_device pointer as a void pointer.
749 dasd_eer_sense_subsystem_status(void *data)
751 struct dasd_device *device;
752 struct dasd_eer_private *private;
753 struct dasd_ccw_req *cqr;
755 unsigned long irqflags;
757 device = (struct dasd_device *)data;
758 private = (struct dasd_eer_private *)device->eer;
759 if (!private) /* device not eer enabled any more */
762 spin_lock_irqsave(&snsslock, irqflags);
763 if(test_and_set_bit(CQR_IN_USE, &private->flags)) {
764 set_bit(SNSS_REQUESTED, &private->flags);
765 spin_unlock_irqrestore(&snsslock, irqflags);
768 spin_unlock_irqrestore(&snsslock, irqflags);
769 dasd_eer_clean_SNSS_request(cqr);
770 cqr->device = device;
772 cqr->expires = 10 * HZ;
775 ccw->cmd_code = DASD_ECKD_CCW_SNSS;
776 ccw->count = SNSS_DATA_SIZE;
778 ccw->cda = (__u32)(addr_t)cqr->data;
780 cqr->buildclk = get_clock();
781 cqr->status = DASD_CQR_FILLED;
782 cqr->callback = dasd_eer_SNSS_cb;
783 cqr->callback_data = (void *)device;
784 dasd_add_request_head(cqr);
790 * This function is called for all triggers. It calls the appropriate
791 * function that writes the actual trigger records.
794 dasd_eer_write_trigger(struct dasd_eer_trigger *trigger)
797 struct dasd_eer_private *private = trigger->device->eer;
799 switch (trigger->id) {
800 case DASD_EER_FATALERROR:
801 case DASD_EER_PPRCSUSPEND:
802 rc = dasd_eer_write_standard_trigger(
803 trigger->id, trigger->device, trigger->cqr);
805 case DASD_EER_NOPATH:
806 rc = dasd_eer_write_standard_trigger(
807 trigger->id, trigger->device, NULL);
809 case DASD_EER_STATECHANGE:
810 if (queue_work(dasd_eer_workqueue, &private->worker)) {
813 /* If the work_struct was already queued, it can't
814 * be queued again. But this is OK since we don't
815 * need to have it queued twice.
820 default: /* unknown trigger, so we write it without any sense data */
821 rc = dasd_eer_write_standard_trigger(
822 trigger->id, trigger->device, NULL);
829 * This function is registered with the dasd device driver and gets called
830 * for all dasd eer notifications.
832 static int dasd_eer_notify(struct notifier_block *self,
833 unsigned long action, void *data)
836 case DASD_EER_DISABLE:
837 dasd_eer_disable_on_device((struct dasd_device *)data);
839 case DASD_EER_TRIGGER:
840 dasd_eer_write_trigger((struct dasd_eer_trigger *)data);
847 /*****************************************************************************/
848 /* the device operations */
849 /*****************************************************************************/
852 * On the one side we need a lock to access our internal buffer, on the
853 * other side a copy_to_user can sleep. So we need to copy the data we have
854 * to transfer in a readbuffer, which is protected by the readbuffer_mutex.
856 static char readbuffer[PAGE_SIZE];
857 DECLARE_MUTEX(readbuffer_mutex);
861 dasd_eer_open(struct inode *inp, struct file *filp)
863 struct eerbuffer *eerb;
866 eerb = kmalloc(sizeof(struct eerbuffer), GFP_KERNEL);
870 eerb->buffer_page_count = 1;
871 eerb->buffersize = eerb->buffer_page_count * PAGE_SIZE;
872 eerb->buffer = kmalloc(eerb->buffer_page_count*sizeof(char*),
876 if (dasd_eer_allocate_buffer_pages(eerb->buffer,
877 eerb->buffer_page_count)) {
881 filp->private_data = eerb;
882 spin_lock_irqsave(&bufferlock, flags);
883 list_add(&eerb->list, &bufferlist);
884 spin_unlock_irqrestore(&bufferlock, flags);
886 return nonseekable_open(inp,filp);
890 dasd_eer_close(struct inode *inp, struct file *filp)
892 struct eerbuffer *eerb;
895 eerb = (struct eerbuffer *)filp->private_data;
896 spin_lock_irqsave(&bufferlock, flags);
897 list_del(&eerb->list);
898 spin_unlock_irqrestore(&bufferlock, flags);
899 dasd_eer_free_buffer_pages(eerb->buffer, eerb->buffer_page_count);
907 dasd_eer_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
910 struct eerbuffer *eerb;
912 eerb = (struct eerbuffer *)filp->private_data;
915 dasd_eer_purge_buffer(eerb);
917 case DASD_EER_SETBUFSIZE:
918 if (get_user(intval, (int __user *)arg))
920 return dasd_eer_resize_buffer(eerb, intval);
927 dasd_eer_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
930 int tailcount,effective_count;
932 struct eerbuffer *eerb;
934 eerb = (struct eerbuffer *)filp->private_data;
935 if(down_interruptible(&readbuffer_mutex))
938 spin_lock_irqsave(&bufferlock, flags);
940 if (eerb->residual < 0) { /* the remainder of this record */
941 /* has been deleted */
943 spin_unlock_irqrestore(&bufferlock, flags);
944 up(&readbuffer_mutex);
946 } else if (eerb->residual > 0) {
947 /* OK we still have a second half of a record to deliver */
948 effective_count = min(eerb->residual, (int)count);
949 eerb->residual -= effective_count;
953 tc = dasd_eer_read_buffer(eerb,
954 sizeof(tailcount), (char*)(&tailcount));
956 /* no data available */
957 spin_unlock_irqrestore(&bufferlock, flags);
958 up(&readbuffer_mutex);
959 if (filp->f_flags & O_NONBLOCK)
961 rc = wait_event_interruptible(
962 dasd_eer_read_wait_queue,
963 eerb->head != eerb->tail);
967 if(down_interruptible(&readbuffer_mutex))
969 spin_lock_irqsave(&bufferlock, flags);
972 WARN_ON(tc != sizeof(tailcount));
973 effective_count = min(tailcount,(int)count);
974 eerb->residual = tailcount - effective_count;
977 tc = dasd_eer_read_buffer(eerb, effective_count, readbuffer);
978 WARN_ON(tc != effective_count);
980 spin_unlock_irqrestore(&bufferlock, flags);
982 if (copy_to_user(buf, readbuffer, effective_count)) {
983 up(&readbuffer_mutex);
987 up(&readbuffer_mutex);
988 return effective_count;
992 dasd_eer_poll (struct file *filp, poll_table *ptable)
996 struct eerbuffer *eerb;
998 eerb = (struct eerbuffer *)filp->private_data;
999 poll_wait(filp, &dasd_eer_read_wait_queue, ptable);
1000 spin_lock_irqsave(&bufferlock, flags);
1001 if (eerb->head != eerb->tail)
1002 mask = POLLIN | POLLRDNORM ;
1005 spin_unlock_irqrestore(&bufferlock, flags);
1009 static struct file_operations dasd_eer_fops = {
1010 .open = &dasd_eer_open,
1011 .release = &dasd_eer_close,
1012 .unlocked_ioctl = &dasd_eer_ioctl,
1013 .compat_ioctl = &dasd_eer_ioctl,
1014 .read = &dasd_eer_read,
1015 .poll = &dasd_eer_poll,
1016 .owner = THIS_MODULE,
1019 static struct miscdevice dasd_eer_dev = {
1020 .minor = MISC_DYNAMIC_MINOR,
1022 .fops = &dasd_eer_fops,
1026 /*****************************************************************************/
1028 /*****************************************************************************/
1031 __init dasd_eer_init(void)
1035 dasd_eer_workqueue = create_singlethread_workqueue("dasd_eer");
1036 if (!dasd_eer_workqueue) {
1037 MESSAGE(KERN_ERR , "%s", "dasd_eer_init could not "
1038 "create workqueue \n");
1043 rc = dasd_register_eer_notifier(&dasd_eer_nb);
1045 MESSAGE(KERN_ERR, "%s", "dasd_eer_init could not "
1046 "register error reporting");
1050 dasd_ioctl_no_register(THIS_MODULE, BIODASDEERSET, dasd_ioctl_set_eer);
1051 dasd_ioctl_no_register(THIS_MODULE, BIODASDEERGET, dasd_ioctl_get_eer);
1053 /* we don't need our own character device,
1054 * so we just register as misc device */
1055 rc = misc_register(&dasd_eer_dev);
1057 MESSAGE(KERN_ERR, "%s", "dasd_eer_init could not "
1058 "register misc device");
1065 dasd_unregister_eer_notifier(&dasd_eer_nb);
1066 dasd_ioctl_no_unregister(THIS_MODULE, BIODASDEERSET,
1067 dasd_ioctl_set_eer);
1068 dasd_ioctl_no_unregister(THIS_MODULE, BIODASDEERGET,
1069 dasd_ioctl_get_eer);
1071 destroy_workqueue(dasd_eer_workqueue);
1076 module_init(dasd_eer_init);
1079 __exit dasd_eer_exit(void)
1081 dasd_unregister_eer_notifier(&dasd_eer_nb);
1082 dasd_ioctl_no_unregister(THIS_MODULE, BIODASDEERSET,
1083 dasd_ioctl_set_eer);
1084 dasd_ioctl_no_unregister(THIS_MODULE, BIODASDEERGET,
1085 dasd_ioctl_get_eer);
1086 destroy_workqueue(dasd_eer_workqueue);
1088 WARN_ON(misc_deregister(&dasd_eer_dev) != 0);
1090 module_exit(dasd_eer_exit);