|
@@ -1227,19 +1227,14 @@ dasd_eckd_fill_info(struct dasd_device * device,
|
|
* (see dasd_eckd_reserve) device.
|
|
* (see dasd_eckd_reserve) device.
|
|
*/
|
|
*/
|
|
static int
|
|
static int
|
|
-dasd_eckd_release(struct block_device *bdev, int no, long args)
|
|
|
|
|
|
+dasd_eckd_release(struct dasd_device *device)
|
|
{
|
|
{
|
|
- struct dasd_device *device;
|
|
|
|
struct dasd_ccw_req *cqr;
|
|
struct dasd_ccw_req *cqr;
|
|
int rc;
|
|
int rc;
|
|
|
|
|
|
if (!capable(CAP_SYS_ADMIN))
|
|
if (!capable(CAP_SYS_ADMIN))
|
|
return -EACCES;
|
|
return -EACCES;
|
|
|
|
|
|
- device = bdev->bd_disk->private_data;
|
|
|
|
- if (device == NULL)
|
|
|
|
- return -ENODEV;
|
|
|
|
-
|
|
|
|
cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
|
|
cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
|
|
1, 32, device);
|
|
1, 32, device);
|
|
if (IS_ERR(cqr)) {
|
|
if (IS_ERR(cqr)) {
|
|
@@ -1272,19 +1267,14 @@ dasd_eckd_release(struct block_device *bdev, int no, long args)
|
|
* the interrupt is outstanding for a certain time.
|
|
* the interrupt is outstanding for a certain time.
|
|
*/
|
|
*/
|
|
static int
|
|
static int
|
|
-dasd_eckd_reserve(struct block_device *bdev, int no, long args)
|
|
|
|
|
|
+dasd_eckd_reserve(struct dasd_device *device)
|
|
{
|
|
{
|
|
- struct dasd_device *device;
|
|
|
|
struct dasd_ccw_req *cqr;
|
|
struct dasd_ccw_req *cqr;
|
|
int rc;
|
|
int rc;
|
|
|
|
|
|
if (!capable(CAP_SYS_ADMIN))
|
|
if (!capable(CAP_SYS_ADMIN))
|
|
return -EACCES;
|
|
return -EACCES;
|
|
|
|
|
|
- device = bdev->bd_disk->private_data;
|
|
|
|
- if (device == NULL)
|
|
|
|
- return -ENODEV;
|
|
|
|
-
|
|
|
|
cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
|
|
cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
|
|
1, 32, device);
|
|
1, 32, device);
|
|
if (IS_ERR(cqr)) {
|
|
if (IS_ERR(cqr)) {
|
|
@@ -1316,19 +1306,14 @@ dasd_eckd_reserve(struct block_device *bdev, int no, long args)
|
|
* (unconditional reserve)
|
|
* (unconditional reserve)
|
|
*/
|
|
*/
|
|
static int
|
|
static int
|
|
-dasd_eckd_steal_lock(struct block_device *bdev, int no, long args)
|
|
|
|
|
|
+dasd_eckd_steal_lock(struct dasd_device *device)
|
|
{
|
|
{
|
|
- struct dasd_device *device;
|
|
|
|
struct dasd_ccw_req *cqr;
|
|
struct dasd_ccw_req *cqr;
|
|
int rc;
|
|
int rc;
|
|
|
|
|
|
if (!capable(CAP_SYS_ADMIN))
|
|
if (!capable(CAP_SYS_ADMIN))
|
|
return -EACCES;
|
|
return -EACCES;
|
|
|
|
|
|
- device = bdev->bd_disk->private_data;
|
|
|
|
- if (device == NULL)
|
|
|
|
- return -ENODEV;
|
|
|
|
-
|
|
|
|
cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
|
|
cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
|
|
1, 32, device);
|
|
1, 32, device);
|
|
if (IS_ERR(cqr)) {
|
|
if (IS_ERR(cqr)) {
|
|
@@ -1358,19 +1343,14 @@ dasd_eckd_steal_lock(struct block_device *bdev, int no, long args)
|
|
* Read performance statistics
|
|
* Read performance statistics
|
|
*/
|
|
*/
|
|
static int
|
|
static int
|
|
-dasd_eckd_performance(struct block_device *bdev, int no, long args)
|
|
|
|
|
|
+dasd_eckd_performance(struct dasd_device *device, void __user *argp)
|
|
{
|
|
{
|
|
- struct dasd_device *device;
|
|
|
|
struct dasd_psf_prssd_data *prssdp;
|
|
struct dasd_psf_prssd_data *prssdp;
|
|
struct dasd_rssd_perf_stats_t *stats;
|
|
struct dasd_rssd_perf_stats_t *stats;
|
|
struct dasd_ccw_req *cqr;
|
|
struct dasd_ccw_req *cqr;
|
|
struct ccw1 *ccw;
|
|
struct ccw1 *ccw;
|
|
int rc;
|
|
int rc;
|
|
|
|
|
|
- device = bdev->bd_disk->private_data;
|
|
|
|
- if (device == NULL)
|
|
|
|
- return -ENODEV;
|
|
|
|
-
|
|
|
|
cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
|
|
cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
|
|
1 /* PSF */ + 1 /* RSSD */ ,
|
|
1 /* PSF */ + 1 /* RSSD */ ,
|
|
(sizeof (struct dasd_psf_prssd_data) +
|
|
(sizeof (struct dasd_psf_prssd_data) +
|
|
@@ -1414,8 +1394,9 @@ dasd_eckd_performance(struct block_device *bdev, int no, long args)
|
|
/* Prepare for Read Subsystem Data */
|
|
/* Prepare for Read Subsystem Data */
|
|
prssdp = (struct dasd_psf_prssd_data *) cqr->data;
|
|
prssdp = (struct dasd_psf_prssd_data *) cqr->data;
|
|
stats = (struct dasd_rssd_perf_stats_t *) (prssdp + 1);
|
|
stats = (struct dasd_rssd_perf_stats_t *) (prssdp + 1);
|
|
- rc = copy_to_user((long __user *) args, (long *) stats,
|
|
|
|
- sizeof(struct dasd_rssd_perf_stats_t));
|
|
|
|
|
|
+ if (copy_to_user(argp, stats,
|
|
|
|
+ sizeof(struct dasd_rssd_perf_stats_t)))
|
|
|
|
+ rc = -EFAULT;
|
|
}
|
|
}
|
|
dasd_sfree_request(cqr, cqr->device);
|
|
dasd_sfree_request(cqr, cqr->device);
|
|
return rc;
|
|
return rc;
|
|
@@ -1426,27 +1407,22 @@ dasd_eckd_performance(struct block_device *bdev, int no, long args)
|
|
* Returnes the cache attributes used in Define Extend (DE).
|
|
* Returnes the cache attributes used in Define Extend (DE).
|
|
*/
|
|
*/
|
|
static int
|
|
static int
|
|
-dasd_eckd_get_attrib (struct block_device *bdev, int no, long args)
|
|
|
|
|
|
+dasd_eckd_get_attrib(struct dasd_device *device, void __user *argp)
|
|
{
|
|
{
|
|
- struct dasd_device *device;
|
|
|
|
- struct dasd_eckd_private *private;
|
|
|
|
- struct attrib_data_t attrib;
|
|
|
|
|
|
+ struct dasd_eckd_private *private =
|
|
|
|
+ (struct dasd_eckd_private *)device->private;
|
|
|
|
+ struct attrib_data_t attrib = private->attrib;
|
|
int rc;
|
|
int rc;
|
|
|
|
|
|
if (!capable(CAP_SYS_ADMIN))
|
|
if (!capable(CAP_SYS_ADMIN))
|
|
return -EACCES;
|
|
return -EACCES;
|
|
- if (!args)
|
|
|
|
|
|
+ if (!argp)
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
|
|
|
|
- device = bdev->bd_disk->private_data;
|
|
|
|
- if (device == NULL)
|
|
|
|
- return -ENODEV;
|
|
|
|
-
|
|
|
|
- private = (struct dasd_eckd_private *) device->private;
|
|
|
|
- attrib = private->attrib;
|
|
|
|
-
|
|
|
|
- rc = copy_to_user((long __user *) args, (long *) &attrib,
|
|
|
|
- sizeof (struct attrib_data_t));
|
|
|
|
|
|
+ rc = 0;
|
|
|
|
+ if (copy_to_user(argp, (long *) &attrib,
|
|
|
|
+ sizeof (struct attrib_data_t)))
|
|
|
|
+ rc = -EFAULT;
|
|
|
|
|
|
return rc;
|
|
return rc;
|
|
}
|
|
}
|
|
@@ -1456,26 +1432,19 @@ dasd_eckd_get_attrib (struct block_device *bdev, int no, long args)
|
|
* Stores the attributes for cache operation to be used in Define Extend (DE).
|
|
* Stores the attributes for cache operation to be used in Define Extend (DE).
|
|
*/
|
|
*/
|
|
static int
|
|
static int
|
|
-dasd_eckd_set_attrib(struct block_device *bdev, int no, long args)
|
|
|
|
|
|
+dasd_eckd_set_attrib(struct dasd_device *device, void __user *argp)
|
|
{
|
|
{
|
|
- struct dasd_device *device;
|
|
|
|
- struct dasd_eckd_private *private;
|
|
|
|
|
|
+ struct dasd_eckd_private *private =
|
|
|
|
+ (struct dasd_eckd_private *)device->private;
|
|
struct attrib_data_t attrib;
|
|
struct attrib_data_t attrib;
|
|
|
|
|
|
if (!capable(CAP_SYS_ADMIN))
|
|
if (!capable(CAP_SYS_ADMIN))
|
|
return -EACCES;
|
|
return -EACCES;
|
|
- if (!args)
|
|
|
|
|
|
+ if (!argp)
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
|
|
|
|
- device = bdev->bd_disk->private_data;
|
|
|
|
- if (device == NULL)
|
|
|
|
- return -ENODEV;
|
|
|
|
-
|
|
|
|
- if (copy_from_user(&attrib, (void __user *) args,
|
|
|
|
- sizeof (struct attrib_data_t))) {
|
|
|
|
|
|
+ if (copy_from_user(&attrib, argp, sizeof(struct attrib_data_t)))
|
|
return -EFAULT;
|
|
return -EFAULT;
|
|
- }
|
|
|
|
- private = (struct dasd_eckd_private *) device->private;
|
|
|
|
private->attrib = attrib;
|
|
private->attrib = attrib;
|
|
|
|
|
|
DEV_MESSAGE(KERN_INFO, device,
|
|
DEV_MESSAGE(KERN_INFO, device,
|
|
@@ -1484,6 +1453,27 @@ dasd_eckd_set_attrib(struct block_device *bdev, int no, long args)
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static int
|
|
|
|
+dasd_eckd_ioctl(struct dasd_device *device, unsigned int cmd, void __user *argp)
|
|
|
|
+{
|
|
|
|
+ switch (cmd) {
|
|
|
|
+ case BIODASDGATTR:
|
|
|
|
+ return dasd_eckd_get_attrib(device, argp);
|
|
|
|
+ case BIODASDSATTR:
|
|
|
|
+ return dasd_eckd_set_attrib(device, argp);
|
|
|
|
+ case BIODASDPSRD:
|
|
|
|
+ return dasd_eckd_performance(device, argp);
|
|
|
|
+ case BIODASDRLSE:
|
|
|
|
+ return dasd_eckd_release(device);
|
|
|
|
+ case BIODASDRSRV:
|
|
|
|
+ return dasd_eckd_reserve(device);
|
|
|
|
+ case BIODASDSLCK:
|
|
|
|
+ return dasd_eckd_steal_lock(device);
|
|
|
|
+ default:
|
|
|
|
+ return -ENOIOCTLCMD;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* Print sense data and related channel program.
|
|
* Print sense data and related channel program.
|
|
* Parts are printed because printk buffer is only 1024 bytes.
|
|
* Parts are printed because printk buffer is only 1024 bytes.
|
|
@@ -1642,6 +1632,7 @@ static struct dasd_discipline dasd_eckd_discipline = {
|
|
.free_cp = dasd_eckd_free_cp,
|
|
.free_cp = dasd_eckd_free_cp,
|
|
.dump_sense = dasd_eckd_dump_sense,
|
|
.dump_sense = dasd_eckd_dump_sense,
|
|
.fill_info = dasd_eckd_fill_info,
|
|
.fill_info = dasd_eckd_fill_info,
|
|
|
|
+ .ioctl = dasd_eckd_ioctl,
|
|
};
|
|
};
|
|
|
|
|
|
static int __init
|
|
static int __init
|
|
@@ -1649,59 +1640,18 @@ dasd_eckd_init(void)
|
|
{
|
|
{
|
|
int ret;
|
|
int ret;
|
|
|
|
|
|
- dasd_ioctl_no_register(THIS_MODULE, BIODASDGATTR,
|
|
|
|
- dasd_eckd_get_attrib);
|
|
|
|
- dasd_ioctl_no_register(THIS_MODULE, BIODASDSATTR,
|
|
|
|
- dasd_eckd_set_attrib);
|
|
|
|
- dasd_ioctl_no_register(THIS_MODULE, BIODASDPSRD,
|
|
|
|
- dasd_eckd_performance);
|
|
|
|
- dasd_ioctl_no_register(THIS_MODULE, BIODASDRLSE,
|
|
|
|
- dasd_eckd_release);
|
|
|
|
- dasd_ioctl_no_register(THIS_MODULE, BIODASDRSRV,
|
|
|
|
- dasd_eckd_reserve);
|
|
|
|
- dasd_ioctl_no_register(THIS_MODULE, BIODASDSLCK,
|
|
|
|
- dasd_eckd_steal_lock);
|
|
|
|
-
|
|
|
|
ASCEBC(dasd_eckd_discipline.ebcname, 4);
|
|
ASCEBC(dasd_eckd_discipline.ebcname, 4);
|
|
|
|
|
|
ret = ccw_driver_register(&dasd_eckd_driver);
|
|
ret = ccw_driver_register(&dasd_eckd_driver);
|
|
- if (ret) {
|
|
|
|
- dasd_ioctl_no_unregister(THIS_MODULE, BIODASDGATTR,
|
|
|
|
- dasd_eckd_get_attrib);
|
|
|
|
- dasd_ioctl_no_unregister(THIS_MODULE, BIODASDSATTR,
|
|
|
|
- dasd_eckd_set_attrib);
|
|
|
|
- dasd_ioctl_no_unregister(THIS_MODULE, BIODASDPSRD,
|
|
|
|
- dasd_eckd_performance);
|
|
|
|
- dasd_ioctl_no_unregister(THIS_MODULE, BIODASDRLSE,
|
|
|
|
- dasd_eckd_release);
|
|
|
|
- dasd_ioctl_no_unregister(THIS_MODULE, BIODASDRSRV,
|
|
|
|
- dasd_eckd_reserve);
|
|
|
|
- dasd_ioctl_no_unregister(THIS_MODULE, BIODASDSLCK,
|
|
|
|
- dasd_eckd_steal_lock);
|
|
|
|
- return ret;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- dasd_generic_auto_online(&dasd_eckd_driver);
|
|
|
|
- return 0;
|
|
|
|
|
|
+ if (!ret)
|
|
|
|
+ dasd_generic_auto_online(&dasd_eckd_driver);
|
|
|
|
+ return ret;
|
|
}
|
|
}
|
|
|
|
|
|
static void __exit
|
|
static void __exit
|
|
dasd_eckd_cleanup(void)
|
|
dasd_eckd_cleanup(void)
|
|
{
|
|
{
|
|
ccw_driver_unregister(&dasd_eckd_driver);
|
|
ccw_driver_unregister(&dasd_eckd_driver);
|
|
-
|
|
|
|
- dasd_ioctl_no_unregister(THIS_MODULE, BIODASDGATTR,
|
|
|
|
- dasd_eckd_get_attrib);
|
|
|
|
- dasd_ioctl_no_unregister(THIS_MODULE, BIODASDSATTR,
|
|
|
|
- dasd_eckd_set_attrib);
|
|
|
|
- dasd_ioctl_no_unregister(THIS_MODULE, BIODASDPSRD,
|
|
|
|
- dasd_eckd_performance);
|
|
|
|
- dasd_ioctl_no_unregister(THIS_MODULE, BIODASDRLSE,
|
|
|
|
- dasd_eckd_release);
|
|
|
|
- dasd_ioctl_no_unregister(THIS_MODULE, BIODASDRSRV,
|
|
|
|
- dasd_eckd_reserve);
|
|
|
|
- dasd_ioctl_no_unregister(THIS_MODULE, BIODASDSLCK,
|
|
|
|
- dasd_eckd_steal_lock);
|
|
|
|
}
|
|
}
|
|
|
|
|
|
module_init(dasd_eckd_init);
|
|
module_init(dasd_eckd_init);
|