aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarkus Lidel <Markus.Lidel@shadowconnect.com>2005-08-09 13:08:03 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-08-09 15:08:22 -0400
commitdb29e85a7ece62de1899917c1ec0ffe55cf1d3a0 (patch)
treefcecd11c14fd6e95b1dc7daba899c64bbee25ded
parent36d2f5a18205dfc2fac1e3541d324ce186f418cb (diff)
[PATCH] i2o: remove new configuration API
Remove new configuration API from i2o_config The API-patch is still available from the I2O website (which is mentioned in the kernel config now). It is removed because it creates a new binary sysfs-attribute, which doesn't have the limitiation of 4k. Expect for the Adaptec controllers, which has a limitation in the hardware this attribute doesn't make sense anywhere else. Until the sysfs API provides an attribute which doesn't buffer (like firmware) and let access to at least 64k blocks i provide a separate patch... (akpm: basically, this API was introduced post-2.6.12 and Markus wants to pull it out before 2.6.13). Signed-off-by: Markus Lidel <Markus.Lidel@shadowconnect.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--drivers/message/i2o/Kconfig3
-rw-r--r--drivers/message/i2o/config-osm.c494
2 files changed, 3 insertions, 494 deletions
diff --git a/drivers/message/i2o/Kconfig b/drivers/message/i2o/Kconfig
index 06e8eb19a05c..43a942a29c2e 100644
--- a/drivers/message/i2o/Kconfig
+++ b/drivers/message/i2o/Kconfig
@@ -53,6 +53,9 @@ config I2O_CONFIG
53 To compile this support as a module, choose M here: the 53 To compile this support as a module, choose M here: the
54 module will be called i2o_config. 54 module will be called i2o_config.
55 55
56 Note: If you want to use the new API you have to download the
57 i2o_config patch from http://i2o.shadowconnect.com/
58
56config I2O_CONFIG_OLD_IOCTL 59config I2O_CONFIG_OLD_IOCTL
57 bool "Enable ioctls (OBSOLETE)" 60 bool "Enable ioctls (OBSOLETE)"
58 depends on I2O_CONFIG 61 depends on I2O_CONFIG
diff --git a/drivers/message/i2o/config-osm.c b/drivers/message/i2o/config-osm.c
index fe2e7afc9eae..af32ab4e90cd 100644
--- a/drivers/message/i2o/config-osm.c
+++ b/drivers/message/i2o/config-osm.c
@@ -30,503 +30,9 @@
30 30
31static struct i2o_driver i2o_config_driver; 31static struct i2o_driver i2o_config_driver;
32 32
33/* Special file operations for sysfs */
34struct fops_attribute {
35 struct bin_attribute bin;
36 struct file_operations fops;
37};
38
39/**
40 * sysfs_read_dummy
41 */
42static ssize_t sysfs_read_dummy(struct kobject *kobj, char *buf, loff_t offset,
43 size_t count)
44{
45 return 0;
46};
47
48/**
49 * sysfs_write_dummy
50 */
51static ssize_t sysfs_write_dummy(struct kobject *kobj, char *buf, loff_t offset,
52 size_t count)
53{
54 return 0;
55};
56
57/**
58 * sysfs_create_fops_file - Creates attribute with special file operations
59 * @kobj: kobject which should contains the attribute
60 * @attr: attributes which should be used to create file
61 *
62 * First creates attribute @attr in kobject @kobj. If it is the first time
63 * this function is called, merge old fops from sysfs with new one and
64 * write it back. Afterwords the new fops will be set for the created
65 * attribute.
66 *
67 * Returns 0 on success or negative error code on failure.
68 */
69static int sysfs_create_fops_file(struct kobject *kobj,
70 struct fops_attribute *attr)
71{
72 struct file_operations tmp, *fops;
73 struct dentry *d;
74 struct qstr qstr;
75 int rc;
76
77 fops = &attr->fops;
78
79 if (fops->read)
80 attr->bin.read = sysfs_read_dummy;
81
82 if (fops->write)
83 attr->bin.write = sysfs_write_dummy;
84
85 if ((rc = sysfs_create_bin_file(kobj, &attr->bin)))
86 return rc;
87
88 qstr.name = attr->bin.attr.name;
89 qstr.len = strlen(qstr.name);
90 qstr.hash = full_name_hash(qstr.name, qstr.len);
91
92 if ((d = lookup_hash(&qstr, kobj->dentry))) {
93 if (!fops->owner) {
94 memcpy(&tmp, d->d_inode->i_fop, sizeof(tmp));
95 if (fops->read)
96 tmp.read = fops->read;
97 if (fops->write)
98 tmp.write = fops->write;
99 memcpy(fops, &tmp, sizeof(tmp));
100 }
101
102 d->d_inode->i_fop = fops;
103 } else
104 sysfs_remove_bin_file(kobj, &attr->bin);
105
106 return -ENOENT;
107};
108
109/**
110 * sysfs_remove_fops_file - Remove attribute with special file operations
111 * @kobj: kobject which contains the attribute
112 * @attr: attributes which are used to create file
113 *
114 * Only wrapper arround sysfs_remove_bin_file()
115 *
116 * Returns 0 on success or negative error code on failure.
117 */
118static inline int sysfs_remove_fops_file(struct kobject *kobj,
119 struct fops_attribute *attr)
120{
121 return sysfs_remove_bin_file(kobj, &attr->bin);
122};
123
124/**
125 * i2o_config_read_hrt - Returns the HRT of the controller
126 * @kob: kernel object handle
127 * @buf: buffer into which the HRT should be copied
128 * @off: file offset
129 * @count: number of bytes to read
130 *
131 * Put @count bytes starting at @off into @buf from the HRT of the I2O
132 * controller corresponding to @kobj.
133 *
134 * Returns number of bytes copied into buffer.
135 */
136static ssize_t i2o_config_read_hrt(struct kobject *kobj, char *buf,
137 loff_t offset, size_t count)
138{
139 struct i2o_controller *c = kobj_to_i2o_device(kobj)->iop;
140 i2o_hrt *hrt = c->hrt.virt;
141
142 u32 size = (hrt->num_entries * hrt->entry_len + 2) * 4;
143
144 if (offset > size)
145 return 0;
146
147 if (offset + count > size)
148 count = size - offset;
149
150 memcpy(buf, (u8 *) hrt + offset, count);
151
152 return count;
153};
154
155/**
156 * i2o_config_read_lct - Returns the LCT of the controller
157 * @kob: kernel object handle
158 * @buf: buffer into which the LCT should be copied
159 * @off: file offset
160 * @count: number of bytes to read
161 *
162 * Put @count bytes starting at @off into @buf from the LCT of the I2O
163 * controller corresponding to @kobj.
164 *
165 * Returns number of bytes copied into buffer.
166 */
167static ssize_t i2o_config_read_lct(struct kobject *kobj, char *buf,
168 loff_t offset, size_t count)
169{
170 struct i2o_controller *c = kobj_to_i2o_device(kobj)->iop;
171 u32 size = c->lct->table_size * 4;
172
173 if (offset > size)
174 return 0;
175
176 if (offset + count > size)
177 count = size - offset;
178
179 memcpy(buf, (u8 *) c->lct + offset, count);
180
181 return count;
182};
183
184#define I2O_CONFIG_SW_ATTR(_name,_mode,_type,_swid) \
185static ssize_t i2o_config_##_name##_read(struct file *file, char __user *buf, size_t count, loff_t * offset) { \
186 return i2o_config_sw_read(file, buf, count, offset, _type, _swid); \
187};\
188\
189static ssize_t i2o_config_##_name##_write(struct file *file, const char __user *buf, size_t count, loff_t * offset) { \
190 return i2o_config_sw_write(file, buf, count, offset, _type, _swid); \
191}; \
192\
193static struct fops_attribute i2o_config_attr_##_name = { \
194 .bin = { .attr = { .name = __stringify(_name), .mode = _mode, \
195 .owner = THIS_MODULE }, \
196 .size = 0, }, \
197 .fops = { .write = i2o_config_##_name##_write, \
198 .read = i2o_config_##_name##_read} \
199};
200
201#ifdef CONFIG_I2O_EXT_ADAPTEC
202
203/**
204 * i2o_config_dpt_reagion - Converts type and id to flash region
205 * @swtype: type of software module reading
206 * @swid: id of software which should be read
207 *
208 * Converts type and id from I2O spec to the matching region for DPT /
209 * Adaptec controllers.
210 *
211 * Returns region which match type and id or -1 on error.
212 */
213static u32 i2o_config_dpt_region(u8 swtype, u8 swid)
214{
215 switch (swtype) {
216 case I2O_SOFTWARE_MODULE_IRTOS:
217 /*
218 * content: operation firmware
219 * region size:
220 * 0xbc000 for 2554, 3754, 2564, 3757
221 * 0x170000 for 2865
222 * 0x17c000 for 3966
223 */
224 if (!swid)
225 return 0;
226
227 break;
228
229 case I2O_SOFTWARE_MODULE_IOP_PRIVATE:
230 /*
231 * content: BIOS and SMOR
232 * BIOS size: first 0x8000 bytes
233 * region size:
234 * 0x40000 for 2554, 3754, 2564, 3757
235 * 0x80000 for 2865, 3966
236 */
237 if (!swid)
238 return 1;
239
240 break;
241
242 case I2O_SOFTWARE_MODULE_IOP_CONFIG:
243 switch (swid) {
244 case 0:
245 /*
246 * content: NVRAM defaults
247 * region size: 0x2000 bytes
248 */
249 return 2;
250 case 1:
251 /*
252 * content: serial number
253 * region size: 0x2000 bytes
254 */
255 return 3;
256 }
257 break;
258 }
259
260 return -1;
261};
262
263#endif
264
265/**
266 * i2o_config_sw_read - Read a software module from controller
267 * @file: file pointer
268 * @buf: buffer into which the data should be copied
269 * @count: number of bytes to read
270 * @off: file offset
271 * @swtype: type of software module reading
272 * @swid: id of software which should be read
273 *
274 * Transfers @count bytes at offset @offset from IOP into buffer using
275 * type @swtype and id @swid as described in I2O spec.
276 *
277 * Returns number of bytes copied into buffer or error code on failure.
278 */
279static ssize_t i2o_config_sw_read(struct file *file, char __user * buf,
280 size_t count, loff_t * offset, u8 swtype,
281 u32 swid)
282{
283 struct sysfs_dirent *sd = file->f_dentry->d_parent->d_fsdata;
284 struct kobject *kobj = sd->s_element;
285 struct i2o_controller *c = kobj_to_i2o_device(kobj)->iop;
286 u32 m, function = I2O_CMD_SW_UPLOAD;
287 struct i2o_dma buffer;
288 struct i2o_message __iomem *msg;
289 u32 __iomem *mptr;
290 int rc, status;
291
292 m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
293 if (m == I2O_QUEUE_EMPTY)
294 return -EBUSY;
295
296 mptr = &msg->body[3];
297
298 if ((rc = i2o_dma_alloc(&c->pdev->dev, &buffer, count, GFP_KERNEL))) {
299 i2o_msg_nop(c, m);
300 return rc;
301 }
302#ifdef CONFIG_I2O_EXT_ADAPTEC
303 if (c->adaptec) {
304 mptr = &msg->body[4];
305 function = I2O_CMD_PRIVATE;
306
307 writel(TEN_WORD_MSG_SIZE | SGL_OFFSET_8, &msg->u.head[0]);
308
309 writel(I2O_VENDOR_DPT << 16 | I2O_DPT_FLASH_READ,
310 &msg->body[0]);
311 writel(i2o_config_dpt_region(swtype, swid), &msg->body[1]);
312 writel(*offset, &msg->body[2]);
313 writel(count, &msg->body[3]);
314 } else
315#endif
316 writel(NINE_WORD_MSG_SIZE | SGL_OFFSET_7, &msg->u.head[0]);
317
318 writel(0xD0000000 | count, mptr++);
319 writel(buffer.phys, mptr);
320
321 writel(function << 24 | HOST_TID << 12 | ADAPTER_TID, &msg->u.head[1]);
322 writel(i2o_config_driver.context, &msg->u.head[2]);
323 writel(0, &msg->u.head[3]);
324
325#ifdef CONFIG_I2O_EXT_ADAPTEC
326 if (!c->adaptec)
327#endif
328 {
329 writel((u32) swtype << 16 | (u32) 1 << 8, &msg->body[0]);
330 writel(0, &msg->body[1]);
331 writel(swid, &msg->body[2]);
332 }
333
334 status = i2o_msg_post_wait_mem(c, m, 60, &buffer);
335
336 if (status == I2O_POST_WAIT_OK) {
337 if (!(rc = copy_to_user(buf, buffer.virt, count))) {
338 rc = count;
339 *offset += count;
340 }
341 } else
342 rc = -EIO;
343
344 if (status != -ETIMEDOUT)
345 i2o_dma_free(&c->pdev->dev, &buffer);
346
347 return rc;
348};
349
350/**
351 * i2o_config_sw_write - Write a software module to controller
352 * @file: file pointer
353 * @buf: buffer into which the data should be copied
354 * @count: number of bytes to read
355 * @off: file offset
356 * @swtype: type of software module writing
357 * @swid: id of software which should be written
358 *
359 * Transfers @count bytes at offset @offset from buffer to IOP using
360 * type @swtype and id @swid as described in I2O spec.
361 *
362 * Returns number of bytes copied from buffer or error code on failure.
363 */
364static ssize_t i2o_config_sw_write(struct file *file, const char __user * buf,
365 size_t count, loff_t * offset, u8 swtype,
366 u32 swid)
367{
368 struct sysfs_dirent *sd = file->f_dentry->d_parent->d_fsdata;
369 struct kobject *kobj = sd->s_element;
370 struct i2o_controller *c = kobj_to_i2o_device(kobj)->iop;
371 u32 m, function = I2O_CMD_SW_DOWNLOAD;
372 struct i2o_dma buffer;
373 struct i2o_message __iomem *msg;
374 u32 __iomem *mptr;
375 int rc, status;
376
377 m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
378 if (m == I2O_QUEUE_EMPTY)
379 return -EBUSY;
380
381 mptr = &msg->body[3];
382
383 if ((rc = i2o_dma_alloc(&c->pdev->dev, &buffer, count, GFP_KERNEL)))
384 goto nop_msg;
385
386 if ((rc = copy_from_user(buffer.virt, buf, count)))
387 goto free_buffer;
388
389#ifdef CONFIG_I2O_EXT_ADAPTEC
390 if (c->adaptec) {
391 mptr = &msg->body[4];
392 function = I2O_CMD_PRIVATE;
393
394 writel(TEN_WORD_MSG_SIZE | SGL_OFFSET_8, &msg->u.head[0]);
395
396 writel(I2O_VENDOR_DPT << 16 | I2O_DPT_FLASH_WRITE,
397 &msg->body[0]);
398 writel(i2o_config_dpt_region(swtype, swid), &msg->body[1]);
399 writel(*offset, &msg->body[2]);
400 writel(count, &msg->body[3]);
401 } else
402#endif
403 writel(NINE_WORD_MSG_SIZE | SGL_OFFSET_7, &msg->u.head[0]);
404
405 writel(0xD4000000 | count, mptr++);
406 writel(buffer.phys, mptr);
407
408 writel(function << 24 | HOST_TID << 12 | ADAPTER_TID, &msg->u.head[1]);
409 writel(i2o_config_driver.context, &msg->u.head[2]);
410 writel(0, &msg->u.head[3]);
411
412#ifdef CONFIG_I2O_EXT_ADAPTEC
413 if (!c->adaptec)
414#endif
415 {
416 writel((u32) swtype << 16 | (u32) 1 << 8, &msg->body[0]);
417 writel(0, &msg->body[1]);
418 writel(swid, &msg->body[2]);
419 }
420
421 status = i2o_msg_post_wait_mem(c, m, 60, &buffer);
422
423 if (status != -ETIMEDOUT)
424 i2o_dma_free(&c->pdev->dev, &buffer);
425
426 if (status != I2O_POST_WAIT_OK)
427 return -EIO;
428
429 *offset += count;
430
431 return count;
432
433 free_buffer:
434 i2o_dma_free(&c->pdev->dev, &buffer);
435
436 nop_msg:
437 i2o_msg_nop(c, m);
438
439 return rc;
440};
441
442/* attribute for HRT in sysfs */
443static struct bin_attribute i2o_config_hrt_attr = {
444 .attr = {
445 .name = "hrt",
446 .mode = S_IRUGO,
447 .owner = THIS_MODULE},
448 .size = 0,
449 .read = i2o_config_read_hrt
450};
451
452/* attribute for LCT in sysfs */
453static struct bin_attribute i2o_config_lct_attr = {
454 .attr = {
455 .name = "lct",
456 .mode = S_IRUGO,
457 .owner = THIS_MODULE},
458 .size = 0,
459 .read = i2o_config_read_lct
460};
461
462/* IRTOS firmware access */
463I2O_CONFIG_SW_ATTR(irtos, S_IWRSR, I2O_SOFTWARE_MODULE_IRTOS, 0);
464
465#ifdef CONFIG_I2O_EXT_ADAPTEC
466
467/*
468 * attribute for BIOS / SMOR, nvram and serial number access on DPT / Adaptec
469 * controllers
470 */
471I2O_CONFIG_SW_ATTR(bios, S_IWRSR, I2O_SOFTWARE_MODULE_IOP_PRIVATE, 0);
472I2O_CONFIG_SW_ATTR(nvram, S_IWRSR, I2O_SOFTWARE_MODULE_IOP_CONFIG, 0);
473I2O_CONFIG_SW_ATTR(serial, S_IWRSR, I2O_SOFTWARE_MODULE_IOP_CONFIG, 1);
474
475#endif
476
477/**
478 * i2o_config_notify_controller_add - Notify of added controller
479 * @c: the controller which was added
480 *
481 * If a I2O controller is added, we catch the notification to add sysfs
482 * entries.
483 */
484static void i2o_config_notify_controller_add(struct i2o_controller *c)
485{
486 struct kobject *kobj = &c->exec->device.kobj;
487
488 sysfs_create_bin_file(kobj, &i2o_config_hrt_attr);
489 sysfs_create_bin_file(kobj, &i2o_config_lct_attr);
490
491 sysfs_create_fops_file(kobj, &i2o_config_attr_irtos);
492#ifdef CONFIG_I2O_EXT_ADAPTEC
493 if (c->adaptec) {
494 sysfs_create_fops_file(kobj, &i2o_config_attr_bios);
495 sysfs_create_fops_file(kobj, &i2o_config_attr_nvram);
496 sysfs_create_fops_file(kobj, &i2o_config_attr_serial);
497 }
498#endif
499};
500
501/**
502 * i2o_config_notify_controller_remove - Notify of removed controller
503 * @c: the controller which was removed
504 *
505 * If a I2O controller is removed, we catch the notification to remove the
506 * sysfs entries.
507 */
508static void i2o_config_notify_controller_remove(struct i2o_controller *c)
509{
510 struct kobject *kobj = &c->exec->device.kobj;
511
512#ifdef CONFIG_I2O_EXT_ADAPTEC
513 if (c->adaptec) {
514 sysfs_remove_fops_file(kobj, &i2o_config_attr_serial);
515 sysfs_remove_fops_file(kobj, &i2o_config_attr_nvram);
516 sysfs_remove_fops_file(kobj, &i2o_config_attr_bios);
517 }
518#endif
519 sysfs_remove_fops_file(kobj, &i2o_config_attr_irtos);
520
521 sysfs_remove_bin_file(kobj, &i2o_config_lct_attr);
522 sysfs_remove_bin_file(kobj, &i2o_config_hrt_attr);
523};
524
525/* Config OSM driver struct */ 33/* Config OSM driver struct */
526static struct i2o_driver i2o_config_driver = { 34static struct i2o_driver i2o_config_driver = {
527 .name = OSM_NAME, 35 .name = OSM_NAME,
528 .notify_controller_add = i2o_config_notify_controller_add,
529 .notify_controller_remove = i2o_config_notify_controller_remove
530}; 36};
531 37
532#ifdef CONFIG_I2O_CONFIG_OLD_IOCTL 38#ifdef CONFIG_I2O_CONFIG_OLD_IOCTL