aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/block/dasd_eckd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/block/dasd_eckd.c')
-rw-r--r--drivers/s390/block/dasd_eckd.c337
1 files changed, 200 insertions, 137 deletions
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index 7d5a6cee4bd8..0dfab30e8089 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * File...........: linux/drivers/s390/block/dasd_eckd.c 2 * File...........: linux/drivers/s390/block/dasd_eckd.c
3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> 3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
4 * Horst Hummel <Horst.Hummel@de.ibm.com> 4 * Horst Hummel <Horst.Hummel@de.ibm.com>
5 * Carsten Otte <Cotte@de.ibm.com> 5 * Carsten Otte <Cotte@de.ibm.com>
6 * Martin Schwidefsky <schwidefsky@de.ibm.com> 6 * Martin Schwidefsky <schwidefsky@de.ibm.com>
7 * Bugreports.to..: <Linux390@de.ibm.com> 7 * Bugreports.to..: <Linux390@de.ibm.com>
@@ -24,6 +24,7 @@
24#include <asm/io.h> 24#include <asm/io.h>
25#include <asm/todclk.h> 25#include <asm/todclk.h>
26#include <asm/uaccess.h> 26#include <asm/uaccess.h>
27#include <asm/cio.h>
27#include <asm/ccwdev.h> 28#include <asm/ccwdev.h>
28 29
29#include "dasd_int.h" 30#include "dasd_int.h"
@@ -89,17 +90,22 @@ dasd_eckd_probe (struct ccw_device *cdev)
89{ 90{
90 int ret; 91 int ret;
91 92
92 ret = dasd_generic_probe (cdev, &dasd_eckd_discipline); 93 /* set ECKD specific ccw-device options */
93 if (ret) 94 ret = ccw_device_set_options(cdev, CCWDEV_ALLOW_FORCE);
95 if (ret) {
96 printk(KERN_WARNING
97 "dasd_eckd_probe: could not set ccw-device options "
98 "for %s\n", cdev->dev.bus_id);
94 return ret; 99 return ret;
95 ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP | CCWDEV_ALLOW_FORCE); 100 }
96 return 0; 101 ret = dasd_generic_probe(cdev, &dasd_eckd_discipline);
102 return ret;
97} 103}
98 104
99static int 105static int
100dasd_eckd_set_online(struct ccw_device *cdev) 106dasd_eckd_set_online(struct ccw_device *cdev)
101{ 107{
102 return dasd_generic_set_online (cdev, &dasd_eckd_discipline); 108 return dasd_generic_set_online(cdev, &dasd_eckd_discipline);
103} 109}
104 110
105static struct ccw_driver dasd_eckd_driver = { 111static struct ccw_driver dasd_eckd_driver = {
@@ -210,14 +216,14 @@ check_XRC (struct ccw1 *de_ccw,
210 216
211 /* switch on System Time Stamp - needed for XRC Support */ 217 /* switch on System Time Stamp - needed for XRC Support */
212 if (private->rdc_data.facilities.XRC_supported) { 218 if (private->rdc_data.facilities.XRC_supported) {
213 219
214 data->ga_extended |= 0x08; /* switch on 'Time Stamp Valid' */ 220 data->ga_extended |= 0x08; /* switch on 'Time Stamp Valid' */
215 data->ga_extended |= 0x02; /* switch on 'Extended Parameter' */ 221 data->ga_extended |= 0x02; /* switch on 'Extended Parameter' */
216 222
217 data->ep_sys_time = get_clock (); 223 data->ep_sys_time = get_clock ();
218 224
219 de_ccw->count = sizeof (struct DE_eckd_data); 225 de_ccw->count = sizeof (struct DE_eckd_data);
220 de_ccw->flags |= CCW_FLAG_SLI; 226 de_ccw->flags |= CCW_FLAG_SLI;
221 } 227 }
222 228
223 return; 229 return;
@@ -296,8 +302,8 @@ define_extent(struct ccw1 * ccw, struct DE_eckd_data * data, int trk,
296 /* check for sequential prestage - enhance cylinder range */ 302 /* check for sequential prestage - enhance cylinder range */
297 if (data->attributes.operation == DASD_SEQ_PRESTAGE || 303 if (data->attributes.operation == DASD_SEQ_PRESTAGE ||
298 data->attributes.operation == DASD_SEQ_ACCESS) { 304 data->attributes.operation == DASD_SEQ_ACCESS) {
299 305
300 if (end.cyl + private->attrib.nr_cyl < geo.cyl) 306 if (end.cyl + private->attrib.nr_cyl < geo.cyl)
301 end.cyl += private->attrib.nr_cyl; 307 end.cyl += private->attrib.nr_cyl;
302 else 308 else
303 end.cyl = (geo.cyl - 1); 309 end.cyl = (geo.cyl - 1);
@@ -317,7 +323,7 @@ locate_record(struct ccw1 *ccw, struct LO_eckd_data *data, int trk,
317 struct dasd_eckd_private *private; 323 struct dasd_eckd_private *private;
318 int sector; 324 int sector;
319 int dn, d; 325 int dn, d;
320 326
321 private = (struct dasd_eckd_private *) device->private; 327 private = (struct dasd_eckd_private *) device->private;
322 328
323 DBF_DEV_EVENT(DBF_INFO, device, 329 DBF_DEV_EVENT(DBF_INFO, device,
@@ -541,6 +547,86 @@ dasd_eckd_read_conf(struct dasd_device *device)
541} 547}
542 548
543/* 549/*
550 * Build CP for Perform Subsystem Function - SSC.
551 */
552struct dasd_ccw_req *
553dasd_eckd_build_psf_ssc(struct dasd_device *device)
554{
555 struct dasd_ccw_req *cqr;
556 struct dasd_psf_ssc_data *psf_ssc_data;
557 struct ccw1 *ccw;
558
559 cqr = dasd_smalloc_request("ECKD", 1 /* PSF */ ,
560 sizeof(struct dasd_psf_ssc_data),
561 device);
562
563 if (IS_ERR(cqr)) {
564 DEV_MESSAGE(KERN_WARNING, device, "%s",
565 "Could not allocate PSF-SSC request");
566 return cqr;
567 }
568 psf_ssc_data = (struct dasd_psf_ssc_data *)cqr->data;
569 psf_ssc_data->order = PSF_ORDER_SSC;
570 psf_ssc_data->suborder = 0x08;
571
572 ccw = cqr->cpaddr;
573 ccw->cmd_code = DASD_ECKD_CCW_PSF;
574 ccw->cda = (__u32)(addr_t)psf_ssc_data;
575 ccw->count = 66;
576
577 cqr->device = device;
578 cqr->expires = 10*HZ;
579 cqr->buildclk = get_clock();
580 cqr->status = DASD_CQR_FILLED;
581 return cqr;
582}
583
584/*
585 * Perform Subsystem Function.
586 * It is necessary to trigger CIO for channel revalidation since this
587 * call might change behaviour of DASD devices.
588 */
589static int
590dasd_eckd_psf_ssc(struct dasd_device *device)
591{
592 struct dasd_ccw_req *cqr;
593 int rc;
594
595 cqr = dasd_eckd_build_psf_ssc(device);
596 if (IS_ERR(cqr))
597 return PTR_ERR(cqr);
598
599 rc = dasd_sleep_on(cqr);
600 if (!rc)
601 /* trigger CIO to reprobe devices */
602 css_schedule_reprobe();
603 dasd_sfree_request(cqr, cqr->device);
604 return rc;
605}
606
607/*
608 * Valide storage server of current device.
609 */
610static int
611dasd_eckd_validate_server(struct dasd_device *device)
612{
613 int rc;
614
615 /* Currently PAV is the only reason to 'validate' server on LPAR */
616 if (dasd_nopav || MACHINE_IS_VM)
617 return 0;
618
619 rc = dasd_eckd_psf_ssc(device);
620 if (rc)
621 /* may be requested feature is not available on server,
622 * therefore just report error and go ahead */
623 DEV_MESSAGE(KERN_INFO, device,
624 "Perform Subsystem Function returned rc=%d", rc);
625 /* RE-Read Configuration Data */
626 return dasd_eckd_read_conf(device);
627}
628
629/*
544 * Check device characteristics. 630 * Check device characteristics.
545 * If the device is accessible using ECKD discipline, the device is enabled. 631 * If the device is accessible using ECKD discipline, the device is enabled.
546 */ 632 */
@@ -554,7 +640,7 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
554 640
555 private = (struct dasd_eckd_private *) device->private; 641 private = (struct dasd_eckd_private *) device->private;
556 if (private == NULL) { 642 if (private == NULL) {
557 private = kmalloc(sizeof(struct dasd_eckd_private), 643 private = kzalloc(sizeof(struct dasd_eckd_private),
558 GFP_KERNEL | GFP_DMA); 644 GFP_KERNEL | GFP_DMA);
559 if (private == NULL) { 645 if (private == NULL) {
560 DEV_MESSAGE(KERN_WARNING, device, "%s", 646 DEV_MESSAGE(KERN_WARNING, device, "%s",
@@ -562,7 +648,6 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
562 "data"); 648 "data");
563 return -ENOMEM; 649 return -ENOMEM;
564 } 650 }
565 memset(private, 0, sizeof(struct dasd_eckd_private));
566 device->private = (void *) private; 651 device->private = (void *) private;
567 } 652 }
568 /* Invalidate status of initial analysis. */ 653 /* Invalidate status of initial analysis. */
@@ -571,16 +656,29 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
571 private->attrib.operation = DASD_NORMAL_CACHE; 656 private->attrib.operation = DASD_NORMAL_CACHE;
572 private->attrib.nr_cyl = 0; 657 private->attrib.nr_cyl = 0;
573 658
659 /* Read Configuration Data */
660 rc = dasd_eckd_read_conf(device);
661 if (rc)
662 return rc;
663
664 /* Generate device unique id and register in devmap */
665 rc = dasd_eckd_generate_uid(device, &uid);
666 if (rc)
667 return rc;
668 rc = dasd_set_uid(device->cdev, &uid);
669 if (rc == 1) /* new server found */
670 rc = dasd_eckd_validate_server(device);
671 if (rc)
672 return rc;
673
574 /* Read Device Characteristics */ 674 /* Read Device Characteristics */
575 rdc_data = (void *) &(private->rdc_data); 675 rdc_data = (void *) &(private->rdc_data);
576 memset(rdc_data, 0, sizeof(rdc_data)); 676 memset(rdc_data, 0, sizeof(rdc_data));
577 rc = read_dev_chars(device->cdev, &rdc_data, 64); 677 rc = read_dev_chars(device->cdev, &rdc_data, 64);
578 if (rc) { 678 if (rc)
579 DEV_MESSAGE(KERN_WARNING, device, 679 DEV_MESSAGE(KERN_WARNING, device,
580 "Read device characteristics returned error %d", 680 "Read device characteristics returned "
581 rc); 681 "rc=%d", rc);
582 return rc;
583 }
584 682
585 DEV_MESSAGE(KERN_INFO, device, 683 DEV_MESSAGE(KERN_INFO, device,
586 "%04X/%02X(CU:%04X/%02X) Cyl:%d Head:%d Sec:%d", 684 "%04X/%02X(CU:%04X/%02X) Cyl:%d Head:%d Sec:%d",
@@ -591,19 +689,6 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
591 private->rdc_data.no_cyl, 689 private->rdc_data.no_cyl,
592 private->rdc_data.trk_per_cyl, 690 private->rdc_data.trk_per_cyl,
593 private->rdc_data.sec_per_trk); 691 private->rdc_data.sec_per_trk);
594
595 /* Read Configuration Data */
596 rc = dasd_eckd_read_conf (device);
597 if (rc)
598 return rc;
599
600 /* Generate device unique id and register in devmap */
601 rc = dasd_eckd_generate_uid(device, &uid);
602 if (rc)
603 return rc;
604
605 rc = dasd_set_uid(device->cdev, &uid);
606
607 return rc; 692 return rc;
608} 693}
609 694
@@ -773,7 +858,7 @@ dasd_eckd_end_analysis(struct dasd_device *device)
773 ((private->rdc_data.no_cyl * 858 ((private->rdc_data.no_cyl *
774 private->rdc_data.trk_per_cyl * 859 private->rdc_data.trk_per_cyl *
775 blk_per_trk * (device->bp_block >> 9)) >> 1), 860 blk_per_trk * (device->bp_block >> 9)) >> 1),
776 ((blk_per_trk * device->bp_block) >> 10), 861 ((blk_per_trk * device->bp_block) >> 10),
777 private->uses_cdl ? 862 private->uses_cdl ?
778 "compatible disk layout" : "linux disk layout"); 863 "compatible disk layout" : "linux disk layout");
779 864
@@ -970,7 +1055,7 @@ dasd_eckd_format_device(struct dasd_device * device,
970 if (i < 3) { 1055 if (i < 3) {
971 ect->kl = 4; 1056 ect->kl = 4;
972 ect->dl = sizes_trk0[i] - 4; 1057 ect->dl = sizes_trk0[i] - 4;
973 } 1058 }
974 } 1059 }
975 if ((fdata->intensity & 0x08) && 1060 if ((fdata->intensity & 0x08) &&
976 fdata->start_unit == 1) { 1061 fdata->start_unit == 1) {
@@ -1270,7 +1355,7 @@ dasd_eckd_fill_info(struct dasd_device * device,
1270 1355
1271/* 1356/*
1272 * Release device ioctl. 1357 * Release device ioctl.
1273 * Buils a channel programm to releases a prior reserved 1358 * Buils a channel programm to releases a prior reserved
1274 * (see dasd_eckd_reserve) device. 1359 * (see dasd_eckd_reserve) device.
1275 */ 1360 */
1276static int 1361static int
@@ -1310,8 +1395,8 @@ dasd_eckd_release(struct dasd_device *device)
1310/* 1395/*
1311 * Reserve device ioctl. 1396 * Reserve device ioctl.
1312 * Options are set to 'synchronous wait for interrupt' and 1397 * Options are set to 'synchronous wait for interrupt' and
1313 * 'timeout the request'. This leads to a terminate IO if 1398 * 'timeout the request'. This leads to a terminate IO if
1314 * the interrupt is outstanding for a certain time. 1399 * the interrupt is outstanding for a certain time.
1315 */ 1400 */
1316static int 1401static int
1317dasd_eckd_reserve(struct dasd_device *device) 1402dasd_eckd_reserve(struct dasd_device *device)
@@ -1349,7 +1434,7 @@ dasd_eckd_reserve(struct dasd_device *device)
1349 1434
1350/* 1435/*
1351 * Steal lock ioctl - unconditional reserve device. 1436 * Steal lock ioctl - unconditional reserve device.
1352 * Buils a channel programm to break a device's reservation. 1437 * Buils a channel programm to break a device's reservation.
1353 * (unconditional reserve) 1438 * (unconditional reserve)
1354 */ 1439 */
1355static int 1440static int
@@ -1522,6 +1607,40 @@ dasd_eckd_ioctl(struct dasd_device *device, unsigned int cmd, void __user *argp)
1522} 1607}
1523 1608
1524/* 1609/*
1610 * Dump the range of CCWs into 'page' buffer
1611 * and return number of printed chars.
1612 */
1613static inline int
1614dasd_eckd_dump_ccw_range(struct ccw1 *from, struct ccw1 *to, char *page)
1615{
1616 int len, count;
1617 char *datap;
1618
1619 len = 0;
1620 while (from <= to) {
1621 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
1622 " CCW %p: %08X %08X DAT:",
1623 from, ((int *) from)[0], ((int *) from)[1]);
1624
1625 /* get pointer to data (consider IDALs) */
1626 if (from->flags & CCW_FLAG_IDA)
1627 datap = (char *) *((addr_t *) (addr_t) from->cda);
1628 else
1629 datap = (char *) ((addr_t) from->cda);
1630
1631 /* dump data (max 32 bytes) */
1632 for (count = 0; count < from->count && count < 32; count++) {
1633 if (count % 8 == 0) len += sprintf(page + len, " ");
1634 if (count % 4 == 0) len += sprintf(page + len, " ");
1635 len += sprintf(page + len, "%02x", datap[count]);
1636 }
1637 len += sprintf(page + len, "\n");
1638 from++;
1639 }
1640 return len;
1641}
1642
1643/*
1525 * Print sense data and related channel program. 1644 * Print sense data and related channel program.
1526 * Parts are printed because printk buffer is only 1024 bytes. 1645 * Parts are printed because printk buffer is only 1024 bytes.
1527 */ 1646 */
@@ -1530,8 +1649,8 @@ dasd_eckd_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req,
1530 struct irb *irb) 1649 struct irb *irb)
1531{ 1650{
1532 char *page; 1651 char *page;
1533 struct ccw1 *act, *end, *last; 1652 struct ccw1 *first, *last, *fail, *from, *to;
1534 int len, sl, sct, count; 1653 int len, sl, sct;
1535 1654
1536 page = (char *) get_zeroed_page(GFP_ATOMIC); 1655 page = (char *) get_zeroed_page(GFP_ATOMIC);
1537 if (page == NULL) { 1656 if (page == NULL) {
@@ -1539,7 +1658,8 @@ dasd_eckd_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req,
1539 "No memory to dump sense data"); 1658 "No memory to dump sense data");
1540 return; 1659 return;
1541 } 1660 }
1542 len = sprintf(page, KERN_ERR PRINTK_HEADER 1661 /* dump the sense data */
1662 len = sprintf(page, KERN_ERR PRINTK_HEADER
1543 " I/O status report for device %s:\n", 1663 " I/O status report for device %s:\n",
1544 device->cdev->dev.bus_id); 1664 device->cdev->dev.bus_id);
1545 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 1665 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
@@ -1564,87 +1684,55 @@ dasd_eckd_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req,
1564 1684
1565 if (irb->ecw[27] & DASD_SENSE_BIT_0) { 1685 if (irb->ecw[27] & DASD_SENSE_BIT_0) {
1566 /* 24 Byte Sense Data */ 1686 /* 24 Byte Sense Data */
1567 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 1687 sprintf(page + len, KERN_ERR PRINTK_HEADER
1568 " 24 Byte: %x MSG %x, " 1688 " 24 Byte: %x MSG %x, "
1569 "%s MSGb to SYSOP\n", 1689 "%s MSGb to SYSOP\n",
1570 irb->ecw[7] >> 4, irb->ecw[7] & 0x0f, 1690 irb->ecw[7] >> 4, irb->ecw[7] & 0x0f,
1571 irb->ecw[1] & 0x10 ? "" : "no"); 1691 irb->ecw[1] & 0x10 ? "" : "no");
1572 } else { 1692 } else {
1573 /* 32 Byte Sense Data */ 1693 /* 32 Byte Sense Data */
1574 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 1694 sprintf(page + len, KERN_ERR PRINTK_HEADER
1575 " 32 Byte: Format: %x " 1695 " 32 Byte: Format: %x "
1576 "Exception class %x\n", 1696 "Exception class %x\n",
1577 irb->ecw[6] & 0x0f, irb->ecw[22] >> 4); 1697 irb->ecw[6] & 0x0f, irb->ecw[22] >> 4);
1578 } 1698 }
1579 } else { 1699 } else {
1580 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 1700 sprintf(page + len, KERN_ERR PRINTK_HEADER
1581 " SORRY - NO VALID SENSE AVAILABLE\n"); 1701 " SORRY - NO VALID SENSE AVAILABLE\n");
1582 } 1702 }
1583 MESSAGE_LOG(KERN_ERR, "%s", 1703 printk("%s", page);
1584 page + sizeof(KERN_ERR PRINTK_HEADER)); 1704
1585 1705 /* dump the Channel Program (max 140 Bytes per line) */
1586 /* dump the Channel Program */ 1706 /* Count CCW and print first CCWs (maximum 1024 % 140 = 7) */
1587 /* print first CCWs (maximum 8) */ 1707 first = req->cpaddr;
1588 act = req->cpaddr; 1708 for (last = first; last->flags & (CCW_FLAG_CC | CCW_FLAG_DC); last++);
1589 for (last = act; last->flags & (CCW_FLAG_CC | CCW_FLAG_DC); last++); 1709 to = min(first + 6, last);
1590 end = min(act + 8, last); 1710 len = sprintf(page, KERN_ERR PRINTK_HEADER
1591 len = sprintf(page, KERN_ERR PRINTK_HEADER
1592 " Related CP in req: %p\n", req); 1711 " Related CP in req: %p\n", req);
1593 while (act <= end) { 1712 dasd_eckd_dump_ccw_range(first, to, page + len);
1594 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 1713 printk("%s", page);
1595 " CCW %p: %08X %08X DAT:",
1596 act, ((int *) act)[0], ((int *) act)[1]);
1597 for (count = 0; count < 32 && count < act->count;
1598 count += sizeof(int))
1599 len += sprintf(page + len, " %08X",
1600 ((int *) (addr_t) act->cda)
1601 [(count>>2)]);
1602 len += sprintf(page + len, "\n");
1603 act++;
1604 }
1605 MESSAGE_LOG(KERN_ERR, "%s",
1606 page + sizeof(KERN_ERR PRINTK_HEADER));
1607 1714
1608 /* print failing CCW area */ 1715 /* print failing CCW area (maximum 4) */
1716 /* scsw->cda is either valid or zero */
1609 len = 0; 1717 len = 0;
1610 if (act < ((struct ccw1 *)(addr_t) irb->scsw.cpa) - 2) { 1718 from = ++to;
1611 act = ((struct ccw1 *)(addr_t) irb->scsw.cpa) - 2; 1719 fail = (struct ccw1 *)(addr_t) irb->scsw.cpa; /* failing CCW */
1612 len += sprintf(page + len, KERN_ERR PRINTK_HEADER "......\n"); 1720 if (from < fail - 2) {
1613 } 1721 from = fail - 2; /* there is a gap - print header */
1614 end = min((struct ccw1 *)(addr_t) irb->scsw.cpa + 2, last); 1722 len += sprintf(page, KERN_ERR PRINTK_HEADER "......\n");
1615 while (act <= end) {
1616 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
1617 " CCW %p: %08X %08X DAT:",
1618 act, ((int *) act)[0], ((int *) act)[1]);
1619 for (count = 0; count < 32 && count < act->count;
1620 count += sizeof(int))
1621 len += sprintf(page + len, " %08X",
1622 ((int *) (addr_t) act->cda)
1623 [(count>>2)]);
1624 len += sprintf(page + len, "\n");
1625 act++;
1626 } 1723 }
1724 to = min(fail + 1, last);
1725 len += dasd_eckd_dump_ccw_range(from, to, page + len);
1627 1726
1628 /* print last CCWs */ 1727 /* print last CCWs (maximum 2) */
1629 if (act < last - 2) { 1728 from = max(from, ++to);
1630 act = last - 2; 1729 if (from < last - 1) {
1730 from = last - 1; /* there is a gap - print header */
1631 len += sprintf(page + len, KERN_ERR PRINTK_HEADER "......\n"); 1731 len += sprintf(page + len, KERN_ERR PRINTK_HEADER "......\n");
1632 } 1732 }
1633 while (act <= last) { 1733 len += dasd_eckd_dump_ccw_range(from, last, page + len);
1634 len += sprintf(page + len, KERN_ERR PRINTK_HEADER
1635 " CCW %p: %08X %08X DAT:",
1636 act, ((int *) act)[0], ((int *) act)[1]);
1637 for (count = 0; count < 32 && count < act->count;
1638 count += sizeof(int))
1639 len += sprintf(page + len, " %08X",
1640 ((int *) (addr_t) act->cda)
1641 [(count>>2)]);
1642 len += sprintf(page + len, "\n");
1643 act++;
1644 }
1645 if (len > 0) 1734 if (len > 0)
1646 MESSAGE_LOG(KERN_ERR, "%s", 1735 printk("%s", page);
1647 page + sizeof(KERN_ERR PRINTK_HEADER));
1648 free_page((unsigned long) page); 1736 free_page((unsigned long) page);
1649} 1737}
1650 1738
@@ -1685,14 +1773,8 @@ static struct dasd_discipline dasd_eckd_discipline = {
1685static int __init 1773static int __init
1686dasd_eckd_init(void) 1774dasd_eckd_init(void)
1687{ 1775{
1688 int ret;
1689
1690 ASCEBC(dasd_eckd_discipline.ebcname, 4); 1776 ASCEBC(dasd_eckd_discipline.ebcname, 4);
1691 1777 return ccw_driver_register(&dasd_eckd_driver);
1692 ret = ccw_driver_register(&dasd_eckd_driver);
1693 if (!ret)
1694 dasd_generic_auto_online(&dasd_eckd_driver);
1695 return ret;
1696} 1778}
1697 1779
1698static void __exit 1780static void __exit
@@ -1703,22 +1785,3 @@ dasd_eckd_cleanup(void)
1703 1785
1704module_init(dasd_eckd_init); 1786module_init(dasd_eckd_init);
1705module_exit(dasd_eckd_cleanup); 1787module_exit(dasd_eckd_cleanup);
1706
1707/*
1708 * Overrides for Emacs so that we follow Linus's tabbing style.
1709 * Emacs will notice this stuff at the end of the file and automatically
1710 * adjust the settings for this buffer only. This must remain at the end
1711 * of the file.
1712 * ---------------------------------------------------------------------------
1713 * Local variables:
1714 * c-indent-level: 4
1715 * c-brace-imaginary-offset: 0
1716 * c-brace-offset: -4
1717 * c-argdecl-indent: 4
1718 * c-label-offset: -4
1719 * c-continued-statement-offset: 4
1720 * c-continued-brace-offset: 0
1721 * indent-tabs-mode: 1
1722 * tab-width: 8
1723 * End:
1724 */