vserver 1.9.3
[linux-2.6.git] / drivers / s390 / block / dasd_eckd.c
index e7afb42..56f471c 100644 (file)
@@ -7,7 +7,7 @@
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
  *
- * $Revision: 1.54 $
+ * $Revision: 1.61 $
  */
 
 #include <linux/config.h>
@@ -68,6 +68,10 @@ static struct ccw_device_id dasd_eckd_ids[] = {
        { CCW_DEVICE_DEVTYPE (0x3990, 0, 0x3380, 0), driver_info: 0x4},
        { CCW_DEVICE_DEVTYPE (0x2105, 0, 0x3380, 0), driver_info: 0x5},
        { CCW_DEVICE_DEVTYPE (0x9343, 0, 0x9345, 0), driver_info: 0x6},
+       { CCW_DEVICE_DEVTYPE (0x2107, 0, 0x3390, 0), driver_info: 0x7},
+       { CCW_DEVICE_DEVTYPE (0x2107, 0, 0x3380, 0), driver_info: 0x8},
+       { CCW_DEVICE_DEVTYPE (0x1750, 0, 0x3390, 0), driver_info: 0x9},
+       { CCW_DEVICE_DEVTYPE (0x1750, 0, 0x3380, 0), driver_info: 0xa},
        { /* end of list */ },
 };
 
@@ -274,9 +278,11 @@ define_extent(struct ccw1 * ccw, struct DE_eckd_data * data, int trk,
 
        data->attributes.mode = 0x3;    /* ECKD */
 
-       if (private->rdc_data.cu_type == 0x2105
+       if ((private->rdc_data.cu_type == 0x2105 ||
+            private->rdc_data.cu_type == 0x2107 ||
+            private->rdc_data.cu_type == 0x1750)
            && !(private->uses_cdl && trk < 2))
-               data->ga_extended |= 0x40;
+               data->ga_extended |= 0x40; /* Regular Data Format Mode */
 
        geo.cyl = private->rdc_data.no_cyl;
        geo.head = private->rdc_data.trk_per_cyl;
@@ -499,11 +505,13 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
                        "sizes of configuration data mismatch"
                        "%d (read) vs %ld (expected)",
                        conf_len, sizeof (struct dasd_eckd_confdata));
+
+               kfree(conf_data); /* allocated by read_conf_data() */
                return 0;       /* no errror */
        }
        memcpy(&private->conf_data, conf_data,
               sizeof (struct dasd_eckd_confdata));
-
+       kfree(conf_data); /* allocated by read_conf_data() */
        return 0;
 }
 
@@ -903,6 +911,8 @@ dasd_eckd_examine_error(struct dasd_ccw_req * cqr, struct irb * irb)
        switch (cdev->id.cu_type) {
        case 0x3990:
        case 0x2105:
+       case 0x2107:
+       case 0x1750:
                return dasd_3990_erp_examine(cqr, irb);
        case 0x9343:
                return dasd_9343_erp_examine(cqr, irb);
@@ -923,6 +933,8 @@ dasd_eckd_erp_action(struct dasd_ccw_req * cqr)
        switch (cdev->id.cu_type) {
        case 0x3990:
        case 0x2105:
+       case 0x2107:
+       case 0x1750:
                return dasd_3990_erp_action;
        case 0x9343:
                /* Return dasd_9343_erp_action; */
@@ -983,8 +995,8 @@ dasd_eckd_build_cp(struct dasd_device * device, struct request *req)
                                return ERR_PTR(-EINVAL);
                        count += bv->bv_len >> (device->s2b_shift + 9);
 #if defined(CONFIG_ARCH_S390X)
-                       cidaw += idal_nr_words(page_address(bv->bv_page) +
-                                              bv->bv_offset, bv->bv_len);
+                       if (idal_is_needed (page_address(bv->bv_page), bv->bv_len))
+                               cidaw += bv->bv_len >> (device->s2b_shift + 9);
 #endif
                }
        }
@@ -1070,7 +1082,7 @@ dasd_eckd_build_cp(struct dasd_device * device, struct request *req)
        cqr->device = device;
        cqr->expires = 5 * 60 * HZ;     /* 5 minutes */
        cqr->lpm = LPM_ANYPATH;
-       cqr->retries = 2;
+       cqr->retries = 256;
        cqr->buildclk = get_clock();
        cqr->status = DASD_CQR_FILLED;
        return cqr;
@@ -1289,7 +1301,7 @@ dasd_eckd_performance(struct block_device *bdev, int no, long args)
                /* Prepare for Read Subsystem Data */
                prssdp = (struct dasd_psf_prssd_data *) cqr->data;
                stats = (struct dasd_rssd_perf_stats_t *) (prssdp + 1);
-               rc = copy_to_user((long *) args, (long *) stats,
+               rc = copy_to_user((long __user *) args, (long *) stats,
                                  sizeof(struct dasd_rssd_perf_stats_t));
        }
        dasd_sfree_request(cqr, cqr->device);
@@ -1319,10 +1331,10 @@ dasd_eckd_get_attrib (struct block_device *bdev, int no, long args)
 
         private = (struct dasd_eckd_private *) device->private;
         attrib = private->attrib;
-       
-        rc = copy_to_user((long *) args, (long *) &attrib,
+
+        rc = copy_to_user((long __user *) args, (long *) &attrib,
                          sizeof (struct attrib_data_t));
-       
+
        return rc;
 }
 
@@ -1346,7 +1358,7 @@ dasd_eckd_set_attrib(struct block_device *bdev, int no, long args)
        if (device == NULL)
                return -ENODEV;
 
-       if (copy_from_user(&attrib, (void *) args,
+       if (copy_from_user(&attrib, (void __user *) args,
                           sizeof (struct attrib_data_t))) {
                return -EFAULT;
        }