* Author(s): Stefan Weinhuber <wein@de.ibm.com>
*/
+#define KMSG_COMPONENT "dasd"
+
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/moduleparam.h>
#include <linux/device.h>
#include <linux/poll.h>
+#include <linux/mutex.h>
+#include <linux/smp_lock.h>
+#include <linux/err.h>
#include <asm/uaccess.h>
-#include <asm/semaphore.h>
#include <asm/atomic.h>
#include <asm/ebcdic.h>
struct dasd_eer_header header;
unsigned long flags;
struct eerbuffer *eerb;
+ char *sense;
/* go through cqr chain and count the valid sense data sets */
data_size = 0;
for (temp_cqr = cqr; temp_cqr; temp_cqr = temp_cqr->refers)
- if (temp_cqr->irb.esw.esw0.erw.cons)
+ if (dasd_get_sense(&temp_cqr->irb))
data_size += 32;
header.total_size = sizeof(header) + data_size + 4; /* "EOR" */
do_gettimeofday(&tv);
header.tv_sec = tv.tv_sec;
header.tv_usec = tv.tv_usec;
- strncpy(header.busid, device->cdev->dev.bus_id, DASD_EER_BUSID_SIZE);
+ strncpy(header.busid, dev_name(&device->cdev->dev),
+ DASD_EER_BUSID_SIZE);
spin_lock_irqsave(&bufferlock, flags);
list_for_each_entry(eerb, &bufferlist, list) {
dasd_eer_start_record(eerb, header.total_size);
dasd_eer_write_buffer(eerb, (char *) &header, sizeof(header));
- for (temp_cqr = cqr; temp_cqr; temp_cqr = temp_cqr->refers)
- if (temp_cqr->irb.esw.esw0.erw.cons)
- dasd_eer_write_buffer(eerb, cqr->irb.ecw, 32);
+ for (temp_cqr = cqr; temp_cqr; temp_cqr = temp_cqr->refers) {
+ sense = dasd_get_sense(&temp_cqr->irb);
+ if (sense)
+ dasd_eer_write_buffer(eerb, sense, 32);
+ }
dasd_eer_write_buffer(eerb, "EOR", 4);
}
spin_unlock_irqrestore(&bufferlock, flags);
unsigned long flags;
struct eerbuffer *eerb;
- snss_rc = (cqr->status == DASD_CQR_FAILED) ? -EIO : 0;
+ snss_rc = (cqr->status == DASD_CQR_DONE) ? 0 : -EIO;
if (snss_rc)
data_size = 0;
else
do_gettimeofday(&tv);
header.tv_sec = tv.tv_sec;
header.tv_usec = tv.tv_usec;
- strncpy(header.busid, device->cdev->dev.bus_id, DASD_EER_BUSID_SIZE);
+ strncpy(header.busid, dev_name(&device->cdev->dev),
+ DASD_EER_BUSID_SIZE);
spin_lock_irqsave(&bufferlock, flags);
list_for_each_entry(eerb, &bufferlist, list) {
set_bit(DASD_FLAG_EER_SNSS, &device->flags);
return;
}
+ /* cdev is already locked, can't use dasd_add_request_head */
clear_bit(DASD_FLAG_EER_SNSS, &device->flags);
cqr->status = DASD_CQR_QUEUED;
- list_add(&cqr->list, &device->ccw_queue);
- dasd_schedule_bh(device);
+ list_add(&cqr->devlist, &device->ccw_queue);
+ dasd_schedule_device_bh(device);
}
/*
*/
static void dasd_eer_snss_cb(struct dasd_ccw_req *cqr, void *data)
{
- struct dasd_device *device = cqr->device;
+ struct dasd_device *device = cqr->startdev;
unsigned long flags;
dasd_eer_write(device, cqr, DASD_EER_STATECHANGE);
{
struct dasd_ccw_req *cqr;
unsigned long flags;
+ struct ccw1 *ccw;
if (device->eer_cqr)
return 0;
cqr = dasd_kmalloc_request("ECKD", 1 /* SNSS */,
SNSS_DATA_SIZE, device);
- if (!cqr)
+ if (IS_ERR(cqr))
return -ENOMEM;
- cqr->device = device;
+ cqr->startdev = device;
cqr->retries = 255;
cqr->expires = 10 * HZ;
+ clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
- cqr->cpaddr->cmd_code = DASD_ECKD_CCW_SNSS;
- cqr->cpaddr->count = SNSS_DATA_SIZE;
- cqr->cpaddr->flags = 0;
- cqr->cpaddr->cda = (__u32)(addr_t) cqr->data;
+ ccw = cqr->cpaddr;
+ ccw->cmd_code = DASD_ECKD_CCW_SNSS;
+ ccw->count = SNSS_DATA_SIZE;
+ ccw->flags = 0;
+ ccw->cda = (__u32)(addr_t) cqr->data;
cqr->buildclk = get_clock();
cqr->status = DASD_CQR_FILLED;
* to transfer in a readbuffer, which is protected by the readbuffer_mutex.
*/
static char readbuffer[PAGE_SIZE];
-static DECLARE_MUTEX(readbuffer_mutex);
+static DEFINE_MUTEX(readbuffer_mutex);
static int dasd_eer_open(struct inode *inp, struct file *filp)
{
eerb = kzalloc(sizeof(struct eerbuffer), GFP_KERNEL);
if (!eerb)
return -ENOMEM;
+ lock_kernel();
eerb->buffer_page_count = eer_pages;
if (eerb->buffer_page_count < 1 ||
eerb->buffer_page_count > INT_MAX / PAGE_SIZE) {
kfree(eerb);
- MESSAGE(KERN_WARNING, "can't open device since module "
- "parameter eer_pages is smaller then 1 or"
- " bigger then %d", (int)(INT_MAX / PAGE_SIZE));
+ DBF_EVENT(DBF_WARNING, "can't open device since module "
+ "parameter eer_pages is smaller than 1 or"
+ " bigger than %d", (int)(INT_MAX / PAGE_SIZE));
+ unlock_kernel();
return -EINVAL;
}
eerb->buffersize = eerb->buffer_page_count * PAGE_SIZE;
GFP_KERNEL);
if (!eerb->buffer) {
kfree(eerb);
+ unlock_kernel();
return -ENOMEM;
}
if (dasd_eer_allocate_buffer_pages(eerb->buffer,
eerb->buffer_page_count)) {
kfree(eerb->buffer);
kfree(eerb);
+ unlock_kernel();
return -ENOMEM;
}
filp->private_data = eerb;
list_add(&eerb->list, &bufferlist);
spin_unlock_irqrestore(&bufferlock, flags);
+ unlock_kernel();
return nonseekable_open(inp,filp);
}
struct eerbuffer *eerb;
eerb = (struct eerbuffer *) filp->private_data;
- if (down_interruptible(&readbuffer_mutex))
+ if (mutex_lock_interruptible(&readbuffer_mutex))
return -ERESTARTSYS;
spin_lock_irqsave(&bufferlock, flags);
/* has been deleted */
eerb->residual = 0;
spin_unlock_irqrestore(&bufferlock, flags);
- up(&readbuffer_mutex);
+ mutex_unlock(&readbuffer_mutex);
return -EIO;
} else if (eerb->residual > 0) {
/* OK we still have a second half of a record to deliver */
if (!tc) {
/* no data available */
spin_unlock_irqrestore(&bufferlock, flags);
- up(&readbuffer_mutex);
+ mutex_unlock(&readbuffer_mutex);
if (filp->f_flags & O_NONBLOCK)
return -EAGAIN;
rc = wait_event_interruptible(
eerb->head != eerb->tail);
if (rc)
return rc;
- if (down_interruptible(&readbuffer_mutex))
+ if (mutex_lock_interruptible(&readbuffer_mutex))
return -ERESTARTSYS;
spin_lock_irqsave(&bufferlock, flags);
}
spin_unlock_irqrestore(&bufferlock, flags);
if (copy_to_user(buf, readbuffer, effective_count)) {
- up(&readbuffer_mutex);
+ mutex_unlock(&readbuffer_mutex);
return -EFAULT;
}
- up(&readbuffer_mutex);
+ mutex_unlock(&readbuffer_mutex);
return effective_count;
}
if (rc) {
kfree(dasd_eer_dev);
dasd_eer_dev = NULL;
- MESSAGE(KERN_ERR, "%s", "dasd_eer_init could not "
+ DBF_EVENT(DBF_ERR, "%s", "dasd_eer_init could not "
"register misc device");
return rc;
}