| Heiko Carstens | ab14de6 | 2007-02-05 21:18:37 +0100 | [diff] [blame] | 1 | /* | 
|  | 2 | *  drivers/s390/char/sclp_info.c | 
|  | 3 | * | 
|  | 4 | *    Copyright IBM Corp. 2007 | 
|  | 5 | *    Author(s): Heiko Carstens <heiko.carstens@de.ibm.com> | 
|  | 6 | */ | 
|  | 7 |  | 
|  | 8 | #include <linux/init.h> | 
|  | 9 | #include <linux/errno.h> | 
|  | 10 | #include <linux/string.h> | 
|  | 11 | #include <asm/sclp.h> | 
|  | 12 | #include "sclp.h" | 
|  | 13 |  | 
|  | 14 | struct sclp_readinfo_sccb s390_readinfo_sccb; | 
|  | 15 |  | 
|  | 16 | void __init sclp_readinfo_early(void) | 
|  | 17 | { | 
|  | 18 | sclp_cmdw_t command; | 
|  | 19 | struct sccb_header *sccb; | 
|  | 20 | int ret; | 
|  | 21 |  | 
|  | 22 | __ctl_set_bit(0, 9); /* enable service signal subclass mask */ | 
|  | 23 |  | 
|  | 24 | sccb = &s390_readinfo_sccb.header; | 
|  | 25 | command = SCLP_CMDW_READ_SCP_INFO_FORCED; | 
|  | 26 | while (1) { | 
|  | 27 | u16 response; | 
|  | 28 |  | 
|  | 29 | memset(&s390_readinfo_sccb, 0, sizeof(s390_readinfo_sccb)); | 
|  | 30 | sccb->length = sizeof(s390_readinfo_sccb); | 
|  | 31 | sccb->control_mask[2] = 0x80; | 
|  | 32 |  | 
|  | 33 | ret = sclp_service_call(command, &s390_readinfo_sccb); | 
|  | 34 |  | 
|  | 35 | if (ret == -EIO) | 
|  | 36 | goto out; | 
|  | 37 | if (ret == -EBUSY) | 
|  | 38 | continue; | 
|  | 39 |  | 
|  | 40 | __load_psw_mask(PSW_BASE_BITS | PSW_MASK_EXT | | 
|  | 41 | PSW_MASK_WAIT | PSW_DEFAULT_KEY); | 
|  | 42 | local_irq_disable(); | 
|  | 43 | barrier(); | 
|  | 44 |  | 
|  | 45 | response = sccb->response_code; | 
|  | 46 |  | 
|  | 47 | if (response == 0x10) | 
|  | 48 | break; | 
|  | 49 |  | 
|  | 50 | if (response != 0x1f0 || command == SCLP_CMDW_READ_SCP_INFO) | 
|  | 51 | break; | 
|  | 52 |  | 
|  | 53 | command = SCLP_CMDW_READ_SCP_INFO; | 
|  | 54 | } | 
|  | 55 | out: | 
|  | 56 | __ctl_clear_bit(0, 9); /* disable service signal subclass mask */ | 
|  | 57 | } |