diff options
Diffstat (limited to 'drivers/s390/block/dasd.c')
-rw-r--r-- | drivers/s390/block/dasd.c | 32 |
1 files changed, 22 insertions, 10 deletions
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index fdb61380c523..f779f674dfa0 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * Bugreports.to..: <Linux390@de.ibm.com> | 7 | * Bugreports.to..: <Linux390@de.ibm.com> |
8 | * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001 | 8 | * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001 |
9 | * | 9 | * |
10 | * $Revision: 1.167 $ | 10 | * $Revision: 1.172 $ |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/config.h> | 13 | #include <linux/config.h> |
@@ -604,7 +604,7 @@ dasd_smalloc_request(char *magic, int cplength, int datasize, | |||
604 | void | 604 | void |
605 | dasd_kfree_request(struct dasd_ccw_req * cqr, struct dasd_device * device) | 605 | dasd_kfree_request(struct dasd_ccw_req * cqr, struct dasd_device * device) |
606 | { | 606 | { |
607 | #ifdef CONFIG_ARCH_S390X | 607 | #ifdef CONFIG_64BIT |
608 | struct ccw1 *ccw; | 608 | struct ccw1 *ccw; |
609 | 609 | ||
610 | /* Clear any idals used for the request. */ | 610 | /* Clear any idals used for the request. */ |
@@ -1224,6 +1224,12 @@ __dasd_start_head(struct dasd_device * device) | |||
1224 | if (list_empty(&device->ccw_queue)) | 1224 | if (list_empty(&device->ccw_queue)) |
1225 | return; | 1225 | return; |
1226 | cqr = list_entry(device->ccw_queue.next, struct dasd_ccw_req, list); | 1226 | cqr = list_entry(device->ccw_queue.next, struct dasd_ccw_req, list); |
1227 | /* check FAILFAST */ | ||
1228 | if (device->stopped & ~DASD_STOPPED_PENDING && | ||
1229 | test_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags)) { | ||
1230 | cqr->status = DASD_CQR_FAILED; | ||
1231 | dasd_schedule_bh(device); | ||
1232 | } | ||
1227 | if ((cqr->status == DASD_CQR_QUEUED) && | 1233 | if ((cqr->status == DASD_CQR_QUEUED) && |
1228 | (!device->stopped)) { | 1234 | (!device->stopped)) { |
1229 | /* try to start the first I/O that can be started */ | 1235 | /* try to start the first I/O that can be started */ |
@@ -1323,7 +1329,7 @@ void | |||
1323 | dasd_schedule_bh(struct dasd_device * device) | 1329 | dasd_schedule_bh(struct dasd_device * device) |
1324 | { | 1330 | { |
1325 | /* Protect against rescheduling. */ | 1331 | /* Protect against rescheduling. */ |
1326 | if (atomic_compare_and_swap (0, 1, &device->tasklet_scheduled)) | 1332 | if (atomic_cmpxchg (&device->tasklet_scheduled, 0, 1) != 0) |
1327 | return; | 1333 | return; |
1328 | dasd_get_device(device); | 1334 | dasd_get_device(device); |
1329 | tasklet_hi_schedule(&device->tasklet); | 1335 | tasklet_hi_schedule(&device->tasklet); |
@@ -1750,8 +1756,10 @@ dasd_exit(void) | |||
1750 | * SECTION: common functions for ccw_driver use | 1756 | * SECTION: common functions for ccw_driver use |
1751 | */ | 1757 | */ |
1752 | 1758 | ||
1753 | /* initial attempt at a probe function. this can be simplified once | 1759 | /* |
1754 | * the other detection code is gone */ | 1760 | * Initial attempt at a probe function. this can be simplified once |
1761 | * the other detection code is gone. | ||
1762 | */ | ||
1755 | int | 1763 | int |
1756 | dasd_generic_probe (struct ccw_device *cdev, | 1764 | dasd_generic_probe (struct ccw_device *cdev, |
1757 | struct dasd_discipline *discipline) | 1765 | struct dasd_discipline *discipline) |
@@ -1770,8 +1778,10 @@ dasd_generic_probe (struct ccw_device *cdev, | |||
1770 | return ret; | 1778 | return ret; |
1771 | } | 1779 | } |
1772 | 1780 | ||
1773 | /* this will one day be called from a global not_oper handler. | 1781 | /* |
1774 | * It is also used by driver_unregister during module unload */ | 1782 | * This will one day be called from a global not_oper handler. |
1783 | * It is also used by driver_unregister during module unload. | ||
1784 | */ | ||
1775 | void | 1785 | void |
1776 | dasd_generic_remove (struct ccw_device *cdev) | 1786 | dasd_generic_remove (struct ccw_device *cdev) |
1777 | { | 1787 | { |
@@ -1798,9 +1808,11 @@ dasd_generic_remove (struct ccw_device *cdev) | |||
1798 | dasd_delete_device(device); | 1808 | dasd_delete_device(device); |
1799 | } | 1809 | } |
1800 | 1810 | ||
1801 | /* activate a device. This is called from dasd_{eckd,fba}_probe() when either | 1811 | /* |
1812 | * Activate a device. This is called from dasd_{eckd,fba}_probe() when either | ||
1802 | * the device is detected for the first time and is supposed to be used | 1813 | * the device is detected for the first time and is supposed to be used |
1803 | * or the user has started activation through sysfs */ | 1814 | * or the user has started activation through sysfs. |
1815 | */ | ||
1804 | int | 1816 | int |
1805 | dasd_generic_set_online (struct ccw_device *cdev, | 1817 | dasd_generic_set_online (struct ccw_device *cdev, |
1806 | struct dasd_discipline *discipline) | 1818 | struct dasd_discipline *discipline) |
@@ -1917,7 +1929,6 @@ dasd_generic_notify(struct ccw_device *cdev, int event) | |||
1917 | if (cqr->status == DASD_CQR_IN_IO) | 1929 | if (cqr->status == DASD_CQR_IN_IO) |
1918 | cqr->status = DASD_CQR_FAILED; | 1930 | cqr->status = DASD_CQR_FAILED; |
1919 | device->stopped |= DASD_STOPPED_DC_EIO; | 1931 | device->stopped |= DASD_STOPPED_DC_EIO; |
1920 | dasd_schedule_bh(device); | ||
1921 | } else { | 1932 | } else { |
1922 | list_for_each_entry(cqr, &device->ccw_queue, list) | 1933 | list_for_each_entry(cqr, &device->ccw_queue, list) |
1923 | if (cqr->status == DASD_CQR_IN_IO) { | 1934 | if (cqr->status == DASD_CQR_IN_IO) { |
@@ -1927,6 +1938,7 @@ dasd_generic_notify(struct ccw_device *cdev, int event) | |||
1927 | device->stopped |= DASD_STOPPED_DC_WAIT; | 1938 | device->stopped |= DASD_STOPPED_DC_WAIT; |
1928 | dasd_set_timer(device, 0); | 1939 | dasd_set_timer(device, 0); |
1929 | } | 1940 | } |
1941 | dasd_schedule_bh(device); | ||
1930 | ret = 1; | 1942 | ret = 1; |
1931 | break; | 1943 | break; |
1932 | case CIO_OPER: | 1944 | case CIO_OPER: |