patch-2.2.15 linux/drivers/s390/block/mdisk.c
Next file: linux/drivers/s390/block/mdisk.h
Previous file: linux/drivers/s390/block/dasd_types.h
Back to the patch index
Back to the overall index
- Lines: 214
- Date:
Fri Apr 21 12:46:24 2000
- Orig file:
v2.2.14/drivers/s390/block/mdisk.c
- Orig date:
Tue Jan 4 21:18:53 2000
diff -u --new-file --recursive --exclude-from ../../exclude v2.2.14/drivers/s390/block/mdisk.c linux/drivers/s390/block/mdisk.c
@@ -3,7 +3,7 @@
* VM minidisk device driver.
*
* S390 version
- * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ * Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
* Author(s): Hartmut Penner (hp@de.ibm.com)
*/
@@ -37,7 +37,7 @@
#include <asm/io.h> /* virt_to_phys */
/* Added statement HSM 12/03/99 */
-#include "../../../arch/s390/kernel/irq.h"
+#include <asm/irq.h>
#define MAJOR_NR MDISK_MAJOR /* force definitions on in blk.h */
@@ -125,6 +125,7 @@
vdev = size = offset = 0;
if (!isxdigit(*cur)) goto syntax_error;
vdev = simple_strtoul(cur,&cur,16);
+ if (*cur != 0 && *cur != ',') {
if (*cur++ != ':') goto syntax_error;
if (!isxdigit(*cur)) goto syntax_error;
size = simple_strtoul(cur,&cur,16);
@@ -139,6 +140,7 @@
}
}
if (*cur != ',' && *cur != 0) goto syntax_error;
+ }
if (*cur == ',') cur++;
if (i >= MDISK_DEVS) {
printk(KERN_WARNING "mnd: too many devices\n");
@@ -159,6 +161,8 @@
return;
}
+
+
/*
* Open and close
*/
@@ -298,6 +302,101 @@
}
/*
+ * The device characteristics function
+ */
+
+static __inline__ int
+dia210(void* devchar)
+{
+ int rc;
+
+ devchar = (void*) virt_to_phys(devchar);
+
+ asm volatile (" lr 2,%1\n"
+ " .long 0x83200210\n"
+ " ipm %0\n"
+ " srl %0,28"
+ : "=d" (rc)
+ : "d" (devchar)
+ : "2" );
+ return rc;
+}
+/*
+ * read the label of a minidisk and extract its characteristics
+ */
+
+static __inline__ int
+mdisk_read_label (mdisk_Dev *dev, int i)
+{
+ static mdisk_dev_char_t devchar;
+ static long label[1024];
+ int block, b;
+ int rc;
+ mdisk_bio_t *bio;
+
+ devchar.dev_nr = dev -> vdev;
+ devchar.rdc_len = sizeof(mdisk_dev_char_t);
+
+ if (dia210(&devchar) == 0) {
+ if (devchar.vdev_class == DEV_CLASS_FBA) {
+ block = 2;
+ }
+ else {
+ block = 3;
+ }
+ bio = dev->bio;
+ rc = mdisk_term_io(dev);
+ for (b=512;b<4097;b=b*2) {
+ rc = mdisk_init_io(dev, b, 0, 64);
+ if (rc > 4) {
+ continue;
+ }
+ memset(&bio[0], 0, sizeof(mdisk_bio_t));
+ bio[0].type = MDISK_READ_REQ;
+ bio[0].block_number = block;
+ bio[0].buffer = virt_to_phys(&label);
+ dev->nr_bhs = 1;
+ if (mdisk_rw_io_clustered(dev,
+ &bio[0],
+ 1,
+ (unsigned long) dev,
+ MDISK_SYNC)
+ == 0 ) {
+ if (label[0] != 0xc3d4e2f1) { /* CMS1 */
+ printk ( KERN_WARNING "mnd: %4lX "
+ "is not CMS format\n",
+ mdisk_setup_data.vdev[i]);
+ rc = mdisk_term_io(dev);
+ return 1;
+ }
+ if (label[13] == 0) {
+ printk ( KERN_WARNING "mnd: %4lX "
+ "is not reserved\n",
+ mdisk_setup_data.vdev[i]);
+ rc = mdisk_term_io(dev);
+ return 2;
+ }
+ mdisk_setup_data.size[i] =
+ (label[7] - 1 - label[13]) *
+ (label[3] >> 9) >> 1;
+ mdisk_setup_data.blksize[i] = label[3];
+ mdisk_setup_data.offset[i] = label[13] + 1;
+ rc = mdisk_term_io(dev);
+ return rc;
+ }
+ rc = mdisk_term_io(dev);
+ }
+ printk ( KERN_WARNING "mnd: Cannot read label of %4lX "
+ "- is it formatted?\n",
+ mdisk_setup_data.vdev[i]);
+ return 3;
+ }
+ return 4;
+}
+
+
+
+/*
* Init of minidisk device
*/
@@ -365,11 +464,11 @@
iob->bio_list = virt_to_phys(bio_array);
rc = dia250(iob,RW_BIO);
- rc = (rc == 8) ? 0 : rc;
return rc;
}
+
/*
* this handles a clustered request in success case
* all buffers are detach and marked uptodate to the kernel
@@ -507,7 +606,7 @@
#else
MDISK_ASYNC
#endif
- )) != 0 ) {
+ )) > 8 ) {
printk(KERN_WARNING "mnd%c: %s request failed rc %d"
" sector %ld nr_sectors %ld \n",
DEVICE_NR(CURRENT_DEV),
@@ -524,6 +623,9 @@
#ifdef CONFIG_MDISK_SYNC
mdisk_end_request(dev->nr_bhs);
#else
+ if (rc == 0)
+ mdisk_end_request(dev->nr_bhs);
+ else
return;
#endif
}
@@ -627,8 +729,7 @@
max_sectors[MAJOR_NR] = mdisk_maxsectors;
for (i=0;i<MDISK_DEVS;i++) {
- mdisk_sizes[i] = mdisk_setup_data.size[i];
- if (mdisk_sizes[i] == 0) {
+ if (mdisk_setup_data.vdev[i] == 0) {
continue;
}
/* Added block HSM 12/03/99 */
@@ -636,7 +737,7 @@
mdisk_handler, 0, "mnd",
&(mdisk_devices[i].dev_status)) ){
printk ( KERN_WARNING "mnd: Cannot acquire I/O irq of"
- " %4X for paranoia reasons, skipping\n",
+ " %4lX for paranoia reasons, skipping\n",
mdisk_setup_data.vdev[i]);
continue;
}
@@ -647,6 +748,9 @@
dev->bio=mdisk_bio[i];
dev->iob=&mdisk_iob[i];
dev->vdev = mdisk_setup_data.vdev[i];
+
+ if ( mdisk_setup_data.size[i] == 0 )
+ rc = mdisk_read_label(dev, i);
dev->size = mdisk_setup_data.size[i] * 2; /* buffer 512 b */
dev->blksize = mdisk_setup_data.blksize[i];
dev->tqueue.routine = do_mdisk_bh;
@@ -658,6 +762,7 @@
dev->blkmult==4?2:
dev->blkmult==8?3:-1;
+ mdisk_sizes[i] = mdisk_setup_data.size[i];
mdisk_blksizes[i] = mdisk_setup_data.blksize[i];
mdisk_hardsects[i] = mdisk_setup_data.blksize[i];
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)