]> git.karo-electronics.de Git - linux-beck.git/blob - drivers/infiniband/core/user_mad.c
Manual merge of for-linus to upstream (fix conflicts in drivers/infiniband/core/ucm.c)
[linux-beck.git] / drivers / infiniband / core / user_mad.c
1 /*
2  * Copyright (c) 2004 Topspin Communications.  All rights reserved.
3  * Copyright (c) 2005 Voltaire, Inc. All rights reserved. 
4  * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
5  *
6  * This software is available to you under a choice of one of two
7  * licenses.  You may choose to be licensed under the terms of the GNU
8  * General Public License (GPL) Version 2, available from the file
9  * COPYING in the main directory of this source tree, or the
10  * OpenIB.org BSD license below:
11  *
12  *     Redistribution and use in source and binary forms, with or
13  *     without modification, are permitted provided that the following
14  *     conditions are met:
15  *
16  *      - Redistributions of source code must retain the above
17  *        copyright notice, this list of conditions and the following
18  *        disclaimer.
19  *
20  *      - Redistributions in binary form must reproduce the above
21  *        copyright notice, this list of conditions and the following
22  *        disclaimer in the documentation and/or other materials
23  *        provided with the distribution.
24  *
25  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32  * SOFTWARE.
33  *
34  * $Id: user_mad.c 2814 2005-07-06 19:14:09Z halr $
35  */
36
37 #include <linux/module.h>
38 #include <linux/init.h>
39 #include <linux/device.h>
40 #include <linux/err.h>
41 #include <linux/fs.h>
42 #include <linux/cdev.h>
43 #include <linux/pci.h>
44 #include <linux/dma-mapping.h>
45 #include <linux/poll.h>
46 #include <linux/rwsem.h>
47 #include <linux/kref.h>
48
49 #include <asm/uaccess.h>
50 #include <asm/semaphore.h>
51
52 #include <rdma/ib_mad.h>
53 #include <rdma/ib_user_mad.h>
54
55 MODULE_AUTHOR("Roland Dreier");
56 MODULE_DESCRIPTION("InfiniBand userspace MAD packet access");
57 MODULE_LICENSE("Dual BSD/GPL");
58
59 enum {
60         IB_UMAD_MAX_PORTS  = 64,
61         IB_UMAD_MAX_AGENTS = 32,
62
63         IB_UMAD_MAJOR      = 231,
64         IB_UMAD_MINOR_BASE = 0
65 };
66
67 struct ib_umad_port {
68         int                    devnum;
69         struct cdev            dev;
70         struct class_device    class_dev;
71
72         int                    sm_devnum;
73         struct cdev            sm_dev;
74         struct class_device    sm_class_dev;
75         struct semaphore       sm_sem;
76
77         struct ib_device      *ib_dev;
78         struct ib_umad_device *umad_dev;
79         u8                     port_num;
80 };
81
82 struct ib_umad_device {
83         int                  start_port, end_port;
84         struct kref          ref;
85         struct ib_umad_port  port[0];
86 };
87
88 struct ib_umad_file {
89         struct ib_umad_port *port;
90         spinlock_t           recv_lock;
91         struct list_head     recv_list;
92         wait_queue_head_t    recv_wait;
93         struct rw_semaphore  agent_mutex;
94         struct ib_mad_agent *agent[IB_UMAD_MAX_AGENTS];
95         struct ib_mr        *mr[IB_UMAD_MAX_AGENTS];
96 };
97
98 struct ib_umad_packet {
99         struct ib_ah      *ah;
100         struct ib_mad_send_buf *msg;
101         struct list_head   list;
102         int                length;
103         DECLARE_PCI_UNMAP_ADDR(mapping)
104         struct ib_user_mad mad;
105 };
106
107 static const dev_t base_dev = MKDEV(IB_UMAD_MAJOR, IB_UMAD_MINOR_BASE);
108 static spinlock_t map_lock;
109 static DECLARE_BITMAP(dev_map, IB_UMAD_MAX_PORTS * 2);
110
111 static void ib_umad_add_one(struct ib_device *device);
112 static void ib_umad_remove_one(struct ib_device *device);
113
114 static int queue_packet(struct ib_umad_file *file,
115                         struct ib_mad_agent *agent,
116                         struct ib_umad_packet *packet)
117 {
118         int ret = 1;
119
120         down_read(&file->agent_mutex);
121         for (packet->mad.hdr.id = 0;
122              packet->mad.hdr.id < IB_UMAD_MAX_AGENTS;
123              packet->mad.hdr.id++)
124                 if (agent == file->agent[packet->mad.hdr.id]) {
125                         spin_lock_irq(&file->recv_lock);
126                         list_add_tail(&packet->list, &file->recv_list);
127                         spin_unlock_irq(&file->recv_lock);
128                         wake_up_interruptible(&file->recv_wait);
129                         ret = 0;
130                         break;
131                 }
132
133         up_read(&file->agent_mutex);
134
135         return ret;
136 }
137
138 static void send_handler(struct ib_mad_agent *agent,
139                          struct ib_mad_send_wc *send_wc)
140 {
141         struct ib_umad_file *file = agent->context;
142         struct ib_umad_packet *timeout, *packet =
143                 (void *) (unsigned long) send_wc->wr_id;
144
145         ib_destroy_ah(packet->msg->send_wr.wr.ud.ah);
146         ib_free_send_mad(packet->msg);
147
148         if (send_wc->status == IB_WC_RESP_TIMEOUT_ERR) {
149                 timeout = kmalloc(sizeof *timeout + sizeof (struct ib_mad_hdr),
150                                   GFP_KERNEL);
151                 if (!timeout)
152                         goto out;
153
154                 memset(timeout, 0, sizeof *timeout + sizeof (struct ib_mad_hdr));
155
156                 timeout->length = sizeof (struct ib_mad_hdr);
157                 timeout->mad.hdr.id = packet->mad.hdr.id;
158                 timeout->mad.hdr.status = ETIMEDOUT;
159                 memcpy(timeout->mad.data, packet->mad.data,
160                        sizeof (struct ib_mad_hdr));
161
162                 if (!queue_packet(file, agent, timeout))
163                                 return;
164         }
165 out:
166         kfree(packet);
167 }
168
169 static void recv_handler(struct ib_mad_agent *agent,
170                          struct ib_mad_recv_wc *mad_recv_wc)
171 {
172         struct ib_umad_file *file = agent->context;
173         struct ib_umad_packet *packet;
174         int length;
175
176         if (mad_recv_wc->wc->status != IB_WC_SUCCESS)
177                 goto out;
178
179         length = mad_recv_wc->mad_len;
180         packet = kmalloc(sizeof *packet + length, GFP_KERNEL);
181         if (!packet)
182                 goto out;
183
184         memset(packet, 0, sizeof *packet + length);
185         packet->length = length;
186
187         ib_coalesce_recv_mad(mad_recv_wc, packet->mad.data);
188
189         packet->mad.hdr.status    = 0;
190         packet->mad.hdr.length    = length + sizeof (struct ib_user_mad);
191         packet->mad.hdr.qpn       = cpu_to_be32(mad_recv_wc->wc->src_qp);
192         packet->mad.hdr.lid       = cpu_to_be16(mad_recv_wc->wc->slid);
193         packet->mad.hdr.sl        = mad_recv_wc->wc->sl;
194         packet->mad.hdr.path_bits = mad_recv_wc->wc->dlid_path_bits;
195         packet->mad.hdr.grh_present = !!(mad_recv_wc->wc->wc_flags & IB_WC_GRH);
196         if (packet->mad.hdr.grh_present) {
197                 /* XXX parse GRH */
198                 packet->mad.hdr.gid_index       = 0;
199                 packet->mad.hdr.hop_limit       = 0;
200                 packet->mad.hdr.traffic_class   = 0;
201                 memset(packet->mad.hdr.gid, 0, 16);
202                 packet->mad.hdr.flow_label      = 0;
203         }
204
205         if (queue_packet(file, agent, packet))
206                 kfree(packet);
207
208 out:
209         ib_free_recv_mad(mad_recv_wc);
210 }
211
212 static ssize_t ib_umad_read(struct file *filp, char __user *buf,
213                             size_t count, loff_t *pos)
214 {
215         struct ib_umad_file *file = filp->private_data;
216         struct ib_umad_packet *packet;
217         ssize_t ret;
218
219         if (count < sizeof (struct ib_user_mad) + sizeof (struct ib_mad))
220                 return -EINVAL;
221
222         spin_lock_irq(&file->recv_lock);
223
224         while (list_empty(&file->recv_list)) {
225                 spin_unlock_irq(&file->recv_lock);
226
227                 if (filp->f_flags & O_NONBLOCK)
228                         return -EAGAIN;
229
230                 if (wait_event_interruptible(file->recv_wait,
231                                              !list_empty(&file->recv_list)))
232                         return -ERESTARTSYS;
233
234                 spin_lock_irq(&file->recv_lock);
235         }
236
237         packet = list_entry(file->recv_list.next, struct ib_umad_packet, list);
238         list_del(&packet->list);
239
240         spin_unlock_irq(&file->recv_lock);
241
242         if (count < packet->length + sizeof (struct ib_user_mad)) {
243                 /* Return length needed (and first RMPP segment) if too small */
244                 if (copy_to_user(buf, &packet->mad,
245                                  sizeof (struct ib_user_mad) + sizeof (struct ib_mad)))
246                         ret = -EFAULT;
247                 else
248                         ret = -ENOSPC;
249         } else if (copy_to_user(buf, &packet->mad,
250                               packet->length + sizeof (struct ib_user_mad)))
251                 ret = -EFAULT;
252         else
253                 ret = packet->length + sizeof (struct ib_user_mad);
254         if (ret < 0) {
255                 /* Requeue packet */
256                 spin_lock_irq(&file->recv_lock);
257                 list_add(&packet->list, &file->recv_list);
258                 spin_unlock_irq(&file->recv_lock);
259         } else
260                 kfree(packet);
261         return ret;
262 }
263
264 static ssize_t ib_umad_write(struct file *filp, const char __user *buf,
265                              size_t count, loff_t *pos)
266 {
267         struct ib_umad_file *file = filp->private_data;
268         struct ib_umad_packet *packet;
269         struct ib_mad_agent *agent;
270         struct ib_ah_attr ah_attr;
271         struct ib_send_wr *bad_wr;
272         struct ib_rmpp_mad *rmpp_mad;
273         u8 method;
274         __be64 *tid;
275         int ret, length, hdr_len, data_len, rmpp_hdr_size;
276         int rmpp_active = 0;
277
278         if (count < sizeof (struct ib_user_mad))
279                 return -EINVAL;
280
281         length = count - sizeof (struct ib_user_mad);
282         packet = kmalloc(sizeof *packet + sizeof(struct ib_mad_hdr) +
283                          sizeof (struct ib_rmpp_hdr), GFP_KERNEL);
284         if (!packet)
285                 return -ENOMEM;
286
287         if (copy_from_user(&packet->mad, buf,
288                             sizeof (struct ib_user_mad) +
289                             sizeof (struct ib_mad_hdr) +
290                             sizeof (struct ib_rmpp_hdr))) {
291                 ret = -EFAULT;
292                 goto err;
293         }
294
295         if (packet->mad.hdr.id < 0 ||
296             packet->mad.hdr.id >= IB_UMAD_MAX_AGENTS) {
297                 ret = -EINVAL;
298                 goto err;
299         }
300
301         packet->length = length;
302
303         down_read(&file->agent_mutex);
304
305         agent = file->agent[packet->mad.hdr.id];
306         if (!agent) {
307                 ret = -EINVAL;
308                 goto err_up;
309         }
310
311         memset(&ah_attr, 0, sizeof ah_attr);
312         ah_attr.dlid          = be16_to_cpu(packet->mad.hdr.lid);
313         ah_attr.sl            = packet->mad.hdr.sl;
314         ah_attr.src_path_bits = packet->mad.hdr.path_bits;
315         ah_attr.port_num      = file->port->port_num;
316         if (packet->mad.hdr.grh_present) {
317                 ah_attr.ah_flags = IB_AH_GRH;
318                 memcpy(ah_attr.grh.dgid.raw, packet->mad.hdr.gid, 16);
319                 ah_attr.grh.flow_label     = be32_to_cpu(packet->mad.hdr.flow_label);
320                 ah_attr.grh.hop_limit      = packet->mad.hdr.hop_limit;
321                 ah_attr.grh.traffic_class  = packet->mad.hdr.traffic_class;
322         }
323
324         packet->ah = ib_create_ah(agent->qp->pd, &ah_attr);
325         if (IS_ERR(packet->ah)) {
326                 ret = PTR_ERR(packet->ah);
327                 goto err_up;
328         }
329
330         rmpp_mad = (struct ib_rmpp_mad *) packet->mad.data;
331         if (ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) & IB_MGMT_RMPP_FLAG_ACTIVE) {
332                 /* RMPP active */
333                 if (!agent->rmpp_version) {
334                         ret = -EINVAL;
335                         goto err_ah;
336                 }
337
338                 /* Validate that the management class can support RMPP */
339                 if (rmpp_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_ADM) {
340                         hdr_len = offsetof(struct ib_sa_mad, data);
341                         data_len = length - hdr_len;
342                 } else if ((rmpp_mad->mad_hdr.mgmt_class >= IB_MGMT_CLASS_VENDOR_RANGE2_START) &&
343                             (rmpp_mad->mad_hdr.mgmt_class <= IB_MGMT_CLASS_VENDOR_RANGE2_END)) {
344                                 hdr_len = offsetof(struct ib_vendor_mad, data);
345                                 data_len = length - hdr_len;
346                 } else {
347                         ret = -EINVAL;
348                         goto err_ah;
349                 }
350                 rmpp_active = 1;
351         } else {
352                 if (length > sizeof (struct ib_mad)) {
353                         ret = -EINVAL;
354                         goto err_ah;
355                 }
356                 hdr_len = offsetof(struct ib_mad, data);
357                 data_len = length - hdr_len;
358         }
359
360         packet->msg = ib_create_send_mad(agent,
361                                          be32_to_cpu(packet->mad.hdr.qpn),
362                                          0, packet->ah, rmpp_active,
363                                          hdr_len, data_len,
364                                          GFP_KERNEL);
365         if (IS_ERR(packet->msg)) {
366                 ret = PTR_ERR(packet->msg);
367                 goto err_ah;
368         }
369
370         packet->msg->send_wr.wr.ud.timeout_ms  = packet->mad.hdr.timeout_ms;
371         packet->msg->send_wr.wr.ud.retries = packet->mad.hdr.retries;
372
373         /* Override send WR WRID initialized in ib_create_send_mad */
374         packet->msg->send_wr.wr_id = (unsigned long) packet;
375
376         if (!rmpp_active) {
377                 /* Copy message from user into send buffer */
378                 if (copy_from_user(packet->msg->mad,
379                                    buf + sizeof (struct ib_user_mad), length)) {
380                         ret = -EFAULT;
381                         goto err_msg;
382                 }
383         } else {
384                 rmpp_hdr_size = sizeof (struct ib_mad_hdr) +
385                                 sizeof (struct ib_rmpp_hdr);
386
387                 /* Only copy MAD headers (RMPP header in place) */
388                 memcpy(packet->msg->mad, packet->mad.data,
389                        sizeof (struct ib_mad_hdr));
390
391                 /* Now, copy rest of message from user into send buffer */
392                 if (copy_from_user(((struct ib_rmpp_mad *) packet->msg->mad)->data,
393                                    buf + sizeof (struct ib_user_mad) + rmpp_hdr_size,
394                                    length - rmpp_hdr_size)) {
395                         ret = -EFAULT;
396                         goto err_msg;
397                 }
398         }
399
400         /*
401          * If userspace is generating a request that will generate a
402          * response, we need to make sure the high-order part of the
403          * transaction ID matches the agent being used to send the
404          * MAD.
405          */
406         method = packet->msg->mad->mad_hdr.method;
407
408         if (!(method & IB_MGMT_METHOD_RESP)       &&
409             method != IB_MGMT_METHOD_TRAP_REPRESS &&
410             method != IB_MGMT_METHOD_SEND) {
411                 tid = &packet->msg->mad->mad_hdr.tid;
412                 *tid = cpu_to_be64(((u64) agent->hi_tid) << 32 |
413                                    (be64_to_cpup(tid) & 0xffffffff));
414         }
415
416         ret = ib_post_send_mad(agent, &packet->msg->send_wr, &bad_wr);
417         if (ret)
418                 goto err_msg;
419
420         up_read(&file->agent_mutex);
421
422         return sizeof (struct ib_user_mad_hdr) + packet->length;
423
424 err_msg:
425         ib_free_send_mad(packet->msg);
426
427 err_ah:
428         ib_destroy_ah(packet->ah);
429
430 err_up:
431         up_read(&file->agent_mutex);
432
433 err:
434         kfree(packet);
435         return ret;
436 }
437
438 static unsigned int ib_umad_poll(struct file *filp, struct poll_table_struct *wait)
439 {
440         struct ib_umad_file *file = filp->private_data;
441
442         /* we will always be able to post a MAD send */
443         unsigned int mask = POLLOUT | POLLWRNORM;
444
445         poll_wait(filp, &file->recv_wait, wait);
446
447         if (!list_empty(&file->recv_list))
448                 mask |= POLLIN | POLLRDNORM;
449
450         return mask;
451 }
452
453 static int ib_umad_reg_agent(struct ib_umad_file *file, unsigned long arg)
454 {
455         struct ib_user_mad_reg_req ureq;
456         struct ib_mad_reg_req req;
457         struct ib_mad_agent *agent;
458         int agent_id;
459         int ret;
460
461         down_write(&file->agent_mutex);
462
463         if (copy_from_user(&ureq, (void __user *) arg, sizeof ureq)) {
464                 ret = -EFAULT;
465                 goto out;
466         }
467
468         if (ureq.qpn != 0 && ureq.qpn != 1) {
469                 ret = -EINVAL;
470                 goto out;
471         }
472
473         for (agent_id = 0; agent_id < IB_UMAD_MAX_AGENTS; ++agent_id)
474                 if (!file->agent[agent_id])
475                         goto found;
476
477         ret = -ENOMEM;
478         goto out;
479
480 found:
481         if (ureq.mgmt_class) {
482                 req.mgmt_class         = ureq.mgmt_class;
483                 req.mgmt_class_version = ureq.mgmt_class_version;
484                 memcpy(req.method_mask, ureq.method_mask, sizeof req.method_mask);
485                 memcpy(req.oui,         ureq.oui,         sizeof req.oui);
486         }
487
488         agent = ib_register_mad_agent(file->port->ib_dev, file->port->port_num,
489                                       ureq.qpn ? IB_QPT_GSI : IB_QPT_SMI,
490                                       ureq.mgmt_class ? &req : NULL,
491                                       ureq.rmpp_version,
492                                       send_handler, recv_handler, file);
493         if (IS_ERR(agent)) {
494                 ret = PTR_ERR(agent);
495                 goto out;
496         }
497
498         file->agent[agent_id] = agent;
499
500         file->mr[agent_id] = ib_get_dma_mr(agent->qp->pd, IB_ACCESS_LOCAL_WRITE);
501         if (IS_ERR(file->mr[agent_id])) {
502                 ret = -ENOMEM;
503                 goto err;
504         }
505
506         if (put_user(agent_id,
507                      (u32 __user *) (arg + offsetof(struct ib_user_mad_reg_req, id)))) {
508                 ret = -EFAULT;
509                 goto err_mr;
510         }
511
512         ret = 0;
513         goto out;
514
515 err_mr:
516         ib_dereg_mr(file->mr[agent_id]);
517
518 err:
519         file->agent[agent_id] = NULL;
520         ib_unregister_mad_agent(agent);
521
522 out:
523         up_write(&file->agent_mutex);
524         return ret;
525 }
526
527 static int ib_umad_unreg_agent(struct ib_umad_file *file, unsigned long arg)
528 {
529         u32 id;
530         int ret = 0;
531
532         down_write(&file->agent_mutex);
533
534         if (get_user(id, (u32 __user *) arg)) {
535                 ret = -EFAULT;
536                 goto out;
537         }
538
539         if (id < 0 || id >= IB_UMAD_MAX_AGENTS || !file->agent[id]) {
540                 ret = -EINVAL;
541                 goto out;
542         }
543
544         ib_dereg_mr(file->mr[id]);
545         ib_unregister_mad_agent(file->agent[id]);
546         file->agent[id] = NULL;
547
548 out:
549         up_write(&file->agent_mutex);
550         return ret;
551 }
552
553 static long ib_umad_ioctl(struct file *filp, unsigned int cmd,
554                           unsigned long arg)
555 {
556         switch (cmd) {
557         case IB_USER_MAD_REGISTER_AGENT:
558                 return ib_umad_reg_agent(filp->private_data, arg);
559         case IB_USER_MAD_UNREGISTER_AGENT:
560                 return ib_umad_unreg_agent(filp->private_data, arg);
561         default:
562                 return -ENOIOCTLCMD;
563         }
564 }
565
566 static int ib_umad_open(struct inode *inode, struct file *filp)
567 {
568         struct ib_umad_port *port =
569                 container_of(inode->i_cdev, struct ib_umad_port, dev);
570         struct ib_umad_file *file;
571
572         file = kmalloc(sizeof *file, GFP_KERNEL);
573         if (!file)
574                 return -ENOMEM;
575
576         memset(file, 0, sizeof *file);
577
578         spin_lock_init(&file->recv_lock);
579         init_rwsem(&file->agent_mutex);
580         INIT_LIST_HEAD(&file->recv_list);
581         init_waitqueue_head(&file->recv_wait);
582
583         file->port = port;
584         filp->private_data = file;
585
586         return 0;
587 }
588
589 static int ib_umad_close(struct inode *inode, struct file *filp)
590 {
591         struct ib_umad_file *file = filp->private_data;
592         struct ib_umad_packet *packet, *tmp;
593         int i;
594
595         for (i = 0; i < IB_UMAD_MAX_AGENTS; ++i)
596                 if (file->agent[i]) {
597                         ib_dereg_mr(file->mr[i]);
598                         ib_unregister_mad_agent(file->agent[i]);
599                 }
600
601         list_for_each_entry_safe(packet, tmp, &file->recv_list, list)
602                 kfree(packet);
603
604         kfree(file);
605
606         return 0;
607 }
608
609 static struct file_operations umad_fops = {
610         .owner          = THIS_MODULE,
611         .read           = ib_umad_read,
612         .write          = ib_umad_write,
613         .poll           = ib_umad_poll,
614         .unlocked_ioctl = ib_umad_ioctl,
615         .compat_ioctl   = ib_umad_ioctl,
616         .open           = ib_umad_open,
617         .release        = ib_umad_close
618 };
619
620 static int ib_umad_sm_open(struct inode *inode, struct file *filp)
621 {
622         struct ib_umad_port *port =
623                 container_of(inode->i_cdev, struct ib_umad_port, sm_dev);
624         struct ib_port_modify props = {
625                 .set_port_cap_mask = IB_PORT_SM
626         };
627         int ret;
628
629         if (filp->f_flags & O_NONBLOCK) {
630                 if (down_trylock(&port->sm_sem))
631                         return -EAGAIN;
632         } else {
633                 if (down_interruptible(&port->sm_sem))
634                         return -ERESTARTSYS;
635         }
636
637         ret = ib_modify_port(port->ib_dev, port->port_num, 0, &props);
638         if (ret) {
639                 up(&port->sm_sem);
640                 return ret;
641         }
642
643         filp->private_data = port;
644
645         return 0;
646 }
647
648 static int ib_umad_sm_close(struct inode *inode, struct file *filp)
649 {
650         struct ib_umad_port *port = filp->private_data;
651         struct ib_port_modify props = {
652                 .clr_port_cap_mask = IB_PORT_SM
653         };
654         int ret;
655
656         ret = ib_modify_port(port->ib_dev, port->port_num, 0, &props);
657         up(&port->sm_sem);
658
659         return ret;
660 }
661
662 static struct file_operations umad_sm_fops = {
663         .owner   = THIS_MODULE,
664         .open    = ib_umad_sm_open,
665         .release = ib_umad_sm_close
666 };
667
668 static struct ib_client umad_client = {
669         .name   = "umad",
670         .add    = ib_umad_add_one,
671         .remove = ib_umad_remove_one
672 };
673
674 static ssize_t show_ibdev(struct class_device *class_dev, char *buf)
675 {
676         struct ib_umad_port *port = class_get_devdata(class_dev);
677
678         return sprintf(buf, "%s\n", port->ib_dev->name);
679 }
680 static CLASS_DEVICE_ATTR(ibdev, S_IRUGO, show_ibdev, NULL);
681
682 static ssize_t show_port(struct class_device *class_dev, char *buf)
683 {
684         struct ib_umad_port *port = class_get_devdata(class_dev);
685
686         return sprintf(buf, "%d\n", port->port_num);
687 }
688 static CLASS_DEVICE_ATTR(port, S_IRUGO, show_port, NULL);
689
690 static void ib_umad_release_dev(struct kref *ref)
691 {
692         struct ib_umad_device *dev =
693                 container_of(ref, struct ib_umad_device, ref);
694
695         kfree(dev);
696 }
697
698 static void ib_umad_release_port(struct class_device *class_dev)
699 {
700         struct ib_umad_port *port = class_get_devdata(class_dev);
701
702         if (class_dev == &port->class_dev) {
703                 cdev_del(&port->dev);
704                 clear_bit(port->devnum, dev_map);
705         } else {
706                 cdev_del(&port->sm_dev);
707                 clear_bit(port->sm_devnum, dev_map);
708         }
709
710         kref_put(&port->umad_dev->ref, ib_umad_release_dev);
711 }
712
713 static struct class umad_class = {
714         .name    = "infiniband_mad",
715         .release = ib_umad_release_port
716 };
717
718 static ssize_t show_abi_version(struct class *class, char *buf)
719 {
720         return sprintf(buf, "%d\n", IB_USER_MAD_ABI_VERSION);
721 }
722 static CLASS_ATTR(abi_version, S_IRUGO, show_abi_version, NULL);
723
724 static int ib_umad_init_port(struct ib_device *device, int port_num,
725                              struct ib_umad_port *port)
726 {
727         spin_lock(&map_lock);
728         port->devnum = find_first_zero_bit(dev_map, IB_UMAD_MAX_PORTS);
729         if (port->devnum >= IB_UMAD_MAX_PORTS) {
730                 spin_unlock(&map_lock);
731                 return -1;
732         }
733         port->sm_devnum = find_next_zero_bit(dev_map, IB_UMAD_MAX_PORTS * 2, IB_UMAD_MAX_PORTS);
734         if (port->sm_devnum >= IB_UMAD_MAX_PORTS * 2) {
735                 spin_unlock(&map_lock);
736                 return -1;
737         }
738         set_bit(port->devnum, dev_map);
739         set_bit(port->sm_devnum, dev_map);
740         spin_unlock(&map_lock);
741
742         port->ib_dev   = device;
743         port->port_num = port_num;
744         init_MUTEX(&port->sm_sem);
745
746         cdev_init(&port->dev, &umad_fops);
747         port->dev.owner = THIS_MODULE;
748         kobject_set_name(&port->dev.kobj, "umad%d", port->devnum);
749         if (cdev_add(&port->dev, base_dev + port->devnum, 1))
750                 return -1;
751
752         port->class_dev.class = &umad_class;
753         port->class_dev.dev   = device->dma_device;
754         port->class_dev.devt  = port->dev.dev;
755
756         snprintf(port->class_dev.class_id, BUS_ID_SIZE, "umad%d", port->devnum);
757
758         if (class_device_register(&port->class_dev))
759                 goto err_cdev;
760
761         class_set_devdata(&port->class_dev, port);
762         kref_get(&port->umad_dev->ref);
763
764         if (class_device_create_file(&port->class_dev, &class_device_attr_ibdev))
765                 goto err_class;
766         if (class_device_create_file(&port->class_dev, &class_device_attr_port))
767                 goto err_class;
768
769         cdev_init(&port->sm_dev, &umad_sm_fops);
770         port->sm_dev.owner = THIS_MODULE;
771         kobject_set_name(&port->dev.kobj, "issm%d", port->sm_devnum - IB_UMAD_MAX_PORTS);
772         if (cdev_add(&port->sm_dev, base_dev + port->sm_devnum, 1))
773                 return -1;
774
775         port->sm_class_dev.class = &umad_class;
776         port->sm_class_dev.dev   = device->dma_device;
777         port->sm_class_dev.devt  = port->sm_dev.dev;
778
779         snprintf(port->sm_class_dev.class_id, BUS_ID_SIZE, "issm%d", port->sm_devnum - IB_UMAD_MAX_PORTS);
780
781         if (class_device_register(&port->sm_class_dev))
782                 goto err_sm_cdev;
783
784         class_set_devdata(&port->sm_class_dev, port);
785         kref_get(&port->umad_dev->ref);
786
787         if (class_device_create_file(&port->sm_class_dev, &class_device_attr_ibdev))
788                 goto err_sm_class;
789         if (class_device_create_file(&port->sm_class_dev, &class_device_attr_port))
790                 goto err_sm_class;
791
792         return 0;
793
794 err_sm_class:
795         class_device_unregister(&port->sm_class_dev);
796
797 err_sm_cdev:
798         cdev_del(&port->sm_dev);
799
800 err_class:
801         class_device_unregister(&port->class_dev);
802
803 err_cdev:
804         cdev_del(&port->dev);
805         clear_bit(port->devnum, dev_map);
806
807         return -1;
808 }
809
810 static void ib_umad_add_one(struct ib_device *device)
811 {
812         struct ib_umad_device *umad_dev;
813         int s, e, i;
814
815         if (device->node_type == IB_NODE_SWITCH)
816                 s = e = 0;
817         else {
818                 s = 1;
819                 e = device->phys_port_cnt;
820         }
821
822         umad_dev = kmalloc(sizeof *umad_dev +
823                            (e - s + 1) * sizeof (struct ib_umad_port),
824                            GFP_KERNEL);
825         if (!umad_dev)
826                 return;
827
828         memset(umad_dev, 0, sizeof *umad_dev +
829                (e - s + 1) * sizeof (struct ib_umad_port));
830
831         kref_init(&umad_dev->ref);
832
833         umad_dev->start_port = s;
834         umad_dev->end_port   = e;
835
836         for (i = s; i <= e; ++i) {
837                 umad_dev->port[i - s].umad_dev = umad_dev;
838
839                 if (ib_umad_init_port(device, i, &umad_dev->port[i - s]))
840                         goto err;
841         }
842
843         ib_set_client_data(device, &umad_client, umad_dev);
844
845         return;
846
847 err:
848         while (--i >= s) {
849                 class_device_unregister(&umad_dev->port[i - s].class_dev);
850                 class_device_unregister(&umad_dev->port[i - s].sm_class_dev);
851         }
852
853         kref_put(&umad_dev->ref, ib_umad_release_dev);
854 }
855
856 static void ib_umad_remove_one(struct ib_device *device)
857 {
858         struct ib_umad_device *umad_dev = ib_get_client_data(device, &umad_client);
859         int i;
860
861         if (!umad_dev)
862                 return;
863
864         for (i = 0; i <= umad_dev->end_port - umad_dev->start_port; ++i) {
865                 class_device_unregister(&umad_dev->port[i].class_dev);
866                 class_device_unregister(&umad_dev->port[i].sm_class_dev);
867         }
868
869         kref_put(&umad_dev->ref, ib_umad_release_dev);
870 }
871
872 static int __init ib_umad_init(void)
873 {
874         int ret;
875
876         spin_lock_init(&map_lock);
877
878         ret = register_chrdev_region(base_dev, IB_UMAD_MAX_PORTS * 2,
879                                      "infiniband_mad");
880         if (ret) {
881                 printk(KERN_ERR "user_mad: couldn't register device number\n");
882                 goto out;
883         }
884
885         ret = class_register(&umad_class);
886         if (ret) {
887                 printk(KERN_ERR "user_mad: couldn't create class infiniband_mad\n");
888                 goto out_chrdev;
889         }
890
891         ret = class_create_file(&umad_class, &class_attr_abi_version);
892         if (ret) {
893                 printk(KERN_ERR "user_mad: couldn't create abi_version attribute\n");
894                 goto out_class;
895         }
896
897         ret = ib_register_client(&umad_client);
898         if (ret) {
899                 printk(KERN_ERR "user_mad: couldn't register ib_umad client\n");
900                 goto out_class;
901         }
902
903         return 0;
904
905 out_class:
906         class_unregister(&umad_class);
907
908 out_chrdev:
909         unregister_chrdev_region(base_dev, IB_UMAD_MAX_PORTS * 2);
910
911 out:
912         return ret;
913 }
914
915 static void __exit ib_umad_cleanup(void)
916 {
917         ib_unregister_client(&umad_client);
918         class_unregister(&umad_class);
919         unregister_chrdev_region(base_dev, IB_UMAD_MAX_PORTS * 2);
920 }
921
922 module_init(ib_umad_init);
923 module_exit(ib_umad_cleanup);