/*
* drivers/s390/cio/chsc.c
* S/390 common I/O routines -- channel subsystem call
- * $Revision: 1.112 $
+ * $Revision: 1.115 $
*
* Copyright (C) 1999-2002 IBM Deutschland Entwicklung GmbH,
* IBM Corporation
return -ENOMEM;
memset(chp, 0, sizeof(struct channel_path));
- chps[chpid] = chp;
-
/* fill in status, etc. */
chp->id = chpid;
chp->state = 1;
if (ret) {
printk(KERN_WARNING "%s: could not register %02x\n",
__func__, chpid);
- return ret;
+ goto out_free;
}
ret = device_create_file(&chp->dev, &dev_attr_status);
- if (ret)
+ if (ret) {
device_unregister(&chp->dev);
-
+ goto out_free;
+ } else
+ chps[chpid] = chp;
+ return ret;
+out_free:
+ kfree(chp);
return ret;
}
}
subsys_initcall(chsc_alloc_sei_area);
+
+struct css_general_char css_general_characteristics;
+struct css_chsc_char css_chsc_characteristics;
+
+int __init
+chsc_determine_css_characteristics(void)
+{
+ int result;
+ struct {
+ struct chsc_header request;
+ u32 reserved1;
+ u32 reserved2;
+ u32 reserved3;
+ struct chsc_header response;
+ u32 reserved4;
+ u32 general_char[510];
+ u32 chsc_char[518];
+ } *scsc_area;
+
+ scsc_area = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
+ if (!scsc_area) {
+ printk(KERN_WARNING"cio: Was not able to determine available" \
+ "CHSCs due to no memory.\n");
+ return -ENOMEM;
+ }
+
+ scsc_area->request = (struct chsc_header) {
+ .length = 0x0010,
+ .code = 0x0010,
+ };
+
+ result = chsc(scsc_area);
+ if (result) {
+ printk(KERN_WARNING"cio: Was not able to determine " \
+ "available CHSCs, cc=%i.\n", result);
+ result = -EIO;
+ goto exit;
+ }
+
+ if (scsc_area->response.code != 1) {
+ printk(KERN_WARNING"cio: Was not able to determine " \
+ "available CHSCs.\n");
+ result = -EIO;
+ goto exit;
+ }
+ memcpy(&css_general_characteristics, scsc_area->general_char,
+ sizeof(css_general_characteristics));
+ memcpy(&css_chsc_characteristics, scsc_area->chsc_char,
+ sizeof(css_chsc_characteristics));
+exit:
+ free_page ((unsigned long) scsc_area);
+ return result;
+}
+
+EXPORT_SYMBOL_GPL(css_general_characteristics);
+EXPORT_SYMBOL_GPL(css_chsc_characteristics);