1 /******************************************************************************
4 * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
5 * Linux device driver for RTL8192SU
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of version 2 of the GNU General Public License as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
20 * Modifications for inclusion into the Linux staging tree are
21 * Copyright(c) 2010 Larry Finger. All rights reserved.
23 * Contact information:
24 * WLAN FAE <wlanfae@realtek.com>
25 * Larry Finger <Larry.Finger@lwfinger.net>
27 ******************************************************************************/
30 * The purpose of rtl871x_io.c
33 * b. provides the protocol engine
34 * c. provides the software interface between caller and the hardware interface
36 * For r8712u, both sync/async operations are provided.
38 * Only sync read/write_mem operations are provided.
42 #define _RTL871X_IO_C_
44 #include "osdep_service.h"
45 #include "drv_types.h"
46 #include "rtl871x_io.h"
47 #include "osdep_intf.h"
50 static uint
_init_intf_hdl(struct _adapter
*padapter
,
51 struct intf_hdl
*pintf_hdl
)
53 struct intf_priv
*pintf_priv
;
54 void (*set_intf_option
)(u32
*poption
) = NULL
;
55 void (*set_intf_funs
)(struct intf_hdl
*pintf_hdl
);
56 void (*set_intf_ops
)(struct _io_ops
*pops
);
57 uint (*init_intf_priv
)(struct intf_priv
*pintfpriv
);
59 set_intf_option
= &(r8712_usb_set_intf_option
);
60 set_intf_funs
= &(r8712_usb_set_intf_funs
);
61 set_intf_ops
= &r8712_usb_set_intf_ops
;
62 init_intf_priv
= &r8712_usb_init_intf_priv
;
63 pintf_priv
= pintf_hdl
->pintfpriv
= (struct intf_priv
*)
64 _malloc(sizeof(struct intf_priv
));
65 if (pintf_priv
== NULL
)
66 goto _init_intf_hdl_fail
;
67 pintf_hdl
->adapter
= (u8
*)padapter
;
68 set_intf_option(&pintf_hdl
->intf_option
);
69 set_intf_funs(pintf_hdl
);
70 set_intf_ops(&pintf_hdl
->io_ops
);
71 pintf_priv
->intf_dev
= (u8
*)&(padapter
->dvobjpriv
);
72 if (init_intf_priv(pintf_priv
) == _FAIL
)
73 goto _init_intf_hdl_fail
;
80 static void _unload_intf_hdl(struct intf_priv
*pintfpriv
)
82 void (*unload_intf_priv
)(struct intf_priv
*pintfpriv
);
84 unload_intf_priv
= &r8712_usb_unload_intf_priv
;
85 unload_intf_priv(pintfpriv
);
89 static uint
register_intf_hdl(u8
*dev
, struct intf_hdl
*pintfhdl
)
91 struct _adapter
*adapter
= (struct _adapter
*)dev
;
93 pintfhdl
->intf_option
= 0;
94 pintfhdl
->adapter
= dev
;
95 pintfhdl
->intf_dev
= (u8
*)&(adapter
->dvobjpriv
);
96 if (_init_intf_hdl(adapter
, pintfhdl
) == false)
97 goto register_intf_hdl_fail
;
99 register_intf_hdl_fail
:
103 static void unregister_intf_hdl(struct intf_hdl
*pintfhdl
)
105 _unload_intf_hdl(pintfhdl
->pintfpriv
);
106 memset((u8
*)pintfhdl
, 0, sizeof(struct intf_hdl
));
109 uint
r8712_alloc_io_queue(struct _adapter
*adapter
)
112 struct io_queue
*pio_queue
;
113 struct io_req
*pio_req
;
115 pio_queue
= (struct io_queue
*)_malloc(sizeof(struct io_queue
));
116 if (pio_queue
== NULL
)
117 goto alloc_io_queue_fail
;
118 _init_listhead(&pio_queue
->free_ioreqs
);
119 _init_listhead(&pio_queue
->processing
);
120 _init_listhead(&pio_queue
->pending
);
121 spin_lock_init(&pio_queue
->lock
);
122 pio_queue
->pallocated_free_ioreqs_buf
= (u8
*)_malloc(NUM_IOREQ
*
123 (sizeof(struct io_req
)) + 4);
124 if ((pio_queue
->pallocated_free_ioreqs_buf
) == NULL
)
125 goto alloc_io_queue_fail
;
126 memset(pio_queue
->pallocated_free_ioreqs_buf
, 0,
127 (NUM_IOREQ
* (sizeof(struct io_req
)) + 4));
128 pio_queue
->free_ioreqs_buf
= pio_queue
->pallocated_free_ioreqs_buf
+ 4
129 - ((addr_t
)(pio_queue
->pallocated_free_ioreqs_buf
)
131 pio_req
= (struct io_req
*)(pio_queue
->free_ioreqs_buf
);
132 for (i
= 0; i
< NUM_IOREQ
; i
++) {
133 _init_listhead(&pio_req
->list
);
134 sema_init(&pio_req
->sema
, 0);
135 list_insert_tail(&pio_req
->list
, &pio_queue
->free_ioreqs
);
138 if ((register_intf_hdl((u8
*)adapter
, &(pio_queue
->intf
))) == _FAIL
)
139 goto alloc_io_queue_fail
;
140 adapter
->pio_queue
= pio_queue
;
144 kfree(pio_queue
->pallocated_free_ioreqs_buf
);
145 kfree((u8
*)pio_queue
);
147 adapter
->pio_queue
= NULL
;
151 void r8712_free_io_queue(struct _adapter
*adapter
)
153 struct io_queue
*pio_queue
= (struct io_queue
*)(adapter
->pio_queue
);
156 kfree(pio_queue
->pallocated_free_ioreqs_buf
);
157 adapter
->pio_queue
= NULL
;
158 unregister_intf_hdl(&pio_queue
->intf
);
159 kfree((u8
*)pio_queue
);