patch-2.2.15 linux/drivers/s390/block/dasd.c
Next file: linux/drivers/s390/block/dasd_ccwstuff.c
Previous file: linux/drivers/pnp/parport_probe.c
Back to the patch index
Back to the overall index
- Lines: 377
- Date:
Fri Apr 21 12:46:24 2000
- Orig file:
v2.2.14/drivers/s390/block/dasd.c
- Orig date:
Tue Jan 4 21:18:53 2000
diff -u --new-file --recursive --exclude-from ../../exclude v2.2.14/drivers/s390/block/dasd.c linux/drivers/s390/block/dasd.c
@@ -3,7 +3,7 @@
* Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
* : Utz Bacher <utz.bacher@de.ibm.com>
* Bugreports.to..: <Linux390@de.ibm.com>
- * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999
+ * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
*/
#include <linux/stddef.h>
@@ -26,7 +26,7 @@
#include <asm/ebcdic.h>
#include <asm/uaccess.h>
-#include "../../../arch/s390/kernel/irq.h"
+#include <asm/irq.h>
#include "dasd.h"
#include <linux/blk.h>
@@ -38,12 +38,12 @@
#define CCW_READ_DEVICE_CHARACTERISTICS 0x64
-#define DASD_SSCH_RETRIES 5
+#define DASD_SSCH_RETRIES 2
/* This macro is a little tricky, but makes the code more easy to read... */
#define MATCH(info,ct,cm,dt,dm) ( \
-( info -> sid_data.cu_type ct ) && ( info -> sid_data.cu_model cm ) && \
-( info -> sid_data.dev_type dt ) && ( info -> sid_data.dev_model dm ) )
+(( info -> sid_data.cu_type ct ) && ( info -> sid_data.cu_model cm )) && \
+(( info -> sid_data.dev_type dt ) && ( info -> sid_data.dev_model dm )) )
/* Prototypes for the functions called from external */
static ssize_t dasd_read (struct file *, char *, size_t, loff_t *);
@@ -344,14 +344,12 @@
dasd_blks[minor] = dasd_info[di]->sizes.kbytes;
dasd_secsize[minor] = dasd_info[di]->sizes.bp_sector;
dasd_blksize[minor] = dasd_info[di]->sizes.bp_block;
- dasd_maxsecs[minor] =
- ((PAGE_SIZE/sizeof(ccw1_t))-4)<<dasd_info[di]->sizes.s2b_shift;
+ dasd_maxsecs[minor] = 252<<dasd_info[di]->sizes.s2b_shift;
dasd_blks[minor + 1] = dasd_info[di]->sizes.kbytes -
(dasd_info[di]->sizes.first_sector >> 1);
dasd_secsize[minor + 1] = dasd_info[di]->sizes.bp_sector;
dasd_blksize[minor + 1] = dasd_info[di]->sizes.bp_block;
- dasd_maxsecs[minor+1] =
- ((PAGE_SIZE/sizeof(ccw1_t))-4)<<dasd_info[di]->sizes.s2b_shift;
+ dasd_maxsecs[minor+1] = 252<<dasd_info[di]->sizes.s2b_shift;
}
int
@@ -554,6 +552,7 @@
FUNCTION_ENTRY ("check_type");
#ifdef CONFIG_DASD_ECKD
if (MATCH (info, == 0x3990, ||1, == 0x3390, ||1) ||
+ MATCH (info, == 0x9343, ||1, == 0x9345, ||1) ||
MATCH (info, == 0x3990, ||1, == 0x3380, ||1)) {
type = dasd_eckd;
} else
@@ -695,6 +694,8 @@
int retries = DASD_SSCH_RETRIES;
int di, irq;
+ dasd_debug (cqr); /* cqr */
+
if (!cqr) {
PRINT_WARN ("(start_IO) no cqr passed\n");
return -EINVAL;
@@ -773,7 +774,7 @@
{
int sl, sct;
printk (KERN_INFO PRINTK_HEADER
- "-------------------I/O Error-----------------------------\n");
+ "-------------------I/O resulted in unit check:-----------\n");
for (sl = 0; sl < 4; sl++) {
printk (KERN_INFO PRINTK_HEADER "Sense:");
for (sct = 0; sct < 8; sct++) {
@@ -790,17 +791,17 @@
dasd_chanq_t *qp = NULL;
cqr_t *cqr;
long flags;
- int irq,di;
+ int irq;
int tasks;
atomic_set (&bh_scheduled, 0);
- dasd_debug (0x44445f69); /* DD_i */
+ dasd_debug (0xc4c40000); /* DD */
while ((tasks = atomic_read(&chanq_tasks)) != 0) {
/* initialization and wraparound */
if (qp == NULL) {
- dasd_debug (0x44445f68); /* DD_h */
+ dasd_debug (0xc4c46df0); /* DD_0 */
qp = cq_head;
if (!qp) {
- dasd_debug (0x44445f45); /* DD_E */
+ dasd_debug (0xc4c46ff1); /* DD?1 */
dasd_debug (tasks);
PRINT_ERR("Mismatch of NULL queue pointer and "
"still %d chanq_tasks to do!!\n"
@@ -810,18 +811,9 @@
break;
}
}
-/* Get the irq number: Ouch, FIXME!!!!! */
-#if 0
- di =(((unsigned long)qp)-
- ((unsigned long)&(dasd_info[0]->queue)))
- / sizeof(dasd_information_t);
- dasd_debug(di);
- irq = dasd_info[di]->info.irq;
- dasd_debug(irq);
-#endif
/* Get first request */
+ dasd_debug (qp); /* qp */
cqr = (cqr_t *) (qp->head);
- dasd_debug ((unsigned long) cqr); /* cqr */
/* empty queue -> dequeue and proceed */
if (!cqr) {
dasd_chanq_t *nqp = qp->next_q;
@@ -832,33 +824,35 @@
/* process all requests on that queue */
do {
cqr_t *next;
- dasd_debug (0x44445f64); /* DD_d */
dasd_debug ((unsigned long) cqr); /* cqr */
if (cqr->magic != DASD_MAGIC) {
- dasd_debug (0x44445f65); /* DD_e */
- PRINT_WARN ("do_cq:magic mismatch %p\n", cqr);
+ dasd_debug (0xc4c46ff2); /* DD?2 */
+ panic ( PRINTK_HEADER "do_cq:"
+ "magic mismatch %p -> %x\n",
+ cqr, cqr -> magic);
break;
}
irq = dasd_info[cqr->devindex]->info.irq;
s390irq_spin_lock_irqsave (irq, flags);
switch (atomic_read (&cqr->status)) {
case CQR_STATUS_IN_IO:
- dasd_debug (0x44445f48); /* DD_I */
+ dasd_debug (0xc4c4c9d6); /* DDIO */
cqr = NULL;
break;
case CQR_STATUS_QUEUED:
- dasd_debug (0x44445f53); /* DD_S */
+ dasd_debug (0xc4c4e2e3); /* DDST */
if (dasd_start_IO (cqr) == 0) {
atomic_dec (&chanq_tasks);
cqr = NULL;
}
break;
case CQR_STATUS_ERROR:
- dasd_debug (0x44445f54); /* DD_E */
+ dasd_debug (0xc4c4c5d9); /* DDER */
dasd_dump_sense (cqr->dstat);
- if (cqr->retries++ < 5) {
+ if ( ++ cqr->retries < 2 ) {
atomic_set (&cqr->status,
CQR_STATUS_QUEUED);
+ dasd_debug (0xc4c4e2e3); /* DDST */
if (dasd_start_IO (cqr) == 0) {
atomic_dec (&chanq_tasks);
cqr = NULL;
@@ -870,14 +864,14 @@
break;
case CQR_STATUS_DONE:
next = cqr->next;
- dasd_debug (0x44445f44); /* DD_D */
+ dasd_debug (0xc4c49692); /* DDok */
dasd_end_cqr (cqr, 1);
atomic_dec (&chanq_tasks);
cqr = next;
break;
case CQR_STATUS_FAILED:
next = cqr->next;
- dasd_debug (0x44445f45); /* DD_F */
+ dasd_debug (0xc4c47a7a); /* DD:: */
dasd_end_cqr (cqr, 0);
atomic_dec (&chanq_tasks);
cqr = next;
@@ -893,7 +887,7 @@
spin_lock (&io_request_lock);
do_dasd_request ();
spin_unlock (&io_request_lock);
- dasd_debug (0x44445f6f); /* DD_o */
+ dasd_debug (0xc4c46d6d); /* DD__ */
}
/*
@@ -901,6 +895,9 @@
We use it to feed the chanqs.
This implementation assumes we are serialized by the io_request_lock.
*/
+
+#define QUEUE_THRESHOLD 5
+
void
do_dasd_request (void)
{
@@ -916,23 +913,25 @@
long flags;
int irq;
- __asm__ ("lr %0,14":"=d" (caller));
- dasd_debug (0x44525f69); /* DR_i */
- dasd_debug ((unsigned long) caller); /* calleraddres */
+ dasd_debug (0xc4d90000); /* DR */
+ dasd_debug (__builtin_return_address(0)); /* calleraddres */
prev = NULL;
for (req = CURRENT; req != NULL; req = next) {
next = req->next;
di = DEVICE_NR (req->rq_dev);
dasd_debug ((unsigned long) req); /* req */
- dasd_debug (0x44520000 + /* DR## */
- ((((di/16)<9?(di/16)+'0':(di/16)+'a'))<<8) +
- (((di%16)<9?(di%16)+'0':(di%16)+'a')));
+ dasd_debug (0xc4d90000 + /* DR## */
+ ((((di/16)<9?(di/16)+0xf0:(di/16)+0xc1))<<8) +
+ (((di%16)<9?(di%16)+0xf0:(di%16)+0xc1)));
irq = dasd_info[di]->info.irq;
s390irq_spin_lock_irqsave (irq, flags);
q = &dasd_info[di]->queue;
busy[di] = busy[di]||(atomic_read(&q->flags)&DASD_CHANQ_BUSY);
if ( !busy[di] ||
((!broken[di]) && (req->nr_sectors >= QUEUE_SECTORS))) {
+#if 0
+ if ( q -> queued_requests < QUEUE_THRESHOLD ) {
+#endif
if (prev) {
prev->next = next;
} else {
@@ -940,39 +939,41 @@
}
req->next = NULL;
if (req == &blk_dev[MAJOR_NR].plug) {
- dasd_debug (0x44525f75); /* DR_u */
+ dasd_debug (0xc4d99787); /* DRpg */
goto cont;
}
cqr = dasd_cqr_from_req (req);
if (!cqr) {
- dasd_debug (0x44525f65); /* DR_e */
+ dasd_debug (0xc4d96ff1); /* DR?1 */
dasd_end_request (req, 0);
goto cont;
}
- dasd_debug (0x44525f71); /* DR_q */
dasd_debug ((unsigned long) cqr); /* cqr */
dasd_chanq_enq (q, cqr);
- if (!(atomic_read (&q->flags) & DASD_CHANQ_ACTIVE)) {
+ if (!(atomic_read (&q->flags) &
+ DASD_CHANQ_ACTIVE)) {
cql_enq_head (q);
}
if (!busy[di]) {
- if (dasd_start_IO (cqr) == 0)
- dasd_debug (0x44525f73); /* DR_s */
- else {
+ dasd_debug (0xc4d9e2e3); /* DRST */
+ if (dasd_start_IO (cqr) != 0) {
atomic_inc (&chanq_tasks);
schedule_bh (dasd_do_chanq);
busy[di] = 1;
}
}
+#if 0
+ }
+#endif
} else {
- dasd_debug (0x44525f62); /* DR_b */
+ dasd_debug (0xc4d9c2d9); /* DRBR */
broken[di] = 1;
prev = req;
}
cont:
s390irq_spin_unlock_irqrestore (irq, flags);
}
- dasd_debug (0x44525f6f); /* DR_o */
+ dasd_debug (0xc4d96d6d); /* DR__ */
}
void
@@ -983,34 +984,35 @@
cqr_t *cqr;
int done_fast_io = 0;
- dasd_debug (0x44485f69); /* DH_i */
+ dasd_debug (0xc4c80000); /* DH */
if (!stat)
PRINT_ERR ("handler called without devstat");
ip = stat->intparm;
dasd_debug (ip); /* intparm */
switch (ip) { /* filter special intparms... */
case 0x00000000: /* no intparm: unsolicited interrupt */
- dasd_debug (0x44485f30); /* DH_0 */
+ dasd_debug (0xc4c8a489); /* DHui */
PRINT_INFO ("Unsolicited interrupt on device %04X\n",
stat->devno);
dasd_dump_sense (stat);
return;
default:
if (ip & 0x80000001) {
+ dasd_debug (0xc4c8a489); /* DHui */
PRINT_INFO ("Spurious interrupt %08x on device %04X\n",
ip, stat->devno);
return;
}
cqr = (cqr_t *) ip;
if (cqr->magic != DASD_MAGIC) {
- dasd_debug (0x44485f65); /* DH_e */
- PRINT_WARN ("handler:magic mismatch on %p %08x\n",
+ dasd_debug (0xc4c86ff1); /* DH?1 */
+ PRINT_ERR ("handler:magic mismatch on %p %08x\n",
cqr, cqr->magic);
return;
}
asm volatile ("STCK %0":"=m" (cqr->stopclk));
if (stat->cstat == 0x00 && stat->dstat == 0x0c) {
- dasd_debug (0x44486f6b); /* DHok */
+ dasd_debug (0xc4c89692); /* DHok */
if (atomic_compare_and_swap (CQR_STATUS_IN_IO,
CQR_STATUS_DONE,
&cqr->status)) {
@@ -1018,31 +1020,23 @@
atomic_read (&cqr->status));
}
if (cqr->next) {
- dasd_debug (0x44485f6e); /* DH_n */
+ dasd_debug (0xc4c8e2e3); /* DHST */
if (dasd_start_IO (cqr->next) == 0)
done_fast_io = 1;
}
break;
}
- dasd_debug (0x44482121); /* DH!! */
+ dasd_debug (0xc4c8c5d9); /* DHER */
if (!cqr->dstat)
cqr->dstat = kmalloc (sizeof (devstat_t),
GFP_ATOMIC);
if (cqr->dstat) {
memcpy (cqr->dstat, stat, sizeof (devstat_t));
- dasd_dump_sense (cqr->dstat);
} else {
PRINT_ERR ("no memory for dtstat\n");
}
/* errorprocessing */
- if (cqr->retries < DASD_MAX_RETRIES) {
- dasd_debug (0x44485f72); /* DH_r */
atomic_set (&cqr->status, CQR_STATUS_ERROR);
- } else {
- dasd_debug (0x44485f6e); /* DH_f */
- atomic_set (&cqr->status, CQR_STATUS_FAILED);
- }
-
}
if (done_fast_io == 0)
atomic_clear_mask (DASD_CHANQ_BUSY,
@@ -1050,16 +1044,17 @@
queue.flags);
if (cqr->flags & DASD_DO_IO_SLEEP) {
- dasd_debug (0x44485f77); /* DH_w */
+ dasd_debug (0xc4c8a6a4); /* DHwu */
dasd_wakeup ();
} else if (! (cqr->options & DOIO_WAIT_FOR_INTERRUPT) ){
- dasd_debug (0x44485f73); /* DH_s */
+ dasd_debug (0xc4c8a293); /* DHsl */
atomic_inc (&chanq_tasks);
schedule_bh (dasd_do_chanq);
} else {
+ dasd_debug (0x64686f6f); /* DH_g */
dasd_debug (cqr->flags); /* DH_g */
- dasd_debug (0x44485f6f); /* DH_g */
}
+ dasd_debug (0xc4c86d6d); /* DHwu */
}
static int
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)