Commit b833b481c10cf591b15cc674948cc514e55d3b94
Committed by
Paul Mackerras
1 parent
dd9b67ab37
Exists in
master
and in
4 other branches
[POWERPC] iSeries: Move detection of virtual cdroms
Now we will only have entries in the device tree for the actual existing devices (including their OS/400 properties). This way viocd.c gets all the information about the devices from the device tree. Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au> Acked-by: Jens Axboe <jens.axboe@oracle.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
Showing 6 changed files with 361 additions and 105 deletions Side-by-side Diff
arch/powerpc/kernel/vio.c
arch/powerpc/platforms/iseries/Makefile
... | ... | @@ -7,7 +7,7 @@ |
7 | 7 | hvcall.o proc.o htab.o iommu.o misc.o irq.o |
8 | 8 | obj-$(CONFIG_PCI) += pci.o vpdinfo.o |
9 | 9 | obj-$(CONFIG_SMP) += smp.o |
10 | -obj-$(CONFIG_VIOPATH) += viopath.o | |
10 | +obj-$(CONFIG_VIOPATH) += viopath.o vio.o | |
11 | 11 | obj-$(CONFIG_MODULES) += ksyms.o |
12 | 12 | |
13 | 13 | quiet_cmd_dt_strings = DT_STR $@ |
arch/powerpc/platforms/iseries/dt.c
... | ... | @@ -381,10 +381,6 @@ |
381 | 381 | dt_do_vdevice(dt, "viodasd", reg, i, device_type_block, |
382 | 382 | "IBM,iSeries-viodasd", 1); |
383 | 383 | reg += HVMAXARCHITECTEDVIRTUALDISKS; |
384 | - | |
385 | - for (i = 0; i < HVMAXARCHITECTEDVIRTUALCDROMS; i++) | |
386 | - dt_do_vdevice(dt, "viocd", reg, i, device_type_block, | |
387 | - "IBM,iSeries-viocd", 1); | |
388 | 384 | reg += HVMAXARCHITECTEDVIRTUALCDROMS; |
389 | 385 | |
390 | 386 | for (i = 0; i < HVMAXARCHITECTEDVIRTUALTAPES; i++) |
arch/powerpc/platforms/iseries/vio.c
1 | +/* | |
2 | + * Legacy iSeries specific vio initialisation | |
3 | + * that needs to be built in (not a module). | |
4 | + * | |
5 | + * © Copyright 2007 IBM Corporation | |
6 | + * Author: Stephen Rothwell | |
7 | + * Some parts collected from various other files | |
8 | + * | |
9 | + * This program is free software; you can redistribute it and/or | |
10 | + * modify it under the terms of the GNU General Public License as | |
11 | + * published by the Free Software Foundation; either version 2 of the | |
12 | + * License, or (at your option) any later version. | |
13 | + * | |
14 | + * This program is distributed in the hope that it will be useful, but | |
15 | + * WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
17 | + * General Public License for more details. | |
18 | + * | |
19 | + * You should have received a copy of the GNU General Public License | |
20 | + * along with this program; if not, write to the Free Software Foundation, | |
21 | + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
22 | + */ | |
23 | +#include <linux/of.h> | |
24 | +#include <linux/init.h> | |
25 | +#include <linux/gfp.h> | |
26 | +#include <linux/completion.h> | |
27 | +#include <linux/proc_fs.h> | |
28 | + | |
29 | +#include <asm/firmware.h> | |
30 | +#include <asm/iseries/vio.h> | |
31 | +#include <asm/iseries/iommu.h> | |
32 | +#include <asm/iseries/hv_types.h> | |
33 | +#include <asm/iseries/hv_lp_event.h> | |
34 | + | |
35 | +#define FIRST_VTY 0 | |
36 | +#define NUM_VTYS 1 | |
37 | +#define FIRST_VSCSI (FIRST_VTY + NUM_VTYS) | |
38 | +#define NUM_VSCSIS 1 | |
39 | +#define FIRST_VLAN (FIRST_VSCSI + NUM_VSCSIS) | |
40 | +#define NUM_VLANS HVMAXARCHITECTEDVIRTUALLANS | |
41 | +#define FIRST_VIODASD (FIRST_VLAN + NUM_VLANS) | |
42 | +#define NUM_VIODASDS HVMAXARCHITECTEDVIRTUALDISKS | |
43 | +#define FIRST_VIOCD (FIRST_VIODASD + NUM_VIODASDS) | |
44 | +#define NUM_VIOCDS HVMAXARCHITECTEDVIRTUALCDROMS | |
45 | +#define FIRST_VIOTAPE (FIRST_VIOCD + NUM_VIOCDS) | |
46 | +#define NUM_VIOTAPES HVMAXARCHITECTEDVIRTUALTAPES | |
47 | + | |
48 | +static struct property * __init new_property(const char *name, int length, | |
49 | + const void *value) | |
50 | +{ | |
51 | + struct property *np = kzalloc(sizeof(*np) + strlen(name) + 1 + length, | |
52 | + GFP_KERNEL); | |
53 | + | |
54 | + if (!np) | |
55 | + return NULL; | |
56 | + np->name = (char *)(np + 1); | |
57 | + np->value = np->name + strlen(name) + 1; | |
58 | + strcpy(np->name, name); | |
59 | + memcpy(np->value, value, length); | |
60 | + np->length = length; | |
61 | + return np; | |
62 | +} | |
63 | + | |
64 | +static void __init free_property(struct property *np) | |
65 | +{ | |
66 | + kfree(np); | |
67 | +} | |
68 | + | |
69 | +static struct device_node * __init new_node(const char *path, | |
70 | + struct device_node *parent) | |
71 | +{ | |
72 | + struct device_node *np = kzalloc(sizeof(*np), GFP_KERNEL); | |
73 | + | |
74 | + if (!np) | |
75 | + return NULL; | |
76 | + np->full_name = kmalloc(strlen(path) + 1, GFP_KERNEL); | |
77 | + if (!np->full_name) { | |
78 | + kfree(np); | |
79 | + return NULL; | |
80 | + } | |
81 | + strcpy(np->full_name, path); | |
82 | + of_node_set_flag(np, OF_DYNAMIC); | |
83 | + kref_init(&np->kref); | |
84 | + np->parent = of_node_get(parent); | |
85 | + return np; | |
86 | +} | |
87 | + | |
88 | +static void __init free_node(struct device_node *np) | |
89 | +{ | |
90 | + struct property *next; | |
91 | + struct property *prop; | |
92 | + | |
93 | + next = np->properties; | |
94 | + while (next) { | |
95 | + prop = next; | |
96 | + next = prop->next; | |
97 | + free_property(prop); | |
98 | + } | |
99 | + of_node_put(np->parent); | |
100 | + kfree(np->full_name); | |
101 | + kfree(np); | |
102 | +} | |
103 | + | |
104 | +static int __init add_string_property(struct device_node *np, const char *name, | |
105 | + const char *value) | |
106 | +{ | |
107 | + struct property *nprop = new_property(name, strlen(value) + 1, value); | |
108 | + | |
109 | + if (!nprop) | |
110 | + return 0; | |
111 | + prom_add_property(np, nprop); | |
112 | + return 1; | |
113 | +} | |
114 | + | |
115 | +static int __init add_raw_property(struct device_node *np, const char *name, | |
116 | + int length, const void *value) | |
117 | +{ | |
118 | + struct property *nprop = new_property(name, length, value); | |
119 | + | |
120 | + if (!nprop) | |
121 | + return 0; | |
122 | + prom_add_property(np, nprop); | |
123 | + return 1; | |
124 | +} | |
125 | + | |
126 | +struct viocd_waitevent { | |
127 | + struct completion com; | |
128 | + int rc; | |
129 | + u16 sub_result; | |
130 | +}; | |
131 | + | |
132 | +struct cdrom_info { | |
133 | + char rsrcname[10]; | |
134 | + char type[4]; | |
135 | + char model[3]; | |
136 | +}; | |
137 | + | |
138 | +static void __init handle_cd_event(struct HvLpEvent *event) | |
139 | +{ | |
140 | + struct viocdlpevent *bevent; | |
141 | + struct viocd_waitevent *pwe; | |
142 | + | |
143 | + if (!event) | |
144 | + /* Notification that a partition went away! */ | |
145 | + return; | |
146 | + | |
147 | + /* First, we should NEVER get an int here...only acks */ | |
148 | + if (hvlpevent_is_int(event)) { | |
149 | + printk(KERN_WARNING "handle_cd_event: got an unexpected int\n"); | |
150 | + if (hvlpevent_need_ack(event)) { | |
151 | + event->xRc = HvLpEvent_Rc_InvalidSubtype; | |
152 | + HvCallEvent_ackLpEvent(event); | |
153 | + } | |
154 | + return; | |
155 | + } | |
156 | + | |
157 | + bevent = (struct viocdlpevent *)event; | |
158 | + | |
159 | + switch (event->xSubtype & VIOMINOR_SUBTYPE_MASK) { | |
160 | + case viocdgetinfo: | |
161 | + pwe = (struct viocd_waitevent *)event->xCorrelationToken; | |
162 | + pwe->rc = event->xRc; | |
163 | + pwe->sub_result = bevent->sub_result; | |
164 | + complete(&pwe->com); | |
165 | + break; | |
166 | + | |
167 | + default: | |
168 | + printk(KERN_WARNING "handle_cd_event: " | |
169 | + "message with unexpected subtype %0x04X!\n", | |
170 | + event->xSubtype & VIOMINOR_SUBTYPE_MASK); | |
171 | + if (hvlpevent_need_ack(event)) { | |
172 | + event->xRc = HvLpEvent_Rc_InvalidSubtype; | |
173 | + HvCallEvent_ackLpEvent(event); | |
174 | + } | |
175 | + } | |
176 | +} | |
177 | + | |
178 | +static void __init get_viocd_info(struct device_node *vio_root) | |
179 | +{ | |
180 | + HvLpEvent_Rc hvrc; | |
181 | + u32 unit; | |
182 | + struct viocd_waitevent we; | |
183 | + struct cdrom_info *unitinfo; | |
184 | + dma_addr_t unitinfo_dmaaddr; | |
185 | + int ret; | |
186 | + | |
187 | + ret = viopath_open(viopath_hostLp, viomajorsubtype_cdio, 2); | |
188 | + if (ret) { | |
189 | + printk(KERN_WARNING | |
190 | + "get_viocd_info: error opening path to host partition %d\n", | |
191 | + viopath_hostLp); | |
192 | + return; | |
193 | + } | |
194 | + | |
195 | + /* Initialize our request handler */ | |
196 | + vio_setHandler(viomajorsubtype_cdio, handle_cd_event); | |
197 | + | |
198 | + unitinfo = iseries_hv_alloc( | |
199 | + sizeof(*unitinfo) * HVMAXARCHITECTEDVIRTUALCDROMS, | |
200 | + &unitinfo_dmaaddr, GFP_ATOMIC); | |
201 | + if (!unitinfo) { | |
202 | + printk(KERN_WARNING | |
203 | + "get_viocd_info: error allocating unitinfo\n"); | |
204 | + goto clear_handler; | |
205 | + } | |
206 | + | |
207 | + memset(unitinfo, 0, sizeof(*unitinfo) * HVMAXARCHITECTEDVIRTUALCDROMS); | |
208 | + | |
209 | + init_completion(&we.com); | |
210 | + | |
211 | + hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp, | |
212 | + HvLpEvent_Type_VirtualIo, | |
213 | + viomajorsubtype_cdio | viocdgetinfo, | |
214 | + HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck, | |
215 | + viopath_sourceinst(viopath_hostLp), | |
216 | + viopath_targetinst(viopath_hostLp), | |
217 | + (u64)&we, VIOVERSION << 16, unitinfo_dmaaddr, 0, | |
218 | + sizeof(*unitinfo) * HVMAXARCHITECTEDVIRTUALCDROMS, 0); | |
219 | + if (hvrc != HvLpEvent_Rc_Good) { | |
220 | + printk(KERN_WARNING | |
221 | + "get_viocd_info: cdrom error sending event. rc %d\n", | |
222 | + (int)hvrc); | |
223 | + goto hv_free; | |
224 | + } | |
225 | + | |
226 | + wait_for_completion(&we.com); | |
227 | + | |
228 | + if (we.rc) { | |
229 | + printk(KERN_WARNING "get_viocd_info: bad rc %d:0x%04X\n", | |
230 | + we.rc, we.sub_result); | |
231 | + goto hv_free; | |
232 | + } | |
233 | + | |
234 | + for (unit = 0; (unit < HVMAXARCHITECTEDVIRTUALCDROMS) && | |
235 | + unitinfo[unit].rsrcname[0]; unit++) { | |
236 | + struct device_node *np; | |
237 | + char name[64]; | |
238 | + u32 reg = FIRST_VIOCD + unit; | |
239 | + | |
240 | + snprintf(name, sizeof(name), "/vdevice/viocd@%08x", reg); | |
241 | + np = new_node(name, vio_root); | |
242 | + if (!np) | |
243 | + goto hv_free; | |
244 | + if (!add_string_property(np, "name", "viocd") || | |
245 | + !add_string_property(np, "device_type", "block") || | |
246 | + !add_string_property(np, "compatible", | |
247 | + "IBM,iSeries-viocd") || | |
248 | + !add_raw_property(np, "reg", sizeof(reg), ®) || | |
249 | + !add_raw_property(np, "linux,unit_address", | |
250 | + sizeof(unit), &unit) || | |
251 | + !add_raw_property(np, "linux,vio_rsrcname", | |
252 | + sizeof(unitinfo[unit].rsrcname), | |
253 | + unitinfo[unit].rsrcname) || | |
254 | + !add_raw_property(np, "linux,vio_type", | |
255 | + sizeof(unitinfo[unit].type), | |
256 | + unitinfo[unit].type) || | |
257 | + !add_raw_property(np, "linux,vio_model", | |
258 | + sizeof(unitinfo[unit].model), | |
259 | + unitinfo[unit].model)) | |
260 | + goto node_free; | |
261 | + np->name = of_get_property(np, "name", NULL); | |
262 | + np->type = of_get_property(np, "device_type", NULL); | |
263 | + of_attach_node(np); | |
264 | +#ifdef CONFIG_PROC_DEVICETREE | |
265 | + if (vio_root->pde) { | |
266 | + struct proc_dir_entry *ent; | |
267 | + | |
268 | + ent = proc_mkdir(strrchr(np->full_name, '/') + 1, | |
269 | + vio_root->pde); | |
270 | + if (ent) | |
271 | + proc_device_tree_add_node(np, ent); | |
272 | + } | |
273 | +#endif | |
274 | + continue; | |
275 | + | |
276 | + node_free: | |
277 | + free_node(np); | |
278 | + break; | |
279 | + } | |
280 | + | |
281 | + hv_free: | |
282 | + iseries_hv_free(sizeof(*unitinfo) * HVMAXARCHITECTEDVIRTUALCDROMS, | |
283 | + unitinfo, unitinfo_dmaaddr); | |
284 | + clear_handler: | |
285 | + vio_clearHandler(viomajorsubtype_cdio); | |
286 | + viopath_close(viopath_hostLp, viomajorsubtype_cdio, 2); | |
287 | +} | |
288 | + | |
289 | +static int __init iseries_vio_init(void) | |
290 | +{ | |
291 | + struct device_node *vio_root; | |
292 | + | |
293 | + if (!firmware_has_feature(FW_FEATURE_ISERIES)) | |
294 | + return -ENODEV; | |
295 | + | |
296 | + iommu_vio_init(); | |
297 | + | |
298 | + vio_root = of_find_node_by_path("/vdevice"); | |
299 | + if (!vio_root) | |
300 | + return -ENODEV; | |
301 | + | |
302 | + if (viopath_hostLp == HvLpIndexInvalid) { | |
303 | + vio_set_hostlp(); | |
304 | + /* If we don't have a host, bail out */ | |
305 | + if (viopath_hostLp == HvLpIndexInvalid) | |
306 | + goto put_node; | |
307 | + } | |
308 | + | |
309 | + get_viocd_info(vio_root); | |
310 | + | |
311 | + return 0; | |
312 | + | |
313 | + put_node: | |
314 | + of_node_put(vio_root); | |
315 | + return -ENODEV; | |
316 | +} | |
317 | +arch_initcall(iseries_vio_init); |
drivers/cdrom/viocd.c
... | ... | @@ -56,30 +56,6 @@ |
56 | 56 | #define VIOCD_KERN_WARNING KERN_WARNING "viocd: " |
57 | 57 | #define VIOCD_KERN_INFO KERN_INFO "viocd: " |
58 | 58 | |
59 | -struct viocdlpevent { | |
60 | - struct HvLpEvent event; | |
61 | - u32 reserved; | |
62 | - u16 version; | |
63 | - u16 sub_result; | |
64 | - u16 disk; | |
65 | - u16 flags; | |
66 | - u32 token; | |
67 | - u64 offset; /* On open, max number of disks */ | |
68 | - u64 len; /* On open, size of the disk */ | |
69 | - u32 block_size; /* Only set on open */ | |
70 | - u32 media_size; /* Only set on open */ | |
71 | -}; | |
72 | - | |
73 | -enum viocdsubtype { | |
74 | - viocdopen = 0x0001, | |
75 | - viocdclose = 0x0002, | |
76 | - viocdread = 0x0003, | |
77 | - viocdwrite = 0x0004, | |
78 | - viocdlockdoor = 0x0005, | |
79 | - viocdgetinfo = 0x0006, | |
80 | - viocdcheck = 0x0007 | |
81 | -}; | |
82 | - | |
83 | 59 | /* |
84 | 60 | * Should probably make this a module parameter....sigh |
85 | 61 | */ |
86 | 62 | |
... | ... | @@ -131,17 +107,13 @@ |
131 | 107 | /* These are our internal structures for keeping track of devices */ |
132 | 108 | static int viocd_numdev; |
133 | 109 | |
134 | -struct cdrom_info { | |
135 | - char rsrcname[10]; | |
136 | - char type[4]; | |
137 | - char model[3]; | |
138 | -}; | |
139 | - | |
140 | 110 | struct disk_info { |
141 | 111 | struct gendisk *viocd_disk; |
142 | 112 | struct cdrom_device_info viocd_info; |
143 | 113 | struct device *dev; |
144 | - struct cdrom_info unitinfo; | |
114 | + const char *rsrcname; | |
115 | + const char *type; | |
116 | + const char *model; | |
145 | 117 | }; |
146 | 118 | static struct disk_info viocd_diskinfo[VIOCD_MAX_CD]; |
147 | 119 | |
... | ... | @@ -159,9 +131,9 @@ |
159 | 131 | for (i = 0; i < viocd_numdev; i++) { |
160 | 132 | seq_printf(m, "viocd device %d is iSeries resource %10.10s" |
161 | 133 | "type %4.4s, model %3.3s\n", |
162 | - i, viocd_diskinfo[i].unitinfo.rsrcname, | |
163 | - viocd_diskinfo[i].unitinfo.type, | |
164 | - viocd_diskinfo[i].unitinfo.model); | |
134 | + i, viocd_diskinfo[i].rsrcname, | |
135 | + viocd_diskinfo[i].type, | |
136 | + viocd_diskinfo[i].model); | |
165 | 137 | } |
166 | 138 | return 0; |
167 | 139 | } |
... | ... | @@ -211,61 +183,6 @@ |
211 | 183 | .media_changed = viocd_blk_media_changed, |
212 | 184 | }; |
213 | 185 | |
214 | -/* Get info on CD devices from OS/400 */ | |
215 | -static void __init get_viocd_info(void) | |
216 | -{ | |
217 | - HvLpEvent_Rc hvrc; | |
218 | - int i; | |
219 | - struct viocd_waitevent we; | |
220 | - struct cdrom_info *viocd_unitinfo; | |
221 | - dma_addr_t unitinfo_dmaaddr; | |
222 | - | |
223 | - viocd_unitinfo = iseries_hv_alloc( | |
224 | - sizeof(*viocd_unitinfo) * VIOCD_MAX_CD, | |
225 | - &unitinfo_dmaaddr, GFP_ATOMIC); | |
226 | - if (viocd_unitinfo == NULL) { | |
227 | - printk(VIOCD_KERN_WARNING "error allocating unitinfo\n"); | |
228 | - return; | |
229 | - } | |
230 | - | |
231 | - memset(viocd_unitinfo, 0, sizeof(*viocd_unitinfo) * VIOCD_MAX_CD); | |
232 | - | |
233 | - init_completion(&we.com); | |
234 | - | |
235 | - hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp, | |
236 | - HvLpEvent_Type_VirtualIo, | |
237 | - viomajorsubtype_cdio | viocdgetinfo, | |
238 | - HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck, | |
239 | - viopath_sourceinst(viopath_hostLp), | |
240 | - viopath_targetinst(viopath_hostLp), | |
241 | - (u64)&we, VIOVERSION << 16, unitinfo_dmaaddr, 0, | |
242 | - sizeof(*viocd_unitinfo) * VIOCD_MAX_CD, 0); | |
243 | - if (hvrc != HvLpEvent_Rc_Good) { | |
244 | - printk(VIOCD_KERN_WARNING "cdrom error sending event. rc %d\n", | |
245 | - (int)hvrc); | |
246 | - goto error_ret; | |
247 | - } | |
248 | - | |
249 | - wait_for_completion(&we.com); | |
250 | - | |
251 | - if (we.rc) { | |
252 | - const struct vio_error_entry *err = | |
253 | - vio_lookup_rc(viocd_err_table, we.sub_result); | |
254 | - printk(VIOCD_KERN_WARNING "bad rc %d:0x%04X on getinfo: %s\n", | |
255 | - we.rc, we.sub_result, err->msg); | |
256 | - goto error_ret; | |
257 | - } | |
258 | - | |
259 | - for (i = 0; (i < VIOCD_MAX_CD) && viocd_unitinfo[i].rsrcname[0]; i++) { | |
260 | - viocd_diskinfo[viocd_numdev].unitinfo = viocd_unitinfo[i]; | |
261 | - viocd_numdev++; | |
262 | - } | |
263 | - | |
264 | -error_ret: | |
265 | - iseries_hv_free(sizeof(*viocd_unitinfo) * VIOCD_MAX_CD, | |
266 | - viocd_unitinfo, unitinfo_dmaaddr); | |
267 | -} | |
268 | - | |
269 | 186 | static int viocd_open(struct cdrom_device_info *cdi, int purpose) |
270 | 187 | { |
271 | 188 | struct disk_info *diskinfo = cdi->handle; |
... | ... | @@ -576,7 +493,6 @@ |
576 | 493 | bevent->block_size / 512); |
577 | 494 | } |
578 | 495 | /* FALLTHROUGH !! */ |
579 | - case viocdgetinfo: | |
580 | 496 | case viocdlockdoor: |
581 | 497 | pwe = (struct viocd_waitevent *)event->xCorrelationToken; |
582 | 498 | return_complete: |
583 | 499 | |
584 | 500 | |
585 | 501 | |
586 | 502 | |
587 | 503 | |
588 | 504 | |
589 | 505 | |
... | ... | @@ -660,22 +576,30 @@ |
660 | 576 | int deviceno; |
661 | 577 | struct disk_info *d; |
662 | 578 | struct cdrom_device_info *c; |
663 | - struct cdrom_info *ci; | |
664 | 579 | struct request_queue *q; |
580 | + struct device_node *node = vdev->dev.archdata.of_node; | |
665 | 581 | |
666 | 582 | deviceno = vdev->unit_address; |
667 | - if (deviceno >= viocd_numdev) | |
583 | + if (deviceno > VIOCD_MAX_CD) | |
668 | 584 | return -ENODEV; |
585 | + if (!node) | |
586 | + return -ENODEV; | |
669 | 587 | |
588 | + if (deviceno >= viocd_numdev) | |
589 | + viocd_numdev = deviceno + 1; | |
590 | + | |
670 | 591 | d = &viocd_diskinfo[deviceno]; |
592 | + d->rsrcname = of_get_property(node, "linux,vio_rsrcname", NULL); | |
593 | + d->type = of_get_property(node, "linux,vio_type", NULL); | |
594 | + d->model = of_get_property(node, "linux,vio_model", NULL); | |
595 | + | |
671 | 596 | c = &d->viocd_info; |
672 | - ci = &d->unitinfo; | |
673 | 597 | |
674 | 598 | c->ops = &viocd_dops; |
675 | 599 | c->speed = 4; |
676 | 600 | c->capacity = 1; |
677 | 601 | c->handle = d; |
678 | - c->mask = ~find_capability(ci->type); | |
602 | + c->mask = ~find_capability(d->type); | |
679 | 603 | sprintf(c->name, VIOCD_DEVICE "%c", 'a' + deviceno); |
680 | 604 | |
681 | 605 | if (register_cdrom(c) != 0) { |
... | ... | @@ -685,7 +609,7 @@ |
685 | 609 | } |
686 | 610 | printk(VIOCD_KERN_INFO "cd %s is iSeries resource %10.10s " |
687 | 611 | "type %4.4s, model %3.3s\n", |
688 | - c->name, ci->rsrcname, ci->type, ci->model); | |
612 | + c->name, d->rsrcname, d->type, d->model); | |
689 | 613 | q = blk_init_queue(do_viocd_request, &viocd_reqlock); |
690 | 614 | if (q == NULL) { |
691 | 615 | printk(VIOCD_KERN_WARNING "Cannot allocate queue for %s!\n", |
... | ... | @@ -793,8 +717,6 @@ |
793 | 717 | |
794 | 718 | /* Initialize our request handler */ |
795 | 719 | vio_setHandler(viomajorsubtype_cdio, vio_handle_cd_event); |
796 | - | |
797 | - get_viocd_info(); | |
798 | 720 | |
799 | 721 | spin_lock_init(&viocd_reqlock); |
800 | 722 |
include/asm-powerpc/iseries/vio.h
... | ... | @@ -51,6 +51,30 @@ |
51 | 51 | */ |
52 | 52 | #define VIO_MAX_SUBTYPES 8 |
53 | 53 | |
54 | +struct viocdlpevent { | |
55 | + struct HvLpEvent event; | |
56 | + u32 reserved; | |
57 | + u16 version; | |
58 | + u16 sub_result; | |
59 | + u16 disk; | |
60 | + u16 flags; | |
61 | + u32 token; | |
62 | + u64 offset; /* On open, max number of disks */ | |
63 | + u64 len; /* On open, size of the disk */ | |
64 | + u32 block_size; /* Only set on open */ | |
65 | + u32 media_size; /* Only set on open */ | |
66 | +}; | |
67 | + | |
68 | +enum viocdsubtype { | |
69 | + viocdopen = 0x0001, | |
70 | + viocdclose = 0x0002, | |
71 | + viocdread = 0x0003, | |
72 | + viocdwrite = 0x0004, | |
73 | + viocdlockdoor = 0x0005, | |
74 | + viocdgetinfo = 0x0006, | |
75 | + viocdcheck = 0x0007 | |
76 | +}; | |
77 | + | |
54 | 78 | /* |
55 | 79 | * Each subtype can register a handler to process their events. |
56 | 80 | * The handler must have this interface. |