patch-2.4.4 linux/drivers/s390/block/dasd_diag.c
Next file: linux/drivers/s390/block/dasd_eckd.c
Previous file: linux/drivers/s390/block/dasd_9343_erp.h
Back to the patch index
Back to the overall index
- Lines: 177
- Date:
Wed Apr 11 19:02:28 2001
- Orig file:
v2.4.3/linux/drivers/s390/block/dasd_diag.c
- Orig date:
Tue Feb 13 14:13:44 2001
diff -u --recursive --new-file v2.4.3/linux/drivers/s390/block/dasd_diag.c linux/drivers/s390/block/dasd_diag.c
@@ -10,6 +10,8 @@
* 07/13/00 Added fixup sections for diagnoses ans saved some registers
* 07/14/00 fixed constraints in newly generated inline asm
* 10/05/00 adapted to 'new' DASD driver
+ * fixed return codes of dia250()
+ * fixed partition handling and HDIO_GETGEO
*/
#include <linux/stddef.h>
@@ -73,10 +75,11 @@
static __inline__ int
dia250 (void *iob, int cmd)
{
- int rc;
-
- __asm__ __volatile__ (" lr 1,%1\n"
- " diag 1,%2,0x250\n"
+ __asm__ __volatile__ (" lr 0,%1\n"
+ " diag 0,%0,0x250\n"
+ "0: ipm %0\n"
+ " srl %0,28\n"
+ " or %0,1\n"
"1:\n"
".section .fixup,\"ax\"\n"
"2: lhi %0,3\n"
@@ -87,12 +90,12 @@
".previous\n"
".section __ex_table,\"a\"\n"
" .align 4\n"
- " .long 1b,2b\n"
- ".previous\n"
- :"=d" (rc)
- :"d" ((void *) __pa (iob)), "0" (cmd)
- :"1");
- return rc;
+ " .long 0b,2b\n"
+ ".previous\n"
+ : "+d" (cmd)
+ : "d" ((void *) __pa (iob))
+ : "0", "1", "cc" );
+ return cmd;
}
static __inline__ int
@@ -112,7 +115,7 @@
rc = dia250 (iib, INIT_BIO);
- return rc;
+ return rc&3;
}
static __inline__ int
@@ -125,7 +128,7 @@
memset (iib, 0, sizeof (diag_init_io_t));
iib->dev_nr = device->devinfo.devno;
rc = dia250 (iib, TERM_BIO);
- return rc;
+ return rc&3;
}
int
@@ -153,7 +156,12 @@
check_then_set (&cqr->status,
CQR_STATUS_QUEUED,
CQR_STATUS_ERROR);
- } else {
+ } else if (rc == 0 ) {
+ check_then_set(&cqr->status,
+ CQR_STATUS_QUEUED,
+ CQR_STATUS_DONE);
+ dasd_schedule_bh(device);
+ } else {
if (cqr->expires) {
cqr->expires += cqr->startclk;
}
@@ -250,13 +258,14 @@
"Null device pointer passed to characteristics checker\n");
return -ENODEV;
}
- if (device->private == NULL) {
- device->private = kmalloc (sizeof (dasd_diag_private_t), GFP_KERNEL);
- if (device->private == NULL) {
- printk (KERN_WARNING PRINTK_HEADER
- "memory allocation failed for private data\n");
- return -ENOMEM;
- }
+ if (device->private != NULL) {
+ kfree (device->private);
+ }
+ device->private = kmalloc (sizeof (dasd_diag_private_t), GFP_KERNEL);
+ if (device->private == NULL) {
+ printk (KERN_WARNING PRINTK_HEADER
+ "memory allocation failed for private data\n");
+ return -ENOMEM;
}
private = (dasd_diag_private_t *) device->private;
rdc_data = (void *) &(private->rdc_data);
@@ -304,7 +313,7 @@
if (cqr == NULL) {
printk (KERN_WARNING PRINTK_HEADER
"No memory to allocate initialization request\n");
- free_page(private->label);
+ free_page((long)private->label);
kfree(private);
device->private = NULL;
return -ENOMEM;
@@ -319,7 +328,7 @@
memset (iob, 0, sizeof (diag_rw_io_t));
iob->dev_nr = rdc_data->dev_nr;
iob->block_count = 1;
- iob->interrupt_params = cqr;
+ iob->interrupt_params = (u32)cqr;
iob->bio_list = __pa (bio);
rc = dia250 (iob, RW_BIO);
if (rc == 0) {
@@ -354,19 +363,26 @@
static int
dasd_diag_do_analysis (struct dasd_device_t *device)
{
- int sb;
dasd_diag_private_t *private = (dasd_diag_private_t *) device->private;
long *label = private->label;
/* real size of the volume */
device->sizes.blocks = label[7];
+ if (private->rdc_data.vdev_class == DEV_CLASS_FBA) {
+ device->sizes.pt_block = 1;
+ } else if (private->rdc_data.vdev_class == DEV_CLASS_ECKD ||
+ private->rdc_data.vdev_class == DEV_CLASS_CKD) {
+ device->sizes.pt_block = 2;
+ } else {
+ return -EINVAL;
+ }
printk (KERN_INFO PRINTK_HEADER
"/dev/%s (%04X): capacity (%dkB blks): %ldkB\n",
device->name, device->devinfo.devno,
(device->sizes.bp_block >> 10),
(device->sizes.blocks << device->sizes.s2b_shift) >> 1);
- free_page(private->label);
+ free_page((long)private->label);
return 0;
}
@@ -393,14 +409,6 @@
geo->cylinders = cyls;
geo->heads = 16;
geo->sectors = 128 >> device->sizes.s2b_shift;
- if (private->rdc_data.vdev_class == DEV_CLASS_FBA) {
- geo->start = 1;
- } else if (private->rdc_data.vdev_class == DEV_CLASS_ECKD ||
- private->rdc_data.vdev_class == DEV_CLASS_CKD) {
- geo->start = 2;
- } else {
- return -EINVAL;
- }
return rc;
}
@@ -482,7 +490,7 @@
}
}
rw_cp->device = device;
- rw_cp->expires = 5 * 0xf424000; /* 5 seconds */
+ rw_cp->expires = 50 * TOD_SEC; /* 50 seconds */
rw_cp->req = req;
check_then_set (&rw_cp->status, CQR_STATUS_EMPTY, CQR_STATUS_FILLED);
return rw_cp;
@@ -507,6 +515,7 @@
{
name:"DIAG",
ebcname:"DIAG",
+ max_blocks:PAGE_SIZE/sizeof(diag_bio_t),
check_characteristics:dasd_diag_check_characteristics,
do_analysis:dasd_diag_do_analysis,
fill_geometry:dasd_diag_fill_geometry,
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)