aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/s390/block/dasd_eckd.c142
-rw-r--r--drivers/s390/block/dasd_int.h1
-rw-r--r--drivers/s390/block/dasd_ioctl.c9
3 files changed, 55 insertions, 97 deletions
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index 822e2a265578..ee09ef33d08d 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -1227,19 +1227,14 @@ dasd_eckd_fill_info(struct dasd_device * device,
1227 * (see dasd_eckd_reserve) device. 1227 * (see dasd_eckd_reserve) device.
1228 */ 1228 */
1229static int 1229static int
1230dasd_eckd_release(struct block_device *bdev, int no, long args) 1230dasd_eckd_release(struct dasd_device *device)
1231{ 1231{
1232 struct dasd_device *device;
1233 struct dasd_ccw_req *cqr; 1232 struct dasd_ccw_req *cqr;
1234 int rc; 1233 int rc;
1235 1234
1236 if (!capable(CAP_SYS_ADMIN)) 1235 if (!capable(CAP_SYS_ADMIN))
1237 return -EACCES; 1236 return -EACCES;
1238 1237
1239 device = bdev->bd_disk->private_data;
1240 if (device == NULL)
1241 return -ENODEV;
1242
1243 cqr = dasd_smalloc_request(dasd_eckd_discipline.name, 1238 cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
1244 1, 32, device); 1239 1, 32, device);
1245 if (IS_ERR(cqr)) { 1240 if (IS_ERR(cqr)) {
@@ -1272,19 +1267,14 @@ dasd_eckd_release(struct block_device *bdev, int no, long args)
1272 * the interrupt is outstanding for a certain time. 1267 * the interrupt is outstanding for a certain time.
1273 */ 1268 */
1274static int 1269static int
1275dasd_eckd_reserve(struct block_device *bdev, int no, long args) 1270dasd_eckd_reserve(struct dasd_device *device)
1276{ 1271{
1277 struct dasd_device *device;
1278 struct dasd_ccw_req *cqr; 1272 struct dasd_ccw_req *cqr;
1279 int rc; 1273 int rc;
1280 1274
1281 if (!capable(CAP_SYS_ADMIN)) 1275 if (!capable(CAP_SYS_ADMIN))
1282 return -EACCES; 1276 return -EACCES;
1283 1277
1284 device = bdev->bd_disk->private_data;
1285 if (device == NULL)
1286 return -ENODEV;
1287
1288 cqr = dasd_smalloc_request(dasd_eckd_discipline.name, 1278 cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
1289 1, 32, device); 1279 1, 32, device);
1290 if (IS_ERR(cqr)) { 1280 if (IS_ERR(cqr)) {
@@ -1316,19 +1306,14 @@ dasd_eckd_reserve(struct block_device *bdev, int no, long args)
1316 * (unconditional reserve) 1306 * (unconditional reserve)
1317 */ 1307 */
1318static int 1308static int
1319dasd_eckd_steal_lock(struct block_device *bdev, int no, long args) 1309dasd_eckd_steal_lock(struct dasd_device *device)
1320{ 1310{
1321 struct dasd_device *device;
1322 struct dasd_ccw_req *cqr; 1311 struct dasd_ccw_req *cqr;
1323 int rc; 1312 int rc;
1324 1313
1325 if (!capable(CAP_SYS_ADMIN)) 1314 if (!capable(CAP_SYS_ADMIN))
1326 return -EACCES; 1315 return -EACCES;
1327 1316
1328 device = bdev->bd_disk->private_data;
1329 if (device == NULL)
1330 return -ENODEV;
1331
1332 cqr = dasd_smalloc_request(dasd_eckd_discipline.name, 1317 cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
1333 1, 32, device); 1318 1, 32, device);
1334 if (IS_ERR(cqr)) { 1319 if (IS_ERR(cqr)) {
@@ -1358,19 +1343,14 @@ dasd_eckd_steal_lock(struct block_device *bdev, int no, long args)
1358 * Read performance statistics 1343 * Read performance statistics
1359 */ 1344 */
1360static int 1345static int
1361dasd_eckd_performance(struct block_device *bdev, int no, long args) 1346dasd_eckd_performance(struct dasd_device *device, void __user *argp)
1362{ 1347{
1363 struct dasd_device *device;
1364 struct dasd_psf_prssd_data *prssdp; 1348 struct dasd_psf_prssd_data *prssdp;
1365 struct dasd_rssd_perf_stats_t *stats; 1349 struct dasd_rssd_perf_stats_t *stats;
1366 struct dasd_ccw_req *cqr; 1350 struct dasd_ccw_req *cqr;
1367 struct ccw1 *ccw; 1351 struct ccw1 *ccw;
1368 int rc; 1352 int rc;
1369 1353
1370 device = bdev->bd_disk->private_data;
1371 if (device == NULL)
1372 return -ENODEV;
1373
1374 cqr = dasd_smalloc_request(dasd_eckd_discipline.name, 1354 cqr = dasd_smalloc_request(dasd_eckd_discipline.name,
1375 1 /* PSF */ + 1 /* RSSD */ , 1355 1 /* PSF */ + 1 /* RSSD */ ,
1376 (sizeof (struct dasd_psf_prssd_data) + 1356 (sizeof (struct dasd_psf_prssd_data) +
@@ -1414,8 +1394,9 @@ dasd_eckd_performance(struct block_device *bdev, int no, long args)
1414 /* Prepare for Read Subsystem Data */ 1394 /* Prepare for Read Subsystem Data */
1415 prssdp = (struct dasd_psf_prssd_data *) cqr->data; 1395 prssdp = (struct dasd_psf_prssd_data *) cqr->data;
1416 stats = (struct dasd_rssd_perf_stats_t *) (prssdp + 1); 1396 stats = (struct dasd_rssd_perf_stats_t *) (prssdp + 1);
1417 rc = copy_to_user((long __user *) args, (long *) stats, 1397 if (copy_to_user(argp, stats,
1418 sizeof(struct dasd_rssd_perf_stats_t)); 1398 sizeof(struct dasd_rssd_perf_stats_t)))
1399 rc = -EFAULT;
1419 } 1400 }
1420 dasd_sfree_request(cqr, cqr->device); 1401 dasd_sfree_request(cqr, cqr->device);
1421 return rc; 1402 return rc;
@@ -1426,27 +1407,22 @@ dasd_eckd_performance(struct block_device *bdev, int no, long args)
1426 * Returnes the cache attributes used in Define Extend (DE). 1407 * Returnes the cache attributes used in Define Extend (DE).
1427 */ 1408 */
1428static int 1409static int
1429dasd_eckd_get_attrib (struct block_device *bdev, int no, long args) 1410dasd_eckd_get_attrib(struct dasd_device *device, void __user *argp)
1430{ 1411{
1431 struct dasd_device *device; 1412 struct dasd_eckd_private *private =
1432 struct dasd_eckd_private *private; 1413 (struct dasd_eckd_private *)device->private;
1433 struct attrib_data_t attrib; 1414 struct attrib_data_t attrib = private->attrib;
1434 int rc; 1415 int rc;
1435 1416
1436 if (!capable(CAP_SYS_ADMIN)) 1417 if (!capable(CAP_SYS_ADMIN))
1437 return -EACCES; 1418 return -EACCES;
1438 if (!args) 1419 if (!argp)
1439 return -EINVAL; 1420 return -EINVAL;
1440 1421
1441 device = bdev->bd_disk->private_data; 1422 rc = 0;
1442 if (device == NULL) 1423 if (copy_to_user(argp, (long *) &attrib,
1443 return -ENODEV; 1424 sizeof (struct attrib_data_t)))
1444 1425 rc = -EFAULT;
1445 private = (struct dasd_eckd_private *) device->private;
1446 attrib = private->attrib;
1447
1448 rc = copy_to_user((long __user *) args, (long *) &attrib,
1449 sizeof (struct attrib_data_t));
1450 1426
1451 return rc; 1427 return rc;
1452} 1428}
@@ -1456,26 +1432,19 @@ dasd_eckd_get_attrib (struct block_device *bdev, int no, long args)
1456 * Stores the attributes for cache operation to be used in Define Extend (DE). 1432 * Stores the attributes for cache operation to be used in Define Extend (DE).
1457 */ 1433 */
1458static int 1434static int
1459dasd_eckd_set_attrib(struct block_device *bdev, int no, long args) 1435dasd_eckd_set_attrib(struct dasd_device *device, void __user *argp)
1460{ 1436{
1461 struct dasd_device *device; 1437 struct dasd_eckd_private *private =
1462 struct dasd_eckd_private *private; 1438 (struct dasd_eckd_private *)device->private;
1463 struct attrib_data_t attrib; 1439 struct attrib_data_t attrib;
1464 1440
1465 if (!capable(CAP_SYS_ADMIN)) 1441 if (!capable(CAP_SYS_ADMIN))
1466 return -EACCES; 1442 return -EACCES;
1467 if (!args) 1443 if (!argp)
1468 return -EINVAL; 1444 return -EINVAL;
1469 1445
1470 device = bdev->bd_disk->private_data; 1446 if (copy_from_user(&attrib, argp, sizeof(struct attrib_data_t)))
1471 if (device == NULL)
1472 return -ENODEV;
1473
1474 if (copy_from_user(&attrib, (void __user *) args,
1475 sizeof (struct attrib_data_t))) {
1476 return -EFAULT; 1447 return -EFAULT;
1477 }
1478 private = (struct dasd_eckd_private *) device->private;
1479 private->attrib = attrib; 1448 private->attrib = attrib;
1480 1449
1481 DEV_MESSAGE(KERN_INFO, device, 1450 DEV_MESSAGE(KERN_INFO, device,
@@ -1484,6 +1453,27 @@ dasd_eckd_set_attrib(struct block_device *bdev, int no, long args)
1484 return 0; 1453 return 0;
1485} 1454}
1486 1455
1456static int
1457dasd_eckd_ioctl(struct dasd_device *device, unsigned int cmd, void __user *argp)
1458{
1459 switch (cmd) {
1460 case BIODASDGATTR:
1461 return dasd_eckd_get_attrib(device, argp);
1462 case BIODASDSATTR:
1463 return dasd_eckd_set_attrib(device, argp);
1464 case BIODASDPSRD:
1465 return dasd_eckd_performance(device, argp);
1466 case BIODASDRLSE:
1467 return dasd_eckd_release(device);
1468 case BIODASDRSRV:
1469 return dasd_eckd_reserve(device);
1470 case BIODASDSLCK:
1471 return dasd_eckd_steal_lock(device);
1472 default:
1473 return -ENOIOCTLCMD;
1474 }
1475}
1476
1487/* 1477/*
1488 * Print sense data and related channel program. 1478 * Print sense data and related channel program.
1489 * Parts are printed because printk buffer is only 1024 bytes. 1479 * Parts are printed because printk buffer is only 1024 bytes.
@@ -1642,6 +1632,7 @@ static struct dasd_discipline dasd_eckd_discipline = {
1642 .free_cp = dasd_eckd_free_cp, 1632 .free_cp = dasd_eckd_free_cp,
1643 .dump_sense = dasd_eckd_dump_sense, 1633 .dump_sense = dasd_eckd_dump_sense,
1644 .fill_info = dasd_eckd_fill_info, 1634 .fill_info = dasd_eckd_fill_info,
1635 .ioctl = dasd_eckd_ioctl,
1645}; 1636};
1646 1637
1647static int __init 1638static int __init
@@ -1649,59 +1640,18 @@ dasd_eckd_init(void)
1649{ 1640{
1650 int ret; 1641 int ret;
1651 1642
1652 dasd_ioctl_no_register(THIS_MODULE, BIODASDGATTR,
1653 dasd_eckd_get_attrib);
1654 dasd_ioctl_no_register(THIS_MODULE, BIODASDSATTR,
1655 dasd_eckd_set_attrib);
1656 dasd_ioctl_no_register(THIS_MODULE, BIODASDPSRD,
1657 dasd_eckd_performance);
1658 dasd_ioctl_no_register(THIS_MODULE, BIODASDRLSE,
1659 dasd_eckd_release);
1660 dasd_ioctl_no_register(THIS_MODULE, BIODASDRSRV,
1661 dasd_eckd_reserve);
1662 dasd_ioctl_no_register(THIS_MODULE, BIODASDSLCK,
1663 dasd_eckd_steal_lock);
1664
1665 ASCEBC(dasd_eckd_discipline.ebcname, 4); 1643 ASCEBC(dasd_eckd_discipline.ebcname, 4);
1666 1644
1667 ret = ccw_driver_register(&dasd_eckd_driver); 1645 ret = ccw_driver_register(&dasd_eckd_driver);
1668 if (ret) { 1646 if (!ret)
1669 dasd_ioctl_no_unregister(THIS_MODULE, BIODASDGATTR, 1647 dasd_generic_auto_online(&dasd_eckd_driver);
1670 dasd_eckd_get_attrib); 1648 return ret;
1671 dasd_ioctl_no_unregister(THIS_MODULE, BIODASDSATTR,
1672 dasd_eckd_set_attrib);
1673 dasd_ioctl_no_unregister(THIS_MODULE, BIODASDPSRD,
1674 dasd_eckd_performance);
1675 dasd_ioctl_no_unregister(THIS_MODULE, BIODASDRLSE,
1676 dasd_eckd_release);
1677 dasd_ioctl_no_unregister(THIS_MODULE, BIODASDRSRV,
1678 dasd_eckd_reserve);
1679 dasd_ioctl_no_unregister(THIS_MODULE, BIODASDSLCK,
1680 dasd_eckd_steal_lock);
1681 return ret;
1682 }
1683
1684 dasd_generic_auto_online(&dasd_eckd_driver);
1685 return 0;
1686} 1649}
1687 1650
1688static void __exit 1651static void __exit
1689dasd_eckd_cleanup(void) 1652dasd_eckd_cleanup(void)
1690{ 1653{
1691 ccw_driver_unregister(&dasd_eckd_driver); 1654 ccw_driver_unregister(&dasd_eckd_driver);
1692
1693 dasd_ioctl_no_unregister(THIS_MODULE, BIODASDGATTR,
1694 dasd_eckd_get_attrib);
1695 dasd_ioctl_no_unregister(THIS_MODULE, BIODASDSATTR,
1696 dasd_eckd_set_attrib);
1697 dasd_ioctl_no_unregister(THIS_MODULE, BIODASDPSRD,
1698 dasd_eckd_performance);
1699 dasd_ioctl_no_unregister(THIS_MODULE, BIODASDRLSE,
1700 dasd_eckd_release);
1701 dasd_ioctl_no_unregister(THIS_MODULE, BIODASDRSRV,
1702 dasd_eckd_reserve);
1703 dasd_ioctl_no_unregister(THIS_MODULE, BIODASDSLCK,
1704 dasd_eckd_steal_lock);
1705} 1655}
1706 1656
1707module_init(dasd_eckd_init); 1657module_init(dasd_eckd_init);
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h
index 6010ecf76b4c..e9485559e22e 100644
--- a/drivers/s390/block/dasd_int.h
+++ b/drivers/s390/block/dasd_int.h
@@ -272,6 +272,7 @@ struct dasd_discipline {
272 /* i/o control functions. */ 272 /* i/o control functions. */
273 int (*fill_geometry) (struct dasd_device *, struct hd_geometry *); 273 int (*fill_geometry) (struct dasd_device *, struct hd_geometry *);
274 int (*fill_info) (struct dasd_device *, struct dasd_information2_t *); 274 int (*fill_info) (struct dasd_device *, struct dasd_information2_t *);
275 int (*ioctl) (struct dasd_device *, unsigned int, void __user *);
275}; 276};
276 277
277extern struct dasd_discipline *dasd_diag_discipline_pointer; 278extern struct dasd_discipline *dasd_diag_discipline_pointer;
diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c
index e3ad34686444..bb6caf46bbd9 100644
--- a/drivers/s390/block/dasd_ioctl.c
+++ b/drivers/s390/block/dasd_ioctl.c
@@ -448,7 +448,14 @@ dasd_ioctl(struct inode *inode, struct file *file,
448 case DASDAPIVER: 448 case DASDAPIVER:
449 return dasd_ioctl_api_version(argp); 449 return dasd_ioctl_api_version(argp);
450 default: 450 default:
451 /* resort to the deprecated dynamic ioctl list */ 451 /* if the discipline has an ioctl method try it. */
452 if (device->discipline->ioctl) {
453 int rval = device->discipline->ioctl(device, cmd, argp);
454 if (rval != -ENOIOCTLCMD)
455 return rval;
456 }
457
458 /* else resort to the deprecated dynamic ioctl list */
452 list_for_each_entry(ioctl, &dasd_ioctl_list, list) { 459 list_for_each_entry(ioctl, &dasd_ioctl_list, list) {
453 if (ioctl->no == cmd) { 460 if (ioctl->no == cmd) {
454 /* Found a matching ioctl. Call it. */ 461 /* Found a matching ioctl. Call it. */