diff options
Diffstat (limited to 'drivers/parisc')
-rw-r--r-- | drivers/parisc/ccio-dma.c | 7 | ||||
-rw-r--r-- | drivers/parisc/dino.c | 4 | ||||
-rw-r--r-- | drivers/parisc/hppb.c | 3 | ||||
-rw-r--r-- | drivers/parisc/iosapic.c | 8 | ||||
-rw-r--r-- | drivers/parisc/lasi.c | 5 | ||||
-rw-r--r-- | drivers/parisc/lba_pci.c | 6 | ||||
-rw-r--r-- | drivers/parisc/pdc_stable.c | 356 | ||||
-rw-r--r-- | drivers/parisc/sba_iommu.c | 3 | ||||
-rw-r--r-- | drivers/parisc/superio.c | 41 | ||||
-rw-r--r-- | drivers/parisc/wax.c | 2 |
10 files changed, 298 insertions, 137 deletions
diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c index 9e0229f7e25f..f46e8438e0d2 100644 --- a/drivers/parisc/ccio-dma.c +++ b/drivers/parisc/ccio-dma.c | |||
@@ -1423,7 +1423,7 @@ static void __init ccio_init_resources(struct ioc *ioc) | |||
1423 | struct resource *res = ioc->mmio_region; | 1423 | struct resource *res = ioc->mmio_region; |
1424 | char *name = kmalloc(14, GFP_KERNEL); | 1424 | char *name = kmalloc(14, GFP_KERNEL); |
1425 | 1425 | ||
1426 | sprintf(name, "GSC Bus [%d/]", ioc->hw_path); | 1426 | snprintf(name, 14, "GSC Bus [%d/]", ioc->hw_path); |
1427 | 1427 | ||
1428 | ccio_init_resource(res, name, &ioc->ioc_regs->io_io_low); | 1428 | ccio_init_resource(res, name, &ioc->ioc_regs->io_io_low); |
1429 | ccio_init_resource(res + 1, name, &ioc->ioc_regs->io_io_low_hv); | 1429 | ccio_init_resource(res + 1, name, &ioc->ioc_regs->io_io_low_hv); |
@@ -1557,12 +1557,11 @@ static int ccio_probe(struct parisc_device *dev) | |||
1557 | int i; | 1557 | int i; |
1558 | struct ioc *ioc, **ioc_p = &ioc_list; | 1558 | struct ioc *ioc, **ioc_p = &ioc_list; |
1559 | 1559 | ||
1560 | ioc = kmalloc(sizeof(struct ioc), GFP_KERNEL); | 1560 | ioc = kzalloc(sizeof(struct ioc), GFP_KERNEL); |
1561 | if (ioc == NULL) { | 1561 | if (ioc == NULL) { |
1562 | printk(KERN_ERR MODULE_NAME ": memory allocation failure\n"); | 1562 | printk(KERN_ERR MODULE_NAME ": memory allocation failure\n"); |
1563 | return 1; | 1563 | return 1; |
1564 | } | 1564 | } |
1565 | memset(ioc, 0, sizeof(struct ioc)); | ||
1566 | 1565 | ||
1567 | ioc->name = dev->id.hversion == U2_IOA_RUNWAY ? "U2" : "UTurn"; | 1566 | ioc->name = dev->id.hversion == U2_IOA_RUNWAY ? "U2" : "UTurn"; |
1568 | 1567 | ||
@@ -1578,7 +1577,7 @@ static int ccio_probe(struct parisc_device *dev) | |||
1578 | ccio_ioc_init(ioc); | 1577 | ccio_ioc_init(ioc); |
1579 | ccio_init_resources(ioc); | 1578 | ccio_init_resources(ioc); |
1580 | hppa_dma_ops = &ccio_ops; | 1579 | hppa_dma_ops = &ccio_ops; |
1581 | dev->dev.platform_data = kmalloc(sizeof(struct pci_hba_data), GFP_KERNEL); | 1580 | dev->dev.platform_data = kzalloc(sizeof(struct pci_hba_data), GFP_KERNEL); |
1582 | 1581 | ||
1583 | /* if this fails, no I/O cards will work, so may as well bug */ | 1582 | /* if this fails, no I/O cards will work, so may as well bug */ |
1584 | BUG_ON(dev->dev.platform_data == NULL); | 1583 | BUG_ON(dev->dev.platform_data == NULL); |
diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c index 216d1d859326..3d1a7f98c676 100644 --- a/drivers/parisc/dino.c +++ b/drivers/parisc/dino.c | |||
@@ -989,14 +989,12 @@ static int __init dino_probe(struct parisc_device *dev) | |||
989 | */ | 989 | */ |
990 | } | 990 | } |
991 | 991 | ||
992 | dino_dev = kmalloc(sizeof(struct dino_device), GFP_KERNEL); | 992 | dino_dev = kzalloc(sizeof(struct dino_device), GFP_KERNEL); |
993 | if (!dino_dev) { | 993 | if (!dino_dev) { |
994 | printk("dino_init_chip - couldn't alloc dino_device\n"); | 994 | printk("dino_init_chip - couldn't alloc dino_device\n"); |
995 | return 1; | 995 | return 1; |
996 | } | 996 | } |
997 | 997 | ||
998 | memset(dino_dev, 0, sizeof(struct dino_device)); | ||
999 | |||
1000 | dino_dev->hba.dev = dev; | 998 | dino_dev->hba.dev = dev; |
1001 | dino_dev->hba.base_addr = ioremap(hpa, 4096); | 999 | dino_dev->hba.base_addr = ioremap(hpa, 4096); |
1002 | dino_dev->hba.lmmio_space_offset = 0; /* CPU addrs == bus addrs */ | 1000 | dino_dev->hba.lmmio_space_offset = 0; /* CPU addrs == bus addrs */ |
diff --git a/drivers/parisc/hppb.c b/drivers/parisc/hppb.c index 5edf93f80757..07dc2b6d4e93 100644 --- a/drivers/parisc/hppb.c +++ b/drivers/parisc/hppb.c | |||
@@ -60,12 +60,11 @@ static int hppb_probe(struct parisc_device *dev) | |||
60 | } | 60 | } |
61 | 61 | ||
62 | if(card->hpa) { | 62 | if(card->hpa) { |
63 | card->next = kmalloc(sizeof(struct hppb_card), GFP_KERNEL); | 63 | card->next = kzalloc(sizeof(struct hppb_card), GFP_KERNEL); |
64 | if(!card->next) { | 64 | if(!card->next) { |
65 | printk(KERN_ERR "HP-PB: Unable to allocate memory.\n"); | 65 | printk(KERN_ERR "HP-PB: Unable to allocate memory.\n"); |
66 | return 1; | 66 | return 1; |
67 | } | 67 | } |
68 | memset(card->next, '\0', sizeof(struct hppb_card)); | ||
69 | card = card->next; | 68 | card = card->next; |
70 | } | 69 | } |
71 | printk(KERN_INFO "Found GeckoBoa at 0x%lx\n", dev->hpa.start); | 70 | printk(KERN_INFO "Found GeckoBoa at 0x%lx\n", dev->hpa.start); |
diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c index 19657efa8dc3..8d7a36392eb8 100644 --- a/drivers/parisc/iosapic.c +++ b/drivers/parisc/iosapic.c | |||
@@ -873,28 +873,24 @@ void *iosapic_register(unsigned long hpa) | |||
873 | return NULL; | 873 | return NULL; |
874 | } | 874 | } |
875 | 875 | ||
876 | isi = (struct iosapic_info *)kmalloc(sizeof(struct iosapic_info), GFP_KERNEL); | 876 | isi = (struct iosapic_info *)kzalloc(sizeof(struct iosapic_info), GFP_KERNEL); |
877 | if (!isi) { | 877 | if (!isi) { |
878 | BUG(); | 878 | BUG(); |
879 | return NULL; | 879 | return NULL; |
880 | } | 880 | } |
881 | 881 | ||
882 | memset(isi, 0, sizeof(struct iosapic_info)); | ||
883 | |||
884 | isi->addr = ioremap(hpa, 4096); | 882 | isi->addr = ioremap(hpa, 4096); |
885 | isi->isi_hpa = hpa; | 883 | isi->isi_hpa = hpa; |
886 | isi->isi_version = iosapic_rd_version(isi); | 884 | isi->isi_version = iosapic_rd_version(isi); |
887 | isi->isi_num_vectors = IOSAPIC_IRDT_MAX_ENTRY(isi->isi_version) + 1; | 885 | isi->isi_num_vectors = IOSAPIC_IRDT_MAX_ENTRY(isi->isi_version) + 1; |
888 | 886 | ||
889 | vip = isi->isi_vector = (struct vector_info *) | 887 | vip = isi->isi_vector = (struct vector_info *) |
890 | kmalloc(sizeof(struct vector_info) * isi->isi_num_vectors, GFP_KERNEL); | 888 | kzalloc(sizeof(struct vector_info) * isi->isi_num_vectors, GFP_KERNEL); |
891 | if (vip == NULL) { | 889 | if (vip == NULL) { |
892 | kfree(isi); | 890 | kfree(isi); |
893 | return NULL; | 891 | return NULL; |
894 | } | 892 | } |
895 | 893 | ||
896 | memset(vip, 0, sizeof(struct vector_info) * isi->isi_num_vectors); | ||
897 | |||
898 | for (cnt=0; cnt < isi->isi_num_vectors; cnt++, vip++) { | 894 | for (cnt=0; cnt < isi->isi_num_vectors; cnt++, vip++) { |
899 | vip->irqline = (unsigned char) cnt; | 895 | vip->irqline = (unsigned char) cnt; |
900 | vip->iosapic = isi; | 896 | vip->iosapic = isi; |
diff --git a/drivers/parisc/lasi.c b/drivers/parisc/lasi.c index 2b3ba1dcf332..cb3d28176129 100644 --- a/drivers/parisc/lasi.c +++ b/drivers/parisc/lasi.c | |||
@@ -166,11 +166,12 @@ static void lasi_power_off(void) | |||
166 | int __init | 166 | int __init |
167 | lasi_init_chip(struct parisc_device *dev) | 167 | lasi_init_chip(struct parisc_device *dev) |
168 | { | 168 | { |
169 | extern void (*chassis_power_off)(void); | ||
169 | struct gsc_asic *lasi; | 170 | struct gsc_asic *lasi; |
170 | struct gsc_irq gsc_irq; | 171 | struct gsc_irq gsc_irq; |
171 | int ret; | 172 | int ret; |
172 | 173 | ||
173 | lasi = kmalloc(sizeof(*lasi), GFP_KERNEL); | 174 | lasi = kzalloc(sizeof(*lasi), GFP_KERNEL); |
174 | if (!lasi) | 175 | if (!lasi) |
175 | return -ENOMEM; | 176 | return -ENOMEM; |
176 | 177 | ||
@@ -222,7 +223,7 @@ lasi_init_chip(struct parisc_device *dev) | |||
222 | * ensure that only the first LASI (the one controlling the power off) | 223 | * ensure that only the first LASI (the one controlling the power off) |
223 | * should set the HPA here */ | 224 | * should set the HPA here */ |
224 | lasi_power_off_hpa = lasi->hpa; | 225 | lasi_power_off_hpa = lasi->hpa; |
225 | pm_power_off = lasi_power_off; | 226 | chassis_power_off = lasi_power_off; |
226 | 227 | ||
227 | return ret; | 228 | return ret; |
228 | } | 229 | } |
diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c index cbae8c8963fa..e8a2a4a852f5 100644 --- a/drivers/parisc/lba_pci.c +++ b/drivers/parisc/lba_pci.c | |||
@@ -1565,7 +1565,7 @@ lba_driver_probe(struct parisc_device *dev) | |||
1565 | } else if (IS_MERCURY(dev) || IS_QUICKSILVER(dev)) { | 1565 | } else if (IS_MERCURY(dev) || IS_QUICKSILVER(dev)) { |
1566 | func_class &= 0xff; | 1566 | func_class &= 0xff; |
1567 | version = kmalloc(6, GFP_KERNEL); | 1567 | version = kmalloc(6, GFP_KERNEL); |
1568 | sprintf(version,"TR%d.%d",(func_class >> 4),(func_class & 0xf)); | 1568 | snprintf(version, 6, "TR%d.%d",(func_class >> 4),(func_class & 0xf)); |
1569 | /* We could use one printk for both Elroy and Mercury, | 1569 | /* We could use one printk for both Elroy and Mercury, |
1570 | * but for the mask for func_class. | 1570 | * but for the mask for func_class. |
1571 | */ | 1571 | */ |
@@ -1586,14 +1586,12 @@ lba_driver_probe(struct parisc_device *dev) | |||
1586 | ** have an IRT entry will get NULL back from iosapic code. | 1586 | ** have an IRT entry will get NULL back from iosapic code. |
1587 | */ | 1587 | */ |
1588 | 1588 | ||
1589 | lba_dev = kmalloc(sizeof(struct lba_device), GFP_KERNEL); | 1589 | lba_dev = kzalloc(sizeof(struct lba_device), GFP_KERNEL); |
1590 | if (!lba_dev) { | 1590 | if (!lba_dev) { |
1591 | printk(KERN_ERR "lba_init_chip - couldn't alloc lba_device\n"); | 1591 | printk(KERN_ERR "lba_init_chip - couldn't alloc lba_device\n"); |
1592 | return(1); | 1592 | return(1); |
1593 | } | 1593 | } |
1594 | 1594 | ||
1595 | memset(lba_dev, 0, sizeof(struct lba_device)); | ||
1596 | |||
1597 | 1595 | ||
1598 | /* ---------- First : initialize data we already have --------- */ | 1596 | /* ---------- First : initialize data we already have --------- */ |
1599 | 1597 | ||
diff --git a/drivers/parisc/pdc_stable.c b/drivers/parisc/pdc_stable.c index 42a3c54e8e6c..a28e17898fbd 100644 --- a/drivers/parisc/pdc_stable.c +++ b/drivers/parisc/pdc_stable.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Interfaces to retrieve and set PDC Stable options (firmware) | 2 | * Interfaces to retrieve and set PDC Stable options (firmware) |
3 | * | 3 | * |
4 | * Copyright (C) 2005 Thibaut VARENE <varenet@parisc-linux.org> | 4 | * Copyright (C) 2005-2006 Thibaut VARENE <varenet@parisc-linux.org> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
@@ -26,11 +26,19 @@ | |||
26 | * | 26 | * |
27 | * Since locations between 96 and 192 are the various paths, most (if not | 27 | * Since locations between 96 and 192 are the various paths, most (if not |
28 | * all) PA-RISC machines should have them. Anyway, for safety reasons, the | 28 | * all) PA-RISC machines should have them. Anyway, for safety reasons, the |
29 | * following code can deal with only 96 bytes of Stable Storage, and all | 29 | * following code can deal with just 96 bytes of Stable Storage, and all |
30 | * sizes between 96 and 192 bytes (provided they are multiple of struct | 30 | * sizes between 96 and 192 bytes (provided they are multiple of struct |
31 | * device_path size, eg: 128, 160 and 192) to provide full information. | 31 | * device_path size, eg: 128, 160 and 192) to provide full information. |
32 | * The code makes no use of data above 192 bytes. One last word: there's one | 32 | * The code makes no use of data above 192 bytes. One last word: there's one |
33 | * path we can always count on: the primary path. | 33 | * path we can always count on: the primary path. |
34 | * | ||
35 | * The current policy wrt file permissions is: | ||
36 | * - write: root only | ||
37 | * - read: (reading triggers PDC calls) ? root only : everyone | ||
38 | * The rationale is that PDC calls could hog (DoS) the machine. | ||
39 | * | ||
40 | * TODO: | ||
41 | * - timer/fastsize write calls | ||
34 | */ | 42 | */ |
35 | 43 | ||
36 | #undef PDCS_DEBUG | 44 | #undef PDCS_DEBUG |
@@ -50,13 +58,15 @@ | |||
50 | #include <linux/kobject.h> | 58 | #include <linux/kobject.h> |
51 | #include <linux/device.h> | 59 | #include <linux/device.h> |
52 | #include <linux/errno.h> | 60 | #include <linux/errno.h> |
61 | #include <linux/spinlock.h> | ||
53 | 62 | ||
54 | #include <asm/pdc.h> | 63 | #include <asm/pdc.h> |
55 | #include <asm/page.h> | 64 | #include <asm/page.h> |
56 | #include <asm/uaccess.h> | 65 | #include <asm/uaccess.h> |
57 | #include <asm/hardware.h> | 66 | #include <asm/hardware.h> |
58 | 67 | ||
59 | #define PDCS_VERSION "0.10" | 68 | #define PDCS_VERSION "0.22" |
69 | #define PDCS_PREFIX "PDC Stable Storage" | ||
60 | 70 | ||
61 | #define PDCS_ADDR_PPRI 0x00 | 71 | #define PDCS_ADDR_PPRI 0x00 |
62 | #define PDCS_ADDR_OSID 0x40 | 72 | #define PDCS_ADDR_OSID 0x40 |
@@ -70,10 +80,12 @@ MODULE_DESCRIPTION("sysfs interface to HP PDC Stable Storage data"); | |||
70 | MODULE_LICENSE("GPL"); | 80 | MODULE_LICENSE("GPL"); |
71 | MODULE_VERSION(PDCS_VERSION); | 81 | MODULE_VERSION(PDCS_VERSION); |
72 | 82 | ||
83 | /* holds Stable Storage size. Initialized once and for all, no lock needed */ | ||
73 | static unsigned long pdcs_size __read_mostly; | 84 | static unsigned long pdcs_size __read_mostly; |
74 | 85 | ||
75 | /* This struct defines what we need to deal with a parisc pdc path entry */ | 86 | /* This struct defines what we need to deal with a parisc pdc path entry */ |
76 | struct pdcspath_entry { | 87 | struct pdcspath_entry { |
88 | rwlock_t rw_lock; /* to protect path entry access */ | ||
77 | short ready; /* entry record is valid if != 0 */ | 89 | short ready; /* entry record is valid if != 0 */ |
78 | unsigned long addr; /* entry address in stable storage */ | 90 | unsigned long addr; /* entry address in stable storage */ |
79 | char *name; /* entry name */ | 91 | char *name; /* entry name */ |
@@ -121,6 +133,8 @@ struct pdcspath_attribute paths_attr_##_name = { \ | |||
121 | * content of the stable storage WRT various paths in these structs. We read | 133 | * content of the stable storage WRT various paths in these structs. We read |
122 | * these structs when reading the files, and we will write to these structs when | 134 | * these structs when reading the files, and we will write to these structs when |
123 | * writing to the files, and only then write them back to the Stable Storage. | 135 | * writing to the files, and only then write them back to the Stable Storage. |
136 | * | ||
137 | * This function expects to be called with @entry->rw_lock write-hold. | ||
124 | */ | 138 | */ |
125 | static int | 139 | static int |
126 | pdcspath_fetch(struct pdcspath_entry *entry) | 140 | pdcspath_fetch(struct pdcspath_entry *entry) |
@@ -160,14 +174,15 @@ pdcspath_fetch(struct pdcspath_entry *entry) | |||
160 | * pointer, from which it'll find out the corresponding hardware path. | 174 | * pointer, from which it'll find out the corresponding hardware path. |
161 | * For now we do not handle the case where there's an error in writing to the | 175 | * For now we do not handle the case where there's an error in writing to the |
162 | * Stable Storage area, so you'd better not mess up the data :P | 176 | * Stable Storage area, so you'd better not mess up the data :P |
177 | * | ||
178 | * This function expects to be called with @entry->rw_lock write-hold. | ||
163 | */ | 179 | */ |
164 | static int | 180 | static void |
165 | pdcspath_store(struct pdcspath_entry *entry) | 181 | pdcspath_store(struct pdcspath_entry *entry) |
166 | { | 182 | { |
167 | struct device_path *devpath; | 183 | struct device_path *devpath; |
168 | 184 | ||
169 | if (!entry) | 185 | BUG_ON(!entry); |
170 | return -EINVAL; | ||
171 | 186 | ||
172 | devpath = &entry->devpath; | 187 | devpath = &entry->devpath; |
173 | 188 | ||
@@ -176,10 +191,8 @@ pdcspath_store(struct pdcspath_entry *entry) | |||
176 | First case, we don't have a preset hwpath... */ | 191 | First case, we don't have a preset hwpath... */ |
177 | if (!entry->ready) { | 192 | if (!entry->ready) { |
178 | /* ...but we have a device, map it */ | 193 | /* ...but we have a device, map it */ |
179 | if (entry->dev) | 194 | BUG_ON(!entry->dev); |
180 | device_to_hwpath(entry->dev, (struct hardware_path *)devpath); | 195 | device_to_hwpath(entry->dev, (struct hardware_path *)devpath); |
181 | else | ||
182 | return -EINVAL; | ||
183 | } | 196 | } |
184 | /* else, we expect the provided hwpath to be valid. */ | 197 | /* else, we expect the provided hwpath to be valid. */ |
185 | 198 | ||
@@ -191,15 +204,13 @@ pdcspath_store(struct pdcspath_entry *entry) | |||
191 | printk(KERN_ERR "%s: an error occured when writing to PDC.\n" | 204 | printk(KERN_ERR "%s: an error occured when writing to PDC.\n" |
192 | "It is likely that the Stable Storage data has been corrupted.\n" | 205 | "It is likely that the Stable Storage data has been corrupted.\n" |
193 | "Please check it carefully upon next reboot.\n", __func__); | 206 | "Please check it carefully upon next reboot.\n", __func__); |
194 | return -EIO; | 207 | WARN_ON(1); |
195 | } | 208 | } |
196 | 209 | ||
197 | /* kobject is already registered */ | 210 | /* kobject is already registered */ |
198 | entry->ready = 2; | 211 | entry->ready = 2; |
199 | 212 | ||
200 | DPRINTK("%s: device: 0x%p\n", __func__, entry->dev); | 213 | DPRINTK("%s: device: 0x%p\n", __func__, entry->dev); |
201 | |||
202 | return 0; | ||
203 | } | 214 | } |
204 | 215 | ||
205 | /** | 216 | /** |
@@ -214,14 +225,17 @@ pdcspath_hwpath_read(struct pdcspath_entry *entry, char *buf) | |||
214 | { | 225 | { |
215 | char *out = buf; | 226 | char *out = buf; |
216 | struct device_path *devpath; | 227 | struct device_path *devpath; |
217 | unsigned short i; | 228 | short i; |
218 | 229 | ||
219 | if (!entry || !buf) | 230 | if (!entry || !buf) |
220 | return -EINVAL; | 231 | return -EINVAL; |
221 | 232 | ||
233 | read_lock(&entry->rw_lock); | ||
222 | devpath = &entry->devpath; | 234 | devpath = &entry->devpath; |
235 | i = entry->ready; | ||
236 | read_unlock(&entry->rw_lock); | ||
223 | 237 | ||
224 | if (!entry->ready) | 238 | if (!i) /* entry is not ready */ |
225 | return -ENODATA; | 239 | return -ENODATA; |
226 | 240 | ||
227 | for (i = 0; i < 6; i++) { | 241 | for (i = 0; i < 6; i++) { |
@@ -242,7 +256,7 @@ pdcspath_hwpath_read(struct pdcspath_entry *entry, char *buf) | |||
242 | * | 256 | * |
243 | * We will call this function to change the current hardware path. | 257 | * We will call this function to change the current hardware path. |
244 | * Hardware paths are to be given '/'-delimited, without brackets. | 258 | * Hardware paths are to be given '/'-delimited, without brackets. |
245 | * We take care to make sure that the provided path actually maps to an existing | 259 | * We make sure that the provided path actually maps to an existing |
246 | * device, BUT nothing would prevent some foolish user to set the path to some | 260 | * device, BUT nothing would prevent some foolish user to set the path to some |
247 | * PCI bridge or even a CPU... | 261 | * PCI bridge or even a CPU... |
248 | * A better work around would be to make sure we are at the end of a device tree | 262 | * A better work around would be to make sure we are at the end of a device tree |
@@ -298,17 +312,19 @@ pdcspath_hwpath_write(struct pdcspath_entry *entry, const char *buf, size_t coun | |||
298 | } | 312 | } |
299 | 313 | ||
300 | /* So far so good, let's get in deep */ | 314 | /* So far so good, let's get in deep */ |
315 | write_lock(&entry->rw_lock); | ||
301 | entry->ready = 0; | 316 | entry->ready = 0; |
302 | entry->dev = dev; | 317 | entry->dev = dev; |
303 | 318 | ||
304 | /* Now, dive in. Write back to the hardware */ | 319 | /* Now, dive in. Write back to the hardware */ |
305 | WARN_ON(pdcspath_store(entry)); /* this warn should *NEVER* happen */ | 320 | pdcspath_store(entry); |
306 | 321 | ||
307 | /* Update the symlink to the real device */ | 322 | /* Update the symlink to the real device */ |
308 | sysfs_remove_link(&entry->kobj, "device"); | 323 | sysfs_remove_link(&entry->kobj, "device"); |
309 | sysfs_create_link(&entry->kobj, &entry->dev->kobj, "device"); | 324 | sysfs_create_link(&entry->kobj, &entry->dev->kobj, "device"); |
325 | write_unlock(&entry->rw_lock); | ||
310 | 326 | ||
311 | printk(KERN_INFO "PDC Stable Storage: changed \"%s\" path to \"%s\"\n", | 327 | printk(KERN_INFO PDCS_PREFIX ": changed \"%s\" path to \"%s\"\n", |
312 | entry->name, buf); | 328 | entry->name, buf); |
313 | 329 | ||
314 | return count; | 330 | return count; |
@@ -326,14 +342,17 @@ pdcspath_layer_read(struct pdcspath_entry *entry, char *buf) | |||
326 | { | 342 | { |
327 | char *out = buf; | 343 | char *out = buf; |
328 | struct device_path *devpath; | 344 | struct device_path *devpath; |
329 | unsigned short i; | 345 | short i; |
330 | 346 | ||
331 | if (!entry || !buf) | 347 | if (!entry || !buf) |
332 | return -EINVAL; | 348 | return -EINVAL; |
333 | 349 | ||
350 | read_lock(&entry->rw_lock); | ||
334 | devpath = &entry->devpath; | 351 | devpath = &entry->devpath; |
352 | i = entry->ready; | ||
353 | read_unlock(&entry->rw_lock); | ||
335 | 354 | ||
336 | if (!entry->ready) | 355 | if (!i) /* entry is not ready */ |
337 | return -ENODATA; | 356 | return -ENODATA; |
338 | 357 | ||
339 | for (i = 0; devpath->layers[i] && (likely(i < 6)); i++) | 358 | for (i = 0; devpath->layers[i] && (likely(i < 6)); i++) |
@@ -388,15 +407,17 @@ pdcspath_layer_write(struct pdcspath_entry *entry, const char *buf, size_t count | |||
388 | } | 407 | } |
389 | 408 | ||
390 | /* So far so good, let's get in deep */ | 409 | /* So far so good, let's get in deep */ |
410 | write_lock(&entry->rw_lock); | ||
391 | 411 | ||
392 | /* First, overwrite the current layers with the new ones, not touching | 412 | /* First, overwrite the current layers with the new ones, not touching |
393 | the hardware path. */ | 413 | the hardware path. */ |
394 | memcpy(&entry->devpath.layers, &layers, sizeof(layers)); | 414 | memcpy(&entry->devpath.layers, &layers, sizeof(layers)); |
395 | 415 | ||
396 | /* Now, dive in. Write back to the hardware */ | 416 | /* Now, dive in. Write back to the hardware */ |
397 | WARN_ON(pdcspath_store(entry)); /* this warn should *NEVER* happen */ | 417 | pdcspath_store(entry); |
418 | write_unlock(&entry->rw_lock); | ||
398 | 419 | ||
399 | printk(KERN_INFO "PDC Stable Storage: changed \"%s\" layers to \"%s\"\n", | 420 | printk(KERN_INFO PDCS_PREFIX ": changed \"%s\" layers to \"%s\"\n", |
400 | entry->name, buf); | 421 | entry->name, buf); |
401 | 422 | ||
402 | return count; | 423 | return count; |
@@ -415,9 +436,6 @@ pdcspath_attr_show(struct kobject *kobj, struct attribute *attr, char *buf) | |||
415 | struct pdcspath_attribute *pdcs_attr = to_pdcspath_attribute(attr); | 436 | struct pdcspath_attribute *pdcs_attr = to_pdcspath_attribute(attr); |
416 | ssize_t ret = 0; | 437 | ssize_t ret = 0; |
417 | 438 | ||
418 | if (!capable(CAP_SYS_ADMIN)) | ||
419 | return -EACCES; | ||
420 | |||
421 | if (pdcs_attr->show) | 439 | if (pdcs_attr->show) |
422 | ret = pdcs_attr->show(entry, buf); | 440 | ret = pdcs_attr->show(entry, buf); |
423 | 441 | ||
@@ -454,8 +472,8 @@ static struct sysfs_ops pdcspath_attr_ops = { | |||
454 | }; | 472 | }; |
455 | 473 | ||
456 | /* These are the two attributes of any PDC path. */ | 474 | /* These are the two attributes of any PDC path. */ |
457 | static PATHS_ATTR(hwpath, 0600, pdcspath_hwpath_read, pdcspath_hwpath_write); | 475 | static PATHS_ATTR(hwpath, 0644, pdcspath_hwpath_read, pdcspath_hwpath_write); |
458 | static PATHS_ATTR(layer, 0600, pdcspath_layer_read, pdcspath_layer_write); | 476 | static PATHS_ATTR(layer, 0644, pdcspath_layer_read, pdcspath_layer_write); |
459 | 477 | ||
460 | static struct attribute *paths_subsys_attrs[] = { | 478 | static struct attribute *paths_subsys_attrs[] = { |
461 | &paths_attr_hwpath.attr, | 479 | &paths_attr_hwpath.attr, |
@@ -484,36 +502,119 @@ static struct pdcspath_entry *pdcspath_entries[] = { | |||
484 | NULL, | 502 | NULL, |
485 | }; | 503 | }; |
486 | 504 | ||
505 | |||
506 | /* For more insight of what's going on here, refer to PDC Procedures doc, | ||
507 | * Section PDC_STABLE */ | ||
508 | |||
487 | /** | 509 | /** |
488 | * pdcs_info_read - Pretty printing of the remaining useful data. | 510 | * pdcs_size_read - Stable Storage size output. |
489 | * @entry: An allocated and populated subsytem struct. We don't use it tho. | 511 | * @entry: An allocated and populated subsytem struct. We don't use it tho. |
490 | * @buf: The output buffer to write to. | 512 | * @buf: The output buffer to write to. |
491 | * | ||
492 | * We will call this function to format the output of the 'info' attribute file. | ||
493 | * Please refer to PDC Procedures documentation, section PDC_STABLE to get a | ||
494 | * better insight of what we're doing here. | ||
495 | */ | 513 | */ |
496 | static ssize_t | 514 | static ssize_t |
497 | pdcs_info_read(struct subsystem *entry, char *buf) | 515 | pdcs_size_read(struct subsystem *entry, char *buf) |
498 | { | 516 | { |
499 | char *out = buf; | 517 | char *out = buf; |
500 | __u32 result; | ||
501 | struct device_path devpath; | ||
502 | char *tmpstr = NULL; | ||
503 | 518 | ||
504 | if (!entry || !buf) | 519 | if (!entry || !buf) |
505 | return -EINVAL; | 520 | return -EINVAL; |
506 | 521 | ||
507 | /* show the size of the stable storage */ | 522 | /* show the size of the stable storage */ |
508 | out += sprintf(out, "Stable Storage size: %ld bytes\n", pdcs_size); | 523 | out += sprintf(out, "%ld\n", pdcs_size); |
509 | 524 | ||
510 | /* deal with flags */ | 525 | return out - buf; |
511 | if (pdc_stable_read(PDCS_ADDR_PPRI, &devpath, sizeof(devpath)) != PDC_OK) | 526 | } |
512 | return -EIO; | 527 | |
528 | /** | ||
529 | * pdcs_auto_read - Stable Storage autoboot/search flag output. | ||
530 | * @entry: An allocated and populated subsytem struct. We don't use it tho. | ||
531 | * @buf: The output buffer to write to. | ||
532 | * @knob: The PF_AUTOBOOT or PF_AUTOSEARCH flag | ||
533 | */ | ||
534 | static ssize_t | ||
535 | pdcs_auto_read(struct subsystem *entry, char *buf, int knob) | ||
536 | { | ||
537 | char *out = buf; | ||
538 | struct pdcspath_entry *pathentry; | ||
513 | 539 | ||
514 | out += sprintf(out, "Autoboot: %s\n", (devpath.flags & PF_AUTOBOOT) ? "On" : "Off"); | 540 | if (!entry || !buf) |
515 | out += sprintf(out, "Autosearch: %s\n", (devpath.flags & PF_AUTOSEARCH) ? "On" : "Off"); | 541 | return -EINVAL; |
516 | out += sprintf(out, "Timer: %u s\n", (devpath.flags & PF_TIMER) ? (1 << (devpath.flags & PF_TIMER)) : 0); | 542 | |
543 | /* Current flags are stored in primary boot path entry */ | ||
544 | pathentry = &pdcspath_entry_primary; | ||
545 | |||
546 | read_lock(&pathentry->rw_lock); | ||
547 | out += sprintf(out, "%s\n", (pathentry->devpath.flags & knob) ? | ||
548 | "On" : "Off"); | ||
549 | read_unlock(&pathentry->rw_lock); | ||
550 | |||
551 | return out - buf; | ||
552 | } | ||
553 | |||
554 | /** | ||
555 | * pdcs_autoboot_read - Stable Storage autoboot flag output. | ||
556 | * @entry: An allocated and populated subsytem struct. We don't use it tho. | ||
557 | * @buf: The output buffer to write to. | ||
558 | */ | ||
559 | static inline ssize_t | ||
560 | pdcs_autoboot_read(struct subsystem *entry, char *buf) | ||
561 | { | ||
562 | return pdcs_auto_read(entry, buf, PF_AUTOBOOT); | ||
563 | } | ||
564 | |||
565 | /** | ||
566 | * pdcs_autosearch_read - Stable Storage autoboot flag output. | ||
567 | * @entry: An allocated and populated subsytem struct. We don't use it tho. | ||
568 | * @buf: The output buffer to write to. | ||
569 | */ | ||
570 | static inline ssize_t | ||
571 | pdcs_autosearch_read(struct subsystem *entry, char *buf) | ||
572 | { | ||
573 | return pdcs_auto_read(entry, buf, PF_AUTOSEARCH); | ||
574 | } | ||
575 | |||
576 | /** | ||
577 | * pdcs_timer_read - Stable Storage timer count output (in seconds). | ||
578 | * @entry: An allocated and populated subsytem struct. We don't use it tho. | ||
579 | * @buf: The output buffer to write to. | ||
580 | * | ||
581 | * The value of the timer field correponds to a number of seconds in powers of 2. | ||
582 | */ | ||
583 | static ssize_t | ||
584 | pdcs_timer_read(struct subsystem *entry, char *buf) | ||
585 | { | ||
586 | char *out = buf; | ||
587 | struct pdcspath_entry *pathentry; | ||
588 | |||
589 | if (!entry || !buf) | ||
590 | return -EINVAL; | ||
591 | |||
592 | /* Current flags are stored in primary boot path entry */ | ||
593 | pathentry = &pdcspath_entry_primary; | ||
594 | |||
595 | /* print the timer value in seconds */ | ||
596 | read_lock(&pathentry->rw_lock); | ||
597 | out += sprintf(out, "%u\n", (pathentry->devpath.flags & PF_TIMER) ? | ||
598 | (1 << (pathentry->devpath.flags & PF_TIMER)) : 0); | ||
599 | read_unlock(&pathentry->rw_lock); | ||
600 | |||
601 | return out - buf; | ||
602 | } | ||
603 | |||
604 | /** | ||
605 | * pdcs_osid_read - Stable Storage OS ID register output. | ||
606 | * @entry: An allocated and populated subsytem struct. We don't use it tho. | ||
607 | * @buf: The output buffer to write to. | ||
608 | */ | ||
609 | static ssize_t | ||
610 | pdcs_osid_read(struct subsystem *entry, char *buf) | ||
611 | { | ||
612 | char *out = buf; | ||
613 | __u32 result; | ||
614 | char *tmpstr = NULL; | ||
615 | |||
616 | if (!entry || !buf) | ||
617 | return -EINVAL; | ||
517 | 618 | ||
518 | /* get OSID */ | 619 | /* get OSID */ |
519 | if (pdc_stable_read(PDCS_ADDR_OSID, &result, sizeof(result)) != PDC_OK) | 620 | if (pdc_stable_read(PDCS_ADDR_OSID, &result, sizeof(result)) != PDC_OK) |
@@ -529,13 +630,31 @@ pdcs_info_read(struct subsystem *entry, char *buf) | |||
529 | case 0x0005: tmpstr = "Novell Netware dependent data"; break; | 630 | case 0x0005: tmpstr = "Novell Netware dependent data"; break; |
530 | default: tmpstr = "Unknown"; break; | 631 | default: tmpstr = "Unknown"; break; |
531 | } | 632 | } |
532 | out += sprintf(out, "OS ID: %s (0x%.4x)\n", tmpstr, (result >> 16)); | 633 | out += sprintf(out, "%s (0x%.4x)\n", tmpstr, (result >> 16)); |
634 | |||
635 | return out - buf; | ||
636 | } | ||
637 | |||
638 | /** | ||
639 | * pdcs_fastsize_read - Stable Storage FastSize register output. | ||
640 | * @entry: An allocated and populated subsytem struct. We don't use it tho. | ||
641 | * @buf: The output buffer to write to. | ||
642 | * | ||
643 | * This register holds the amount of system RAM to be tested during boot sequence. | ||
644 | */ | ||
645 | static ssize_t | ||
646 | pdcs_fastsize_read(struct subsystem *entry, char *buf) | ||
647 | { | ||
648 | char *out = buf; | ||
649 | __u32 result; | ||
650 | |||
651 | if (!entry || !buf) | ||
652 | return -EINVAL; | ||
533 | 653 | ||
534 | /* get fast-size */ | 654 | /* get fast-size */ |
535 | if (pdc_stable_read(PDCS_ADDR_FSIZ, &result, sizeof(result)) != PDC_OK) | 655 | if (pdc_stable_read(PDCS_ADDR_FSIZ, &result, sizeof(result)) != PDC_OK) |
536 | return -EIO; | 656 | return -EIO; |
537 | 657 | ||
538 | out += sprintf(out, "Memory tested: "); | ||
539 | if ((result & 0x0F) < 0x0E) | 658 | if ((result & 0x0F) < 0x0E) |
540 | out += sprintf(out, "%d kB", (1<<(result & 0x0F))*256); | 659 | out += sprintf(out, "%d kB", (1<<(result & 0x0F))*256); |
541 | else | 660 | else |
@@ -546,22 +665,18 @@ pdcs_info_read(struct subsystem *entry, char *buf) | |||
546 | } | 665 | } |
547 | 666 | ||
548 | /** | 667 | /** |
549 | * pdcs_info_write - This function handles boot flag modifying. | 668 | * pdcs_auto_write - This function handles autoboot/search flag modifying. |
550 | * @entry: An allocated and populated subsytem struct. We don't use it tho. | 669 | * @entry: An allocated and populated subsytem struct. We don't use it tho. |
551 | * @buf: The input buffer to read from. | 670 | * @buf: The input buffer to read from. |
552 | * @count: The number of bytes to be read. | 671 | * @count: The number of bytes to be read. |
672 | * @knob: The PF_AUTOBOOT or PF_AUTOSEARCH flag | ||
553 | * | 673 | * |
554 | * We will call this function to change the current boot flags. | 674 | * We will call this function to change the current autoboot flag. |
555 | * We expect a precise syntax: | 675 | * We expect a precise syntax: |
556 | * \"n n\" (n == 0 or 1) to toggle respectively AutoBoot and AutoSearch | 676 | * \"n\" (n == 0 or 1) to toggle AutoBoot Off or On |
557 | * | ||
558 | * As of now there is no incentive on my side to provide more "knobs" to that | ||
559 | * interface, since modifying the rest of the data is pretty meaningless when | ||
560 | * the machine is running and for the expected use of that facility, such as | ||
561 | * PALO setting up the boot disk when installing a Linux distribution... | ||
562 | */ | 677 | */ |
563 | static ssize_t | 678 | static ssize_t |
564 | pdcs_info_write(struct subsystem *entry, const char *buf, size_t count) | 679 | pdcs_auto_write(struct subsystem *entry, const char *buf, size_t count, int knob) |
565 | { | 680 | { |
566 | struct pdcspath_entry *pathentry; | 681 | struct pdcspath_entry *pathentry; |
567 | unsigned char flags; | 682 | unsigned char flags; |
@@ -582,7 +697,9 @@ pdcs_info_write(struct subsystem *entry, const char *buf, size_t count) | |||
582 | pathentry = &pdcspath_entry_primary; | 697 | pathentry = &pdcspath_entry_primary; |
583 | 698 | ||
584 | /* Be nice to the existing flag record */ | 699 | /* Be nice to the existing flag record */ |
700 | read_lock(&pathentry->rw_lock); | ||
585 | flags = pathentry->devpath.flags; | 701 | flags = pathentry->devpath.flags; |
702 | read_unlock(&pathentry->rw_lock); | ||
586 | 703 | ||
587 | DPRINTK("%s: flags before: 0x%X\n", __func__, flags); | 704 | DPRINTK("%s: flags before: 0x%X\n", __func__, flags); |
588 | 705 | ||
@@ -595,50 +712,85 @@ pdcs_info_write(struct subsystem *entry, const char *buf, size_t count) | |||
595 | if ((c != 0) && (c != 1)) | 712 | if ((c != 0) && (c != 1)) |
596 | goto parse_error; | 713 | goto parse_error; |
597 | if (c == 0) | 714 | if (c == 0) |
598 | flags &= ~PF_AUTOBOOT; | 715 | flags &= ~knob; |
599 | else | 716 | else |
600 | flags |= PF_AUTOBOOT; | 717 | flags |= knob; |
601 | |||
602 | if (*temp++ != ' ') | ||
603 | goto parse_error; | ||
604 | |||
605 | c = *temp++ - '0'; | ||
606 | if ((c != 0) && (c != 1)) | ||
607 | goto parse_error; | ||
608 | if (c == 0) | ||
609 | flags &= ~PF_AUTOSEARCH; | ||
610 | else | ||
611 | flags |= PF_AUTOSEARCH; | ||
612 | 718 | ||
613 | DPRINTK("%s: flags after: 0x%X\n", __func__, flags); | 719 | DPRINTK("%s: flags after: 0x%X\n", __func__, flags); |
614 | 720 | ||
615 | /* So far so good, let's get in deep */ | 721 | /* So far so good, let's get in deep */ |
722 | write_lock(&pathentry->rw_lock); | ||
616 | 723 | ||
617 | /* Change the path entry flags first */ | 724 | /* Change the path entry flags first */ |
618 | pathentry->devpath.flags = flags; | 725 | pathentry->devpath.flags = flags; |
619 | 726 | ||
620 | /* Now, dive in. Write back to the hardware */ | 727 | /* Now, dive in. Write back to the hardware */ |
621 | WARN_ON(pdcspath_store(pathentry)); /* this warn should *NEVER* happen */ | 728 | pdcspath_store(pathentry); |
729 | write_unlock(&pathentry->rw_lock); | ||
622 | 730 | ||
623 | printk(KERN_INFO "PDC Stable Storage: changed flags to \"%s\"\n", buf); | 731 | printk(KERN_INFO PDCS_PREFIX ": changed \"%s\" to \"%s\"\n", |
732 | (knob & PF_AUTOBOOT) ? "autoboot" : "autosearch", | ||
733 | (flags & knob) ? "On" : "Off"); | ||
624 | 734 | ||
625 | return count; | 735 | return count; |
626 | 736 | ||
627 | parse_error: | 737 | parse_error: |
628 | printk(KERN_WARNING "%s: Parse error: expect \"n n\" (n == 0 or 1) for AB and AS\n", __func__); | 738 | printk(KERN_WARNING "%s: Parse error: expect \"n\" (n == 0 or 1)\n", __func__); |
629 | return -EINVAL; | 739 | return -EINVAL; |
630 | } | 740 | } |
631 | 741 | ||
632 | /* The last attribute (the 'root' one actually) with all remaining data. */ | 742 | /** |
633 | static PDCS_ATTR(info, 0600, pdcs_info_read, pdcs_info_write); | 743 | * pdcs_autoboot_write - This function handles autoboot flag modifying. |
744 | * @entry: An allocated and populated subsytem struct. We don't use it tho. | ||
745 | * @buf: The input buffer to read from. | ||
746 | * @count: The number of bytes to be read. | ||
747 | * | ||
748 | * We will call this function to change the current boot flags. | ||
749 | * We expect a precise syntax: | ||
750 | * \"n\" (n == 0 or 1) to toggle AutoSearch Off or On | ||
751 | */ | ||
752 | static inline ssize_t | ||
753 | pdcs_autoboot_write(struct subsystem *entry, const char *buf, size_t count) | ||
754 | { | ||
755 | return pdcs_auto_write(entry, buf, count, PF_AUTOBOOT); | ||
756 | } | ||
757 | |||
758 | /** | ||
759 | * pdcs_autosearch_write - This function handles autosearch flag modifying. | ||
760 | * @entry: An allocated and populated subsytem struct. We don't use it tho. | ||
761 | * @buf: The input buffer to read from. | ||
762 | * @count: The number of bytes to be read. | ||
763 | * | ||
764 | * We will call this function to change the current boot flags. | ||
765 | * We expect a precise syntax: | ||
766 | * \"n\" (n == 0 or 1) to toggle AutoSearch Off or On | ||
767 | */ | ||
768 | static inline ssize_t | ||
769 | pdcs_autosearch_write(struct subsystem *entry, const char *buf, size_t count) | ||
770 | { | ||
771 | return pdcs_auto_write(entry, buf, count, PF_AUTOSEARCH); | ||
772 | } | ||
773 | |||
774 | /* The remaining attributes. */ | ||
775 | static PDCS_ATTR(size, 0444, pdcs_size_read, NULL); | ||
776 | static PDCS_ATTR(autoboot, 0644, pdcs_autoboot_read, pdcs_autoboot_write); | ||
777 | static PDCS_ATTR(autosearch, 0644, pdcs_autosearch_read, pdcs_autosearch_write); | ||
778 | static PDCS_ATTR(timer, 0444, pdcs_timer_read, NULL); | ||
779 | static PDCS_ATTR(osid, 0400, pdcs_osid_read, NULL); | ||
780 | static PDCS_ATTR(fastsize, 0400, pdcs_fastsize_read, NULL); | ||
634 | 781 | ||
635 | static struct subsys_attribute *pdcs_subsys_attrs[] = { | 782 | static struct subsys_attribute *pdcs_subsys_attrs[] = { |
636 | &pdcs_attr_info, | 783 | &pdcs_attr_size, |
637 | NULL, /* maybe more in the future? */ | 784 | &pdcs_attr_autoboot, |
785 | &pdcs_attr_autosearch, | ||
786 | &pdcs_attr_timer, | ||
787 | &pdcs_attr_osid, | ||
788 | &pdcs_attr_fastsize, | ||
789 | NULL, | ||
638 | }; | 790 | }; |
639 | 791 | ||
640 | static decl_subsys(paths, &ktype_pdcspath, NULL); | 792 | static decl_subsys(paths, &ktype_pdcspath, NULL); |
641 | static decl_subsys(pdc, NULL, NULL); | 793 | static decl_subsys(stable, NULL, NULL); |
642 | 794 | ||
643 | /** | 795 | /** |
644 | * pdcs_register_pathentries - Prepares path entries kobjects for sysfs usage. | 796 | * pdcs_register_pathentries - Prepares path entries kobjects for sysfs usage. |
@@ -656,8 +808,16 @@ pdcs_register_pathentries(void) | |||
656 | struct pdcspath_entry *entry; | 808 | struct pdcspath_entry *entry; |
657 | int err; | 809 | int err; |
658 | 810 | ||
811 | /* Initialize the entries rw_lock before anything else */ | ||
812 | for (i = 0; (entry = pdcspath_entries[i]); i++) | ||
813 | rwlock_init(&entry->rw_lock); | ||
814 | |||
659 | for (i = 0; (entry = pdcspath_entries[i]); i++) { | 815 | for (i = 0; (entry = pdcspath_entries[i]); i++) { |
660 | if (pdcspath_fetch(entry) < 0) | 816 | write_lock(&entry->rw_lock); |
817 | err = pdcspath_fetch(entry); | ||
818 | write_unlock(&entry->rw_lock); | ||
819 | |||
820 | if (err < 0) | ||
661 | continue; | 821 | continue; |
662 | 822 | ||
663 | if ((err = kobject_set_name(&entry->kobj, "%s", entry->name))) | 823 | if ((err = kobject_set_name(&entry->kobj, "%s", entry->name))) |
@@ -667,13 +827,14 @@ pdcs_register_pathentries(void) | |||
667 | return err; | 827 | return err; |
668 | 828 | ||
669 | /* kobject is now registered */ | 829 | /* kobject is now registered */ |
830 | write_lock(&entry->rw_lock); | ||
670 | entry->ready = 2; | 831 | entry->ready = 2; |
671 | 832 | ||
672 | if (!entry->dev) | ||
673 | continue; | ||
674 | |||
675 | /* Add a nice symlink to the real device */ | 833 | /* Add a nice symlink to the real device */ |
676 | sysfs_create_link(&entry->kobj, &entry->dev->kobj, "device"); | 834 | if (entry->dev) |
835 | sysfs_create_link(&entry->kobj, &entry->dev->kobj, "device"); | ||
836 | |||
837 | write_unlock(&entry->rw_lock); | ||
677 | } | 838 | } |
678 | 839 | ||
679 | return 0; | 840 | return 0; |
@@ -688,14 +849,17 @@ pdcs_unregister_pathentries(void) | |||
688 | unsigned short i; | 849 | unsigned short i; |
689 | struct pdcspath_entry *entry; | 850 | struct pdcspath_entry *entry; |
690 | 851 | ||
691 | for (i = 0; (entry = pdcspath_entries[i]); i++) | 852 | for (i = 0; (entry = pdcspath_entries[i]); i++) { |
853 | read_lock(&entry->rw_lock); | ||
692 | if (entry->ready >= 2) | 854 | if (entry->ready >= 2) |
693 | kobject_unregister(&entry->kobj); | 855 | kobject_unregister(&entry->kobj); |
856 | read_unlock(&entry->rw_lock); | ||
857 | } | ||
694 | } | 858 | } |
695 | 859 | ||
696 | /* | 860 | /* |
697 | * For now we register the pdc subsystem with the firmware subsystem | 861 | * For now we register the stable subsystem with the firmware subsystem |
698 | * and the paths subsystem with the pdc subsystem | 862 | * and the paths subsystem with the stable subsystem |
699 | */ | 863 | */ |
700 | static int __init | 864 | static int __init |
701 | pdc_stable_init(void) | 865 | pdc_stable_init(void) |
@@ -707,19 +871,23 @@ pdc_stable_init(void) | |||
707 | if (pdc_stable_get_size(&pdcs_size) != PDC_OK) | 871 | if (pdc_stable_get_size(&pdcs_size) != PDC_OK) |
708 | return -ENODEV; | 872 | return -ENODEV; |
709 | 873 | ||
710 | printk(KERN_INFO "PDC Stable Storage facility v%s\n", PDCS_VERSION); | 874 | /* make sure we have enough data */ |
875 | if (pdcs_size < 96) | ||
876 | return -ENODATA; | ||
877 | |||
878 | printk(KERN_INFO PDCS_PREFIX " facility v%s\n", PDCS_VERSION); | ||
711 | 879 | ||
712 | /* For now we'll register the pdc subsys within this driver */ | 880 | /* For now we'll register the stable subsys within this driver */ |
713 | if ((rc = firmware_register(&pdc_subsys))) | 881 | if ((rc = firmware_register(&stable_subsys))) |
714 | goto fail_firmreg; | 882 | goto fail_firmreg; |
715 | 883 | ||
716 | /* Don't forget the info entry */ | 884 | /* Don't forget the root entries */ |
717 | for (i = 0; (attr = pdcs_subsys_attrs[i]) && !error; i++) | 885 | for (i = 0; (attr = pdcs_subsys_attrs[i]) && !error; i++) |
718 | if (attr->show) | 886 | if (attr->show) |
719 | error = subsys_create_file(&pdc_subsys, attr); | 887 | error = subsys_create_file(&stable_subsys, attr); |
720 | 888 | ||
721 | /* register the paths subsys as a subsystem of pdc subsys */ | 889 | /* register the paths subsys as a subsystem of stable subsys */ |
722 | kset_set_kset_s(&paths_subsys, pdc_subsys); | 890 | kset_set_kset_s(&paths_subsys, stable_subsys); |
723 | if ((rc= subsystem_register(&paths_subsys))) | 891 | if ((rc= subsystem_register(&paths_subsys))) |
724 | goto fail_subsysreg; | 892 | goto fail_subsysreg; |
725 | 893 | ||
@@ -734,10 +902,10 @@ fail_pdcsreg: | |||
734 | subsystem_unregister(&paths_subsys); | 902 | subsystem_unregister(&paths_subsys); |
735 | 903 | ||
736 | fail_subsysreg: | 904 | fail_subsysreg: |
737 | firmware_unregister(&pdc_subsys); | 905 | firmware_unregister(&stable_subsys); |
738 | 906 | ||
739 | fail_firmreg: | 907 | fail_firmreg: |
740 | printk(KERN_INFO "PDC Stable Storage bailing out\n"); | 908 | printk(KERN_INFO PDCS_PREFIX " bailing out\n"); |
741 | return rc; | 909 | return rc; |
742 | } | 910 | } |
743 | 911 | ||
@@ -747,7 +915,7 @@ pdc_stable_exit(void) | |||
747 | pdcs_unregister_pathentries(); | 915 | pdcs_unregister_pathentries(); |
748 | subsystem_unregister(&paths_subsys); | 916 | subsystem_unregister(&paths_subsys); |
749 | 917 | ||
750 | firmware_unregister(&pdc_subsys); | 918 | firmware_unregister(&stable_subsys); |
751 | } | 919 | } |
752 | 920 | ||
753 | 921 | ||
diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c index c85653f315aa..52f265e97729 100644 --- a/drivers/parisc/sba_iommu.c +++ b/drivers/parisc/sba_iommu.c | |||
@@ -2064,14 +2064,13 @@ sba_driver_callback(struct parisc_device *dev) | |||
2064 | printk(KERN_INFO "%s found %s at 0x%lx\n", | 2064 | printk(KERN_INFO "%s found %s at 0x%lx\n", |
2065 | MODULE_NAME, version, dev->hpa.start); | 2065 | MODULE_NAME, version, dev->hpa.start); |
2066 | 2066 | ||
2067 | sba_dev = kmalloc(sizeof(struct sba_device), GFP_KERNEL); | 2067 | sba_dev = kzalloc(sizeof(struct sba_device), GFP_KERNEL); |
2068 | if (!sba_dev) { | 2068 | if (!sba_dev) { |
2069 | printk(KERN_ERR MODULE_NAME " - couldn't alloc sba_device\n"); | 2069 | printk(KERN_ERR MODULE_NAME " - couldn't alloc sba_device\n"); |
2070 | return -ENOMEM; | 2070 | return -ENOMEM; |
2071 | } | 2071 | } |
2072 | 2072 | ||
2073 | parisc_set_drvdata(dev, sba_dev); | 2073 | parisc_set_drvdata(dev, sba_dev); |
2074 | memset(sba_dev, 0, sizeof(struct sba_device)); | ||
2075 | 2074 | ||
2076 | for(i=0; i<MAX_IOC; i++) | 2075 | for(i=0; i<MAX_IOC; i++) |
2077 | spin_lock_init(&(sba_dev->ioc[i].res_lock)); | 2076 | spin_lock_init(&(sba_dev->ioc[i].res_lock)); |
diff --git a/drivers/parisc/superio.c b/drivers/parisc/superio.c index d14888e149bb..ba971fecd0d8 100644 --- a/drivers/parisc/superio.c +++ b/drivers/parisc/superio.c | |||
@@ -89,6 +89,9 @@ static struct superio_device sio_dev; | |||
89 | #define DBG_INIT(x...) | 89 | #define DBG_INIT(x...) |
90 | #endif | 90 | #endif |
91 | 91 | ||
92 | #define SUPERIO "SuperIO" | ||
93 | #define PFX SUPERIO ": " | ||
94 | |||
92 | static irqreturn_t | 95 | static irqreturn_t |
93 | superio_interrupt(int parent_irq, void *devp, struct pt_regs *regs) | 96 | superio_interrupt(int parent_irq, void *devp, struct pt_regs *regs) |
94 | { | 97 | { |
@@ -117,7 +120,7 @@ superio_interrupt(int parent_irq, void *devp, struct pt_regs *regs) | |||
117 | local_irq = results & 0x0f; | 120 | local_irq = results & 0x0f; |
118 | 121 | ||
119 | if (local_irq == 2 || local_irq > 7) { | 122 | if (local_irq == 2 || local_irq > 7) { |
120 | printk(KERN_ERR "SuperIO: slave interrupted!\n"); | 123 | printk(KERN_ERR PFX "slave interrupted!\n"); |
121 | return IRQ_HANDLED; | 124 | return IRQ_HANDLED; |
122 | } | 125 | } |
123 | 126 | ||
@@ -128,7 +131,7 @@ superio_interrupt(int parent_irq, void *devp, struct pt_regs *regs) | |||
128 | outb(OCW3_ISR,IC_PIC1+0); | 131 | outb(OCW3_ISR,IC_PIC1+0); |
129 | results = inb(IC_PIC1+0); | 132 | results = inb(IC_PIC1+0); |
130 | if ((results & 0x80) == 0) { /* if ISR7 not set: spurious */ | 133 | if ((results & 0x80) == 0) { /* if ISR7 not set: spurious */ |
131 | printk(KERN_WARNING "SuperIO: spurious interrupt!\n"); | 134 | printk(KERN_WARNING PFX "spurious interrupt!\n"); |
132 | return IRQ_HANDLED; | 135 | return IRQ_HANDLED; |
133 | } | 136 | } |
134 | } | 137 | } |
@@ -163,27 +166,27 @@ superio_init(struct pci_dev *pcidev) | |||
163 | /* ...then properly fixup the USB to point at suckyio PIC */ | 166 | /* ...then properly fixup the USB to point at suckyio PIC */ |
164 | sio->usb_pdev->irq = superio_fixup_irq(sio->usb_pdev); | 167 | sio->usb_pdev->irq = superio_fixup_irq(sio->usb_pdev); |
165 | 168 | ||
166 | printk(KERN_INFO "SuperIO: Found NS87560 Legacy I/O device at %s (IRQ %i) \n", | 169 | printk(KERN_INFO PFX "Found NS87560 Legacy I/O device at %s (IRQ %i) \n", |
167 | pci_name(pdev), pdev->irq); | 170 | pci_name(pdev), pdev->irq); |
168 | 171 | ||
169 | pci_read_config_dword (pdev, SIO_SP1BAR, &sio->sp1_base); | 172 | pci_read_config_dword (pdev, SIO_SP1BAR, &sio->sp1_base); |
170 | sio->sp1_base &= ~1; | 173 | sio->sp1_base &= ~1; |
171 | printk (KERN_INFO "SuperIO: Serial port 1 at 0x%x\n", sio->sp1_base); | 174 | printk(KERN_INFO PFX "Serial port 1 at 0x%x\n", sio->sp1_base); |
172 | 175 | ||
173 | pci_read_config_dword (pdev, SIO_SP2BAR, &sio->sp2_base); | 176 | pci_read_config_dword (pdev, SIO_SP2BAR, &sio->sp2_base); |
174 | sio->sp2_base &= ~1; | 177 | sio->sp2_base &= ~1; |
175 | printk (KERN_INFO "SuperIO: Serial port 2 at 0x%x\n", sio->sp2_base); | 178 | printk(KERN_INFO PFX "Serial port 2 at 0x%x\n", sio->sp2_base); |
176 | 179 | ||
177 | pci_read_config_dword (pdev, SIO_PPBAR, &sio->pp_base); | 180 | pci_read_config_dword (pdev, SIO_PPBAR, &sio->pp_base); |
178 | sio->pp_base &= ~1; | 181 | sio->pp_base &= ~1; |
179 | printk (KERN_INFO "SuperIO: Parallel port at 0x%x\n", sio->pp_base); | 182 | printk(KERN_INFO PFX "Parallel port at 0x%x\n", sio->pp_base); |
180 | 183 | ||
181 | pci_read_config_dword (pdev, SIO_FDCBAR, &sio->fdc_base); | 184 | pci_read_config_dword (pdev, SIO_FDCBAR, &sio->fdc_base); |
182 | sio->fdc_base &= ~1; | 185 | sio->fdc_base &= ~1; |
183 | printk (KERN_INFO "SuperIO: Floppy controller at 0x%x\n", sio->fdc_base); | 186 | printk(KERN_INFO PFX "Floppy controller at 0x%x\n", sio->fdc_base); |
184 | pci_read_config_dword (pdev, SIO_ACPIBAR, &sio->acpi_base); | 187 | pci_read_config_dword (pdev, SIO_ACPIBAR, &sio->acpi_base); |
185 | sio->acpi_base &= ~1; | 188 | sio->acpi_base &= ~1; |
186 | printk (KERN_INFO "SuperIO: ACPI at 0x%x\n", sio->acpi_base); | 189 | printk(KERN_INFO PFX "ACPI at 0x%x\n", sio->acpi_base); |
187 | 190 | ||
188 | request_region (IC_PIC1, 0x1f, "pic1"); | 191 | request_region (IC_PIC1, 0x1f, "pic1"); |
189 | request_region (IC_PIC2, 0x1f, "pic2"); | 192 | request_region (IC_PIC2, 0x1f, "pic2"); |
@@ -263,14 +266,14 @@ superio_init(struct pci_dev *pcidev) | |||
263 | /* Setup USB power regulation */ | 266 | /* Setup USB power regulation */ |
264 | outb(1, sio->acpi_base + USB_REG_CR); | 267 | outb(1, sio->acpi_base + USB_REG_CR); |
265 | if (inb(sio->acpi_base + USB_REG_CR) & 1) | 268 | if (inb(sio->acpi_base + USB_REG_CR) & 1) |
266 | printk(KERN_INFO "SuperIO: USB regulator enabled\n"); | 269 | printk(KERN_INFO PFX "USB regulator enabled\n"); |
267 | else | 270 | else |
268 | printk(KERN_ERR "USB regulator not initialized!\n"); | 271 | printk(KERN_ERR PFX "USB regulator not initialized!\n"); |
269 | 272 | ||
270 | if (request_irq(pdev->irq, superio_interrupt, SA_INTERRUPT, | 273 | if (request_irq(pdev->irq, superio_interrupt, SA_INTERRUPT, |
271 | "SuperIO", (void *)sio)) { | 274 | SUPERIO, (void *)sio)) { |
272 | 275 | ||
273 | printk(KERN_ERR "SuperIO: could not get irq\n"); | 276 | printk(KERN_ERR PFX "could not get irq\n"); |
274 | BUG(); | 277 | BUG(); |
275 | return; | 278 | return; |
276 | } | 279 | } |
@@ -284,7 +287,7 @@ static void superio_disable_irq(unsigned int irq) | |||
284 | u8 r8; | 287 | u8 r8; |
285 | 288 | ||
286 | if ((irq < 1) || (irq == 2) || (irq > 7)) { | 289 | if ((irq < 1) || (irq == 2) || (irq > 7)) { |
287 | printk(KERN_ERR "SuperIO: Illegal irq number.\n"); | 290 | printk(KERN_ERR PFX "Illegal irq number.\n"); |
288 | BUG(); | 291 | BUG(); |
289 | return; | 292 | return; |
290 | } | 293 | } |
@@ -301,7 +304,7 @@ static void superio_enable_irq(unsigned int irq) | |||
301 | u8 r8; | 304 | u8 r8; |
302 | 305 | ||
303 | if ((irq < 1) || (irq == 2) || (irq > 7)) { | 306 | if ((irq < 1) || (irq == 2) || (irq > 7)) { |
304 | printk(KERN_ERR "SuperIO: Illegal irq number (%d).\n", irq); | 307 | printk(KERN_ERR PFX "Illegal irq number (%d).\n", irq); |
305 | BUG(); | 308 | BUG(); |
306 | return; | 309 | return; |
307 | } | 310 | } |
@@ -319,7 +322,7 @@ static unsigned int superio_startup_irq(unsigned int irq) | |||
319 | } | 322 | } |
320 | 323 | ||
321 | static struct hw_interrupt_type superio_interrupt_type = { | 324 | static struct hw_interrupt_type superio_interrupt_type = { |
322 | .typename = "SuperIO", | 325 | .typename = SUPERIO, |
323 | .startup = superio_startup_irq, | 326 | .startup = superio_startup_irq, |
324 | .shutdown = superio_disable_irq, | 327 | .shutdown = superio_disable_irq, |
325 | .enable = superio_enable_irq, | 328 | .enable = superio_enable_irq, |
@@ -413,7 +416,7 @@ static void __devinit superio_serial_init(void) | |||
413 | 416 | ||
414 | retval = early_serial_setup(&serial[0]); | 417 | retval = early_serial_setup(&serial[0]); |
415 | if (retval < 0) { | 418 | if (retval < 0) { |
416 | printk(KERN_WARNING "SuperIO: Register Serial #0 failed.\n"); | 419 | printk(KERN_WARNING PFX "Register Serial #0 failed.\n"); |
417 | return; | 420 | return; |
418 | } | 421 | } |
419 | 422 | ||
@@ -423,7 +426,7 @@ static void __devinit superio_serial_init(void) | |||
423 | retval = early_serial_setup(&serial[1]); | 426 | retval = early_serial_setup(&serial[1]); |
424 | 427 | ||
425 | if (retval < 0) | 428 | if (retval < 0) |
426 | printk(KERN_WARNING "SuperIO: Register Serial #1 failed.\n"); | 429 | printk(KERN_WARNING PFX "Register Serial #1 failed.\n"); |
427 | #endif /* CONFIG_SERIAL_8250 */ | 430 | #endif /* CONFIG_SERIAL_8250 */ |
428 | } | 431 | } |
429 | 432 | ||
@@ -437,7 +440,7 @@ static void __devinit superio_parport_init(void) | |||
437 | PARPORT_DMA_NONE /* dma */, | 440 | PARPORT_DMA_NONE /* dma */, |
438 | NULL /*struct pci_dev* */) ) | 441 | NULL /*struct pci_dev* */) ) |
439 | 442 | ||
440 | printk(KERN_WARNING "SuperIO: Probing parallel port failed.\n"); | 443 | printk(KERN_WARNING PFX "Probing parallel port failed.\n"); |
441 | #endif /* CONFIG_PARPORT_PC */ | 444 | #endif /* CONFIG_PARPORT_PC */ |
442 | } | 445 | } |
443 | 446 | ||
@@ -499,7 +502,7 @@ static struct pci_device_id superio_tbl[] = { | |||
499 | }; | 502 | }; |
500 | 503 | ||
501 | static struct pci_driver superio_driver = { | 504 | static struct pci_driver superio_driver = { |
502 | .name = "SuperIO", | 505 | .name = SUPERIO, |
503 | .id_table = superio_tbl, | 506 | .id_table = superio_tbl, |
504 | .probe = superio_probe, | 507 | .probe = superio_probe, |
505 | }; | 508 | }; |
diff --git a/drivers/parisc/wax.c b/drivers/parisc/wax.c index 17dce2adf7fe..813c2c24ab1e 100644 --- a/drivers/parisc/wax.c +++ b/drivers/parisc/wax.c | |||
@@ -76,7 +76,7 @@ wax_init_chip(struct parisc_device *dev) | |||
76 | struct gsc_irq gsc_irq; | 76 | struct gsc_irq gsc_irq; |
77 | int ret; | 77 | int ret; |
78 | 78 | ||
79 | wax = kmalloc(sizeof(*wax), GFP_KERNEL); | 79 | wax = kzalloc(sizeof(*wax), GFP_KERNEL); |
80 | if (!wax) | 80 | if (!wax) |
81 | return -ENOMEM; | 81 | return -ENOMEM; |
82 | 82 | ||