Commit 3dbda77e6f3375f87090cfce97b2551d3723521b

Authored by Uwe Kleine-Koenig
Committed by Jiri Kosina
1 parent 31d0f84591

trivial: fix typos "man[ae]g?ment" -> "management"

Signed-off-by: Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>

Showing 18 changed files with 21 additions and 21 deletions Inline Diff

Documentation/DocBook/mtdnand.tmpl
1 <?xml version="1.0" encoding="UTF-8"?> 1 <?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" 2 <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
3 "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []> 3 "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
4 4
5 <book id="MTD-NAND-Guide"> 5 <book id="MTD-NAND-Guide">
6 <bookinfo> 6 <bookinfo>
7 <title>MTD NAND Driver Programming Interface</title> 7 <title>MTD NAND Driver Programming Interface</title>
8 8
9 <authorgroup> 9 <authorgroup>
10 <author> 10 <author>
11 <firstname>Thomas</firstname> 11 <firstname>Thomas</firstname>
12 <surname>Gleixner</surname> 12 <surname>Gleixner</surname>
13 <affiliation> 13 <affiliation>
14 <address> 14 <address>
15 <email>tglx@linutronix.de</email> 15 <email>tglx@linutronix.de</email>
16 </address> 16 </address>
17 </affiliation> 17 </affiliation>
18 </author> 18 </author>
19 </authorgroup> 19 </authorgroup>
20 20
21 <copyright> 21 <copyright>
22 <year>2004</year> 22 <year>2004</year>
23 <holder>Thomas Gleixner</holder> 23 <holder>Thomas Gleixner</holder>
24 </copyright> 24 </copyright>
25 25
26 <legalnotice> 26 <legalnotice>
27 <para> 27 <para>
28 This documentation is free software; you can redistribute 28 This documentation is free software; you can redistribute
29 it and/or modify it under the terms of the GNU General Public 29 it and/or modify it under the terms of the GNU General Public
30 License version 2 as published by the Free Software Foundation. 30 License version 2 as published by the Free Software Foundation.
31 </para> 31 </para>
32 32
33 <para> 33 <para>
34 This program is distributed in the hope that it will be 34 This program is distributed in the hope that it will be
35 useful, but WITHOUT ANY WARRANTY; without even the implied 35 useful, but WITHOUT ANY WARRANTY; without even the implied
36 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 36 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
37 See the GNU General Public License for more details. 37 See the GNU General Public License for more details.
38 </para> 38 </para>
39 39
40 <para> 40 <para>
41 You should have received a copy of the GNU General Public 41 You should have received a copy of the GNU General Public
42 License along with this program; if not, write to the Free 42 License along with this program; if not, write to the Free
43 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, 43 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
44 MA 02111-1307 USA 44 MA 02111-1307 USA
45 </para> 45 </para>
46 46
47 <para> 47 <para>
48 For more details see the file COPYING in the source 48 For more details see the file COPYING in the source
49 distribution of Linux. 49 distribution of Linux.
50 </para> 50 </para>
51 </legalnotice> 51 </legalnotice>
52 </bookinfo> 52 </bookinfo>
53 53
54 <toc></toc> 54 <toc></toc>
55 55
56 <chapter id="intro"> 56 <chapter id="intro">
57 <title>Introduction</title> 57 <title>Introduction</title>
58 <para> 58 <para>
59 The generic NAND driver supports almost all NAND and AG-AND based 59 The generic NAND driver supports almost all NAND and AG-AND based
60 chips and connects them to the Memory Technology Devices (MTD) 60 chips and connects them to the Memory Technology Devices (MTD)
61 subsystem of the Linux Kernel. 61 subsystem of the Linux Kernel.
62 </para> 62 </para>
63 <para> 63 <para>
64 This documentation is provided for developers who want to implement 64 This documentation is provided for developers who want to implement
65 board drivers or filesystem drivers suitable for NAND devices. 65 board drivers or filesystem drivers suitable for NAND devices.
66 </para> 66 </para>
67 </chapter> 67 </chapter>
68 68
69 <chapter id="bugs"> 69 <chapter id="bugs">
70 <title>Known Bugs And Assumptions</title> 70 <title>Known Bugs And Assumptions</title>
71 <para> 71 <para>
72 None. 72 None.
73 </para> 73 </para>
74 </chapter> 74 </chapter>
75 75
76 <chapter id="dochints"> 76 <chapter id="dochints">
77 <title>Documentation hints</title> 77 <title>Documentation hints</title>
78 <para> 78 <para>
79 The function and structure docs are autogenerated. Each function and 79 The function and structure docs are autogenerated. Each function and
80 struct member has a short description which is marked with an [XXX] identifier. 80 struct member has a short description which is marked with an [XXX] identifier.
81 The following chapters explain the meaning of those identifiers. 81 The following chapters explain the meaning of those identifiers.
82 </para> 82 </para>
83 <sect1 id="Function_identifiers_XXX"> 83 <sect1 id="Function_identifiers_XXX">
84 <title>Function identifiers [XXX]</title> 84 <title>Function identifiers [XXX]</title>
85 <para> 85 <para>
86 The functions are marked with [XXX] identifiers in the short 86 The functions are marked with [XXX] identifiers in the short
87 comment. The identifiers explain the usage and scope of the 87 comment. The identifiers explain the usage and scope of the
88 functions. Following identifiers are used: 88 functions. Following identifiers are used:
89 </para> 89 </para>
90 <itemizedlist> 90 <itemizedlist>
91 <listitem><para> 91 <listitem><para>
92 [MTD Interface]</para><para> 92 [MTD Interface]</para><para>
93 These functions provide the interface to the MTD kernel API. 93 These functions provide the interface to the MTD kernel API.
94 They are not replacable and provide functionality 94 They are not replacable and provide functionality
95 which is complete hardware independent. 95 which is complete hardware independent.
96 </para></listitem> 96 </para></listitem>
97 <listitem><para> 97 <listitem><para>
98 [NAND Interface]</para><para> 98 [NAND Interface]</para><para>
99 These functions are exported and provide the interface to the NAND kernel API. 99 These functions are exported and provide the interface to the NAND kernel API.
100 </para></listitem> 100 </para></listitem>
101 <listitem><para> 101 <listitem><para>
102 [GENERIC]</para><para> 102 [GENERIC]</para><para>
103 Generic functions are not replacable and provide functionality 103 Generic functions are not replacable and provide functionality
104 which is complete hardware independent. 104 which is complete hardware independent.
105 </para></listitem> 105 </para></listitem>
106 <listitem><para> 106 <listitem><para>
107 [DEFAULT]</para><para> 107 [DEFAULT]</para><para>
108 Default functions provide hardware related functionality which is suitable 108 Default functions provide hardware related functionality which is suitable
109 for most of the implementations. These functions can be replaced by the 109 for most of the implementations. These functions can be replaced by the
110 board driver if neccecary. Those functions are called via pointers in the 110 board driver if neccecary. Those functions are called via pointers in the
111 NAND chip description structure. The board driver can set the functions which 111 NAND chip description structure. The board driver can set the functions which
112 should be replaced by board dependent functions before calling nand_scan(). 112 should be replaced by board dependent functions before calling nand_scan().
113 If the function pointer is NULL on entry to nand_scan() then the pointer 113 If the function pointer is NULL on entry to nand_scan() then the pointer
114 is set to the default function which is suitable for the detected chip type. 114 is set to the default function which is suitable for the detected chip type.
115 </para></listitem> 115 </para></listitem>
116 </itemizedlist> 116 </itemizedlist>
117 </sect1> 117 </sect1>
118 <sect1 id="Struct_member_identifiers_XXX"> 118 <sect1 id="Struct_member_identifiers_XXX">
119 <title>Struct member identifiers [XXX]</title> 119 <title>Struct member identifiers [XXX]</title>
120 <para> 120 <para>
121 The struct members are marked with [XXX] identifiers in the 121 The struct members are marked with [XXX] identifiers in the
122 comment. The identifiers explain the usage and scope of the 122 comment. The identifiers explain the usage and scope of the
123 members. Following identifiers are used: 123 members. Following identifiers are used:
124 </para> 124 </para>
125 <itemizedlist> 125 <itemizedlist>
126 <listitem><para> 126 <listitem><para>
127 [INTERN]</para><para> 127 [INTERN]</para><para>
128 These members are for NAND driver internal use only and must not be 128 These members are for NAND driver internal use only and must not be
129 modified. Most of these values are calculated from the chip geometry 129 modified. Most of these values are calculated from the chip geometry
130 information which is evaluated during nand_scan(). 130 information which is evaluated during nand_scan().
131 </para></listitem> 131 </para></listitem>
132 <listitem><para> 132 <listitem><para>
133 [REPLACEABLE]</para><para> 133 [REPLACEABLE]</para><para>
134 Replaceable members hold hardware related functions which can be 134 Replaceable members hold hardware related functions which can be
135 provided by the board driver. The board driver can set the functions which 135 provided by the board driver. The board driver can set the functions which
136 should be replaced by board dependent functions before calling nand_scan(). 136 should be replaced by board dependent functions before calling nand_scan().
137 If the function pointer is NULL on entry to nand_scan() then the pointer 137 If the function pointer is NULL on entry to nand_scan() then the pointer
138 is set to the default function which is suitable for the detected chip type. 138 is set to the default function which is suitable for the detected chip type.
139 </para></listitem> 139 </para></listitem>
140 <listitem><para> 140 <listitem><para>
141 [BOARDSPECIFIC]</para><para> 141 [BOARDSPECIFIC]</para><para>
142 Board specific members hold hardware related information which must 142 Board specific members hold hardware related information which must
143 be provided by the board driver. The board driver must set the function 143 be provided by the board driver. The board driver must set the function
144 pointers and datafields before calling nand_scan(). 144 pointers and datafields before calling nand_scan().
145 </para></listitem> 145 </para></listitem>
146 <listitem><para> 146 <listitem><para>
147 [OPTIONAL]</para><para> 147 [OPTIONAL]</para><para>
148 Optional members can hold information relevant for the board driver. The 148 Optional members can hold information relevant for the board driver. The
149 generic NAND driver code does not use this information. 149 generic NAND driver code does not use this information.
150 </para></listitem> 150 </para></listitem>
151 </itemizedlist> 151 </itemizedlist>
152 </sect1> 152 </sect1>
153 </chapter> 153 </chapter>
154 154
155 <chapter id="basicboarddriver"> 155 <chapter id="basicboarddriver">
156 <title>Basic board driver</title> 156 <title>Basic board driver</title>
157 <para> 157 <para>
158 For most boards it will be sufficient to provide just the 158 For most boards it will be sufficient to provide just the
159 basic functions and fill out some really board dependent 159 basic functions and fill out some really board dependent
160 members in the nand chip description structure. 160 members in the nand chip description structure.
161 </para> 161 </para>
162 <sect1 id="Basic_defines"> 162 <sect1 id="Basic_defines">
163 <title>Basic defines</title> 163 <title>Basic defines</title>
164 <para> 164 <para>
165 At least you have to provide a mtd structure and 165 At least you have to provide a mtd structure and
166 a storage for the ioremap'ed chip address. 166 a storage for the ioremap'ed chip address.
167 You can allocate the mtd structure using kmalloc 167 You can allocate the mtd structure using kmalloc
168 or you can allocate it statically. 168 or you can allocate it statically.
169 In case of static allocation you have to allocate 169 In case of static allocation you have to allocate
170 a nand_chip structure too. 170 a nand_chip structure too.
171 </para> 171 </para>
172 <para> 172 <para>
173 Kmalloc based example 173 Kmalloc based example
174 </para> 174 </para>
175 <programlisting> 175 <programlisting>
176 static struct mtd_info *board_mtd; 176 static struct mtd_info *board_mtd;
177 static unsigned long baseaddr; 177 static unsigned long baseaddr;
178 </programlisting> 178 </programlisting>
179 <para> 179 <para>
180 Static example 180 Static example
181 </para> 181 </para>
182 <programlisting> 182 <programlisting>
183 static struct mtd_info board_mtd; 183 static struct mtd_info board_mtd;
184 static struct nand_chip board_chip; 184 static struct nand_chip board_chip;
185 static unsigned long baseaddr; 185 static unsigned long baseaddr;
186 </programlisting> 186 </programlisting>
187 </sect1> 187 </sect1>
188 <sect1 id="Partition_defines"> 188 <sect1 id="Partition_defines">
189 <title>Partition defines</title> 189 <title>Partition defines</title>
190 <para> 190 <para>
191 If you want to divide your device into partitions, then 191 If you want to divide your device into partitions, then
192 enable the configuration switch CONFIG_MTD_PARTITIONS and define 192 enable the configuration switch CONFIG_MTD_PARTITIONS and define
193 a partitioning scheme suitable to your board. 193 a partitioning scheme suitable to your board.
194 </para> 194 </para>
195 <programlisting> 195 <programlisting>
196 #define NUM_PARTITIONS 2 196 #define NUM_PARTITIONS 2
197 static struct mtd_partition partition_info[] = { 197 static struct mtd_partition partition_info[] = {
198 { .name = "Flash partition 1", 198 { .name = "Flash partition 1",
199 .offset = 0, 199 .offset = 0,
200 .size = 8 * 1024 * 1024 }, 200 .size = 8 * 1024 * 1024 },
201 { .name = "Flash partition 2", 201 { .name = "Flash partition 2",
202 .offset = MTDPART_OFS_NEXT, 202 .offset = MTDPART_OFS_NEXT,
203 .size = MTDPART_SIZ_FULL }, 203 .size = MTDPART_SIZ_FULL },
204 }; 204 };
205 </programlisting> 205 </programlisting>
206 </sect1> 206 </sect1>
207 <sect1 id="Hardware_control_functions"> 207 <sect1 id="Hardware_control_functions">
208 <title>Hardware control function</title> 208 <title>Hardware control function</title>
209 <para> 209 <para>
210 The hardware control function provides access to the 210 The hardware control function provides access to the
211 control pins of the NAND chip(s). 211 control pins of the NAND chip(s).
212 The access can be done by GPIO pins or by address lines. 212 The access can be done by GPIO pins or by address lines.
213 If you use address lines, make sure that the timing 213 If you use address lines, make sure that the timing
214 requirements are met. 214 requirements are met.
215 </para> 215 </para>
216 <para> 216 <para>
217 <emphasis>GPIO based example</emphasis> 217 <emphasis>GPIO based example</emphasis>
218 </para> 218 </para>
219 <programlisting> 219 <programlisting>
220 static void board_hwcontrol(struct mtd_info *mtd, int cmd) 220 static void board_hwcontrol(struct mtd_info *mtd, int cmd)
221 { 221 {
222 switch(cmd){ 222 switch(cmd){
223 case NAND_CTL_SETCLE: /* Set CLE pin high */ break; 223 case NAND_CTL_SETCLE: /* Set CLE pin high */ break;
224 case NAND_CTL_CLRCLE: /* Set CLE pin low */ break; 224 case NAND_CTL_CLRCLE: /* Set CLE pin low */ break;
225 case NAND_CTL_SETALE: /* Set ALE pin high */ break; 225 case NAND_CTL_SETALE: /* Set ALE pin high */ break;
226 case NAND_CTL_CLRALE: /* Set ALE pin low */ break; 226 case NAND_CTL_CLRALE: /* Set ALE pin low */ break;
227 case NAND_CTL_SETNCE: /* Set nCE pin low */ break; 227 case NAND_CTL_SETNCE: /* Set nCE pin low */ break;
228 case NAND_CTL_CLRNCE: /* Set nCE pin high */ break; 228 case NAND_CTL_CLRNCE: /* Set nCE pin high */ break;
229 } 229 }
230 } 230 }
231 </programlisting> 231 </programlisting>
232 <para> 232 <para>
233 <emphasis>Address lines based example.</emphasis> It's assumed that the 233 <emphasis>Address lines based example.</emphasis> It's assumed that the
234 nCE pin is driven by a chip select decoder. 234 nCE pin is driven by a chip select decoder.
235 </para> 235 </para>
236 <programlisting> 236 <programlisting>
237 static void board_hwcontrol(struct mtd_info *mtd, int cmd) 237 static void board_hwcontrol(struct mtd_info *mtd, int cmd)
238 { 238 {
239 struct nand_chip *this = (struct nand_chip *) mtd->priv; 239 struct nand_chip *this = (struct nand_chip *) mtd->priv;
240 switch(cmd){ 240 switch(cmd){
241 case NAND_CTL_SETCLE: this->IO_ADDR_W |= CLE_ADRR_BIT; break; 241 case NAND_CTL_SETCLE: this->IO_ADDR_W |= CLE_ADRR_BIT; break;
242 case NAND_CTL_CLRCLE: this->IO_ADDR_W &amp;= ~CLE_ADRR_BIT; break; 242 case NAND_CTL_CLRCLE: this->IO_ADDR_W &amp;= ~CLE_ADRR_BIT; break;
243 case NAND_CTL_SETALE: this->IO_ADDR_W |= ALE_ADRR_BIT; break; 243 case NAND_CTL_SETALE: this->IO_ADDR_W |= ALE_ADRR_BIT; break;
244 case NAND_CTL_CLRALE: this->IO_ADDR_W &amp;= ~ALE_ADRR_BIT; break; 244 case NAND_CTL_CLRALE: this->IO_ADDR_W &amp;= ~ALE_ADRR_BIT; break;
245 } 245 }
246 } 246 }
247 </programlisting> 247 </programlisting>
248 </sect1> 248 </sect1>
249 <sect1 id="Device_ready_function"> 249 <sect1 id="Device_ready_function">
250 <title>Device ready function</title> 250 <title>Device ready function</title>
251 <para> 251 <para>
252 If the hardware interface has the ready busy pin of the NAND chip connected to a 252 If the hardware interface has the ready busy pin of the NAND chip connected to a
253 GPIO or other accesible I/O pin, this function is used to read back the state of the 253 GPIO or other accesible I/O pin, this function is used to read back the state of the
254 pin. The function has no arguments and should return 0, if the device is busy (R/B pin 254 pin. The function has no arguments and should return 0, if the device is busy (R/B pin
255 is low) and 1, if the device is ready (R/B pin is high). 255 is low) and 1, if the device is ready (R/B pin is high).
256 If the hardware interface does not give access to the ready busy pin, then 256 If the hardware interface does not give access to the ready busy pin, then
257 the function must not be defined and the function pointer this->dev_ready is set to NULL. 257 the function must not be defined and the function pointer this->dev_ready is set to NULL.
258 </para> 258 </para>
259 </sect1> 259 </sect1>
260 <sect1 id="Init_function"> 260 <sect1 id="Init_function">
261 <title>Init function</title> 261 <title>Init function</title>
262 <para> 262 <para>
263 The init function allocates memory and sets up all the board 263 The init function allocates memory and sets up all the board
264 specific parameters and function pointers. When everything 264 specific parameters and function pointers. When everything
265 is set up nand_scan() is called. This function tries to 265 is set up nand_scan() is called. This function tries to
266 detect and identify then chip. If a chip is found all the 266 detect and identify then chip. If a chip is found all the
267 internal data fields are initialized accordingly. 267 internal data fields are initialized accordingly.
268 The structure(s) have to be zeroed out first and then filled with the neccecary 268 The structure(s) have to be zeroed out first and then filled with the neccecary
269 information about the device. 269 information about the device.
270 </para> 270 </para>
271 <programlisting> 271 <programlisting>
272 int __init board_init (void) 272 int __init board_init (void)
273 { 273 {
274 struct nand_chip *this; 274 struct nand_chip *this;
275 int err = 0; 275 int err = 0;
276 276
277 /* Allocate memory for MTD device structure and private data */ 277 /* Allocate memory for MTD device structure and private data */
278 board_mtd = kzalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL); 278 board_mtd = kzalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
279 if (!board_mtd) { 279 if (!board_mtd) {
280 printk ("Unable to allocate NAND MTD device structure.\n"); 280 printk ("Unable to allocate NAND MTD device structure.\n");
281 err = -ENOMEM; 281 err = -ENOMEM;
282 goto out; 282 goto out;
283 } 283 }
284 284
285 /* map physical address */ 285 /* map physical address */
286 baseaddr = (unsigned long)ioremap(CHIP_PHYSICAL_ADDRESS, 1024); 286 baseaddr = (unsigned long)ioremap(CHIP_PHYSICAL_ADDRESS, 1024);
287 if(!baseaddr){ 287 if(!baseaddr){
288 printk("Ioremap to access NAND chip failed\n"); 288 printk("Ioremap to access NAND chip failed\n");
289 err = -EIO; 289 err = -EIO;
290 goto out_mtd; 290 goto out_mtd;
291 } 291 }
292 292
293 /* Get pointer to private data */ 293 /* Get pointer to private data */
294 this = (struct nand_chip *) (); 294 this = (struct nand_chip *) ();
295 /* Link the private data with the MTD structure */ 295 /* Link the private data with the MTD structure */
296 board_mtd->priv = this; 296 board_mtd->priv = this;
297 297
298 /* Set address of NAND IO lines */ 298 /* Set address of NAND IO lines */
299 this->IO_ADDR_R = baseaddr; 299 this->IO_ADDR_R = baseaddr;
300 this->IO_ADDR_W = baseaddr; 300 this->IO_ADDR_W = baseaddr;
301 /* Reference hardware control function */ 301 /* Reference hardware control function */
302 this->hwcontrol = board_hwcontrol; 302 this->hwcontrol = board_hwcontrol;
303 /* Set command delay time, see datasheet for correct value */ 303 /* Set command delay time, see datasheet for correct value */
304 this->chip_delay = CHIP_DEPENDEND_COMMAND_DELAY; 304 this->chip_delay = CHIP_DEPENDEND_COMMAND_DELAY;
305 /* Assign the device ready function, if available */ 305 /* Assign the device ready function, if available */
306 this->dev_ready = board_dev_ready; 306 this->dev_ready = board_dev_ready;
307 this->eccmode = NAND_ECC_SOFT; 307 this->eccmode = NAND_ECC_SOFT;
308 308
309 /* Scan to find existence of the device */ 309 /* Scan to find existence of the device */
310 if (nand_scan (board_mtd, 1)) { 310 if (nand_scan (board_mtd, 1)) {
311 err = -ENXIO; 311 err = -ENXIO;
312 goto out_ior; 312 goto out_ior;
313 } 313 }
314 314
315 add_mtd_partitions(board_mtd, partition_info, NUM_PARTITIONS); 315 add_mtd_partitions(board_mtd, partition_info, NUM_PARTITIONS);
316 goto out; 316 goto out;
317 317
318 out_ior: 318 out_ior:
319 iounmap((void *)baseaddr); 319 iounmap((void *)baseaddr);
320 out_mtd: 320 out_mtd:
321 kfree (board_mtd); 321 kfree (board_mtd);
322 out: 322 out:
323 return err; 323 return err;
324 } 324 }
325 module_init(board_init); 325 module_init(board_init);
326 </programlisting> 326 </programlisting>
327 </sect1> 327 </sect1>
328 <sect1 id="Exit_function"> 328 <sect1 id="Exit_function">
329 <title>Exit function</title> 329 <title>Exit function</title>
330 <para> 330 <para>
331 The exit function is only neccecary if the driver is 331 The exit function is only neccecary if the driver is
332 compiled as a module. It releases all resources which 332 compiled as a module. It releases all resources which
333 are held by the chip driver and unregisters the partitions 333 are held by the chip driver and unregisters the partitions
334 in the MTD layer. 334 in the MTD layer.
335 </para> 335 </para>
336 <programlisting> 336 <programlisting>
337 #ifdef MODULE 337 #ifdef MODULE
338 static void __exit board_cleanup (void) 338 static void __exit board_cleanup (void)
339 { 339 {
340 /* Release resources, unregister device */ 340 /* Release resources, unregister device */
341 nand_release (board_mtd); 341 nand_release (board_mtd);
342 342
343 /* unmap physical address */ 343 /* unmap physical address */
344 iounmap((void *)baseaddr); 344 iounmap((void *)baseaddr);
345 345
346 /* Free the MTD device structure */ 346 /* Free the MTD device structure */
347 kfree (board_mtd); 347 kfree (board_mtd);
348 } 348 }
349 module_exit(board_cleanup); 349 module_exit(board_cleanup);
350 #endif 350 #endif
351 </programlisting> 351 </programlisting>
352 </sect1> 352 </sect1>
353 </chapter> 353 </chapter>
354 354
355 <chapter id="boarddriversadvanced"> 355 <chapter id="boarddriversadvanced">
356 <title>Advanced board driver functions</title> 356 <title>Advanced board driver functions</title>
357 <para> 357 <para>
358 This chapter describes the advanced functionality of the NAND 358 This chapter describes the advanced functionality of the NAND
359 driver. For a list of functions which can be overridden by the board 359 driver. For a list of functions which can be overridden by the board
360 driver see the documentation of the nand_chip structure. 360 driver see the documentation of the nand_chip structure.
361 </para> 361 </para>
362 <sect1 id="Multiple_chip_control"> 362 <sect1 id="Multiple_chip_control">
363 <title>Multiple chip control</title> 363 <title>Multiple chip control</title>
364 <para> 364 <para>
365 The nand driver can control chip arrays. Therefor the 365 The nand driver can control chip arrays. Therefor the
366 board driver must provide an own select_chip function. This 366 board driver must provide an own select_chip function. This
367 function must (de)select the requested chip. 367 function must (de)select the requested chip.
368 The function pointer in the nand_chip structure must 368 The function pointer in the nand_chip structure must
369 be set before calling nand_scan(). The maxchip parameter 369 be set before calling nand_scan(). The maxchip parameter
370 of nand_scan() defines the maximum number of chips to 370 of nand_scan() defines the maximum number of chips to
371 scan for. Make sure that the select_chip function can 371 scan for. Make sure that the select_chip function can
372 handle the requested number of chips. 372 handle the requested number of chips.
373 </para> 373 </para>
374 <para> 374 <para>
375 The nand driver concatenates the chips to one virtual 375 The nand driver concatenates the chips to one virtual
376 chip and provides this virtual chip to the MTD layer. 376 chip and provides this virtual chip to the MTD layer.
377 </para> 377 </para>
378 <para> 378 <para>
379 <emphasis>Note: The driver can only handle linear chip arrays 379 <emphasis>Note: The driver can only handle linear chip arrays
380 of equally sized chips. There is no support for 380 of equally sized chips. There is no support for
381 parallel arrays which extend the buswidth.</emphasis> 381 parallel arrays which extend the buswidth.</emphasis>
382 </para> 382 </para>
383 <para> 383 <para>
384 <emphasis>GPIO based example</emphasis> 384 <emphasis>GPIO based example</emphasis>
385 </para> 385 </para>
386 <programlisting> 386 <programlisting>
387 static void board_select_chip (struct mtd_info *mtd, int chip) 387 static void board_select_chip (struct mtd_info *mtd, int chip)
388 { 388 {
389 /* Deselect all chips, set all nCE pins high */ 389 /* Deselect all chips, set all nCE pins high */
390 GPIO(BOARD_NAND_NCE) |= 0xff; 390 GPIO(BOARD_NAND_NCE) |= 0xff;
391 if (chip >= 0) 391 if (chip >= 0)
392 GPIO(BOARD_NAND_NCE) &amp;= ~ (1 &lt;&lt; chip); 392 GPIO(BOARD_NAND_NCE) &amp;= ~ (1 &lt;&lt; chip);
393 } 393 }
394 </programlisting> 394 </programlisting>
395 <para> 395 <para>
396 <emphasis>Address lines based example.</emphasis> 396 <emphasis>Address lines based example.</emphasis>
397 Its assumed that the nCE pins are connected to an 397 Its assumed that the nCE pins are connected to an
398 address decoder. 398 address decoder.
399 </para> 399 </para>
400 <programlisting> 400 <programlisting>
401 static void board_select_chip (struct mtd_info *mtd, int chip) 401 static void board_select_chip (struct mtd_info *mtd, int chip)
402 { 402 {
403 struct nand_chip *this = (struct nand_chip *) mtd->priv; 403 struct nand_chip *this = (struct nand_chip *) mtd->priv;
404 404
405 /* Deselect all chips */ 405 /* Deselect all chips */
406 this->IO_ADDR_R &amp;= ~BOARD_NAND_ADDR_MASK; 406 this->IO_ADDR_R &amp;= ~BOARD_NAND_ADDR_MASK;
407 this->IO_ADDR_W &amp;= ~BOARD_NAND_ADDR_MASK; 407 this->IO_ADDR_W &amp;= ~BOARD_NAND_ADDR_MASK;
408 switch (chip) { 408 switch (chip) {
409 case 0: 409 case 0:
410 this->IO_ADDR_R |= BOARD_NAND_ADDR_CHIP0; 410 this->IO_ADDR_R |= BOARD_NAND_ADDR_CHIP0;
411 this->IO_ADDR_W |= BOARD_NAND_ADDR_CHIP0; 411 this->IO_ADDR_W |= BOARD_NAND_ADDR_CHIP0;
412 break; 412 break;
413 .... 413 ....
414 case n: 414 case n:
415 this->IO_ADDR_R |= BOARD_NAND_ADDR_CHIPn; 415 this->IO_ADDR_R |= BOARD_NAND_ADDR_CHIPn;
416 this->IO_ADDR_W |= BOARD_NAND_ADDR_CHIPn; 416 this->IO_ADDR_W |= BOARD_NAND_ADDR_CHIPn;
417 break; 417 break;
418 } 418 }
419 } 419 }
420 </programlisting> 420 </programlisting>
421 </sect1> 421 </sect1>
422 <sect1 id="Hardware_ECC_support"> 422 <sect1 id="Hardware_ECC_support">
423 <title>Hardware ECC support</title> 423 <title>Hardware ECC support</title>
424 <sect2 id="Functions_and_constants"> 424 <sect2 id="Functions_and_constants">
425 <title>Functions and constants</title> 425 <title>Functions and constants</title>
426 <para> 426 <para>
427 The nand driver supports three different types of 427 The nand driver supports three different types of
428 hardware ECC. 428 hardware ECC.
429 <itemizedlist> 429 <itemizedlist>
430 <listitem><para>NAND_ECC_HW3_256</para><para> 430 <listitem><para>NAND_ECC_HW3_256</para><para>
431 Hardware ECC generator providing 3 bytes ECC per 431 Hardware ECC generator providing 3 bytes ECC per
432 256 byte. 432 256 byte.
433 </para> </listitem> 433 </para> </listitem>
434 <listitem><para>NAND_ECC_HW3_512</para><para> 434 <listitem><para>NAND_ECC_HW3_512</para><para>
435 Hardware ECC generator providing 3 bytes ECC per 435 Hardware ECC generator providing 3 bytes ECC per
436 512 byte. 436 512 byte.
437 </para> </listitem> 437 </para> </listitem>
438 <listitem><para>NAND_ECC_HW6_512</para><para> 438 <listitem><para>NAND_ECC_HW6_512</para><para>
439 Hardware ECC generator providing 6 bytes ECC per 439 Hardware ECC generator providing 6 bytes ECC per
440 512 byte. 440 512 byte.
441 </para> </listitem> 441 </para> </listitem>
442 <listitem><para>NAND_ECC_HW8_512</para><para> 442 <listitem><para>NAND_ECC_HW8_512</para><para>
443 Hardware ECC generator providing 6 bytes ECC per 443 Hardware ECC generator providing 6 bytes ECC per
444 512 byte. 444 512 byte.
445 </para> </listitem> 445 </para> </listitem>
446 </itemizedlist> 446 </itemizedlist>
447 If your hardware generator has a different functionality 447 If your hardware generator has a different functionality
448 add it at the appropriate place in nand_base.c 448 add it at the appropriate place in nand_base.c
449 </para> 449 </para>
450 <para> 450 <para>
451 The board driver must provide following functions: 451 The board driver must provide following functions:
452 <itemizedlist> 452 <itemizedlist>
453 <listitem><para>enable_hwecc</para><para> 453 <listitem><para>enable_hwecc</para><para>
454 This function is called before reading / writing to 454 This function is called before reading / writing to
455 the chip. Reset or initialize the hardware generator 455 the chip. Reset or initialize the hardware generator
456 in this function. The function is called with an 456 in this function. The function is called with an
457 argument which let you distinguish between read 457 argument which let you distinguish between read
458 and write operations. 458 and write operations.
459 </para> </listitem> 459 </para> </listitem>
460 <listitem><para>calculate_ecc</para><para> 460 <listitem><para>calculate_ecc</para><para>
461 This function is called after read / write from / to 461 This function is called after read / write from / to
462 the chip. Transfer the ECC from the hardware to 462 the chip. Transfer the ECC from the hardware to
463 the buffer. If the option NAND_HWECC_SYNDROME is set 463 the buffer. If the option NAND_HWECC_SYNDROME is set
464 then the function is only called on write. See below. 464 then the function is only called on write. See below.
465 </para> </listitem> 465 </para> </listitem>
466 <listitem><para>correct_data</para><para> 466 <listitem><para>correct_data</para><para>
467 In case of an ECC error this function is called for 467 In case of an ECC error this function is called for
468 error detection and correction. Return 1 respectively 2 468 error detection and correction. Return 1 respectively 2
469 in case the error can be corrected. If the error is 469 in case the error can be corrected. If the error is
470 not correctable return -1. If your hardware generator 470 not correctable return -1. If your hardware generator
471 matches the default algorithm of the nand_ecc software 471 matches the default algorithm of the nand_ecc software
472 generator then use the correction function provided 472 generator then use the correction function provided
473 by nand_ecc instead of implementing duplicated code. 473 by nand_ecc instead of implementing duplicated code.
474 </para> </listitem> 474 </para> </listitem>
475 </itemizedlist> 475 </itemizedlist>
476 </para> 476 </para>
477 </sect2> 477 </sect2>
478 <sect2 id="Hardware_ECC_with_syndrome_calculation"> 478 <sect2 id="Hardware_ECC_with_syndrome_calculation">
479 <title>Hardware ECC with syndrome calculation</title> 479 <title>Hardware ECC with syndrome calculation</title>
480 <para> 480 <para>
481 Many hardware ECC implementations provide Reed-Solomon 481 Many hardware ECC implementations provide Reed-Solomon
482 codes and calculate an error syndrome on read. The syndrome 482 codes and calculate an error syndrome on read. The syndrome
483 must be converted to a standard Reed-Solomon syndrome 483 must be converted to a standard Reed-Solomon syndrome
484 before calling the error correction code in the generic 484 before calling the error correction code in the generic
485 Reed-Solomon library. 485 Reed-Solomon library.
486 </para> 486 </para>
487 <para> 487 <para>
488 The ECC bytes must be placed immidiately after the data 488 The ECC bytes must be placed immidiately after the data
489 bytes in order to make the syndrome generator work. This 489 bytes in order to make the syndrome generator work. This
490 is contrary to the usual layout used by software ECC. The 490 is contrary to the usual layout used by software ECC. The
491 seperation of data and out of band area is not longer 491 seperation of data and out of band area is not longer
492 possible. The nand driver code handles this layout and 492 possible. The nand driver code handles this layout and
493 the remaining free bytes in the oob area are managed by 493 the remaining free bytes in the oob area are managed by
494 the autoplacement code. Provide a matching oob-layout 494 the autoplacement code. Provide a matching oob-layout
495 in this case. See rts_from4.c and diskonchip.c for 495 in this case. See rts_from4.c and diskonchip.c for
496 implementation reference. In those cases we must also 496 implementation reference. In those cases we must also
497 use bad block tables on FLASH, because the ECC layout is 497 use bad block tables on FLASH, because the ECC layout is
498 interferring with the bad block marker positions. 498 interferring with the bad block marker positions.
499 See bad block table support for details. 499 See bad block table support for details.
500 </para> 500 </para>
501 </sect2> 501 </sect2>
502 </sect1> 502 </sect1>
503 <sect1 id="Bad_Block_table_support"> 503 <sect1 id="Bad_Block_table_support">
504 <title>Bad block table support</title> 504 <title>Bad block table support</title>
505 <para> 505 <para>
506 Most NAND chips mark the bad blocks at a defined 506 Most NAND chips mark the bad blocks at a defined
507 position in the spare area. Those blocks must 507 position in the spare area. Those blocks must
508 not be erased under any circumstances as the bad 508 not be erased under any circumstances as the bad
509 block information would be lost. 509 block information would be lost.
510 It is possible to check the bad block mark each 510 It is possible to check the bad block mark each
511 time when the blocks are accessed by reading the 511 time when the blocks are accessed by reading the
512 spare area of the first page in the block. This 512 spare area of the first page in the block. This
513 is time consuming so a bad block table is used. 513 is time consuming so a bad block table is used.
514 </para> 514 </para>
515 <para> 515 <para>
516 The nand driver supports various types of bad block 516 The nand driver supports various types of bad block
517 tables. 517 tables.
518 <itemizedlist> 518 <itemizedlist>
519 <listitem><para>Per device</para><para> 519 <listitem><para>Per device</para><para>
520 The bad block table contains all bad block information 520 The bad block table contains all bad block information
521 of the device which can consist of multiple chips. 521 of the device which can consist of multiple chips.
522 </para> </listitem> 522 </para> </listitem>
523 <listitem><para>Per chip</para><para> 523 <listitem><para>Per chip</para><para>
524 A bad block table is used per chip and contains the 524 A bad block table is used per chip and contains the
525 bad block information for this particular chip. 525 bad block information for this particular chip.
526 </para> </listitem> 526 </para> </listitem>
527 <listitem><para>Fixed offset</para><para> 527 <listitem><para>Fixed offset</para><para>
528 The bad block table is located at a fixed offset 528 The bad block table is located at a fixed offset
529 in the chip (device). This applies to various 529 in the chip (device). This applies to various
530 DiskOnChip devices. 530 DiskOnChip devices.
531 </para> </listitem> 531 </para> </listitem>
532 <listitem><para>Automatic placed</para><para> 532 <listitem><para>Automatic placed</para><para>
533 The bad block table is automatically placed and 533 The bad block table is automatically placed and
534 detected either at the end or at the beginning 534 detected either at the end or at the beginning
535 of a chip (device) 535 of a chip (device)
536 </para> </listitem> 536 </para> </listitem>
537 <listitem><para>Mirrored tables</para><para> 537 <listitem><para>Mirrored tables</para><para>
538 The bad block table is mirrored on the chip (device) to 538 The bad block table is mirrored on the chip (device) to
539 allow updates of the bad block table without data loss. 539 allow updates of the bad block table without data loss.
540 </para> </listitem> 540 </para> </listitem>
541 </itemizedlist> 541 </itemizedlist>
542 </para> 542 </para>
543 <para> 543 <para>
544 nand_scan() calls the function nand_default_bbt(). 544 nand_scan() calls the function nand_default_bbt().
545 nand_default_bbt() selects appropriate default 545 nand_default_bbt() selects appropriate default
546 bad block table desriptors depending on the chip information 546 bad block table desriptors depending on the chip information
547 which was retrieved by nand_scan(). 547 which was retrieved by nand_scan().
548 </para> 548 </para>
549 <para> 549 <para>
550 The standard policy is scanning the device for bad 550 The standard policy is scanning the device for bad
551 blocks and build a ram based bad block table which 551 blocks and build a ram based bad block table which
552 allows faster access than always checking the 552 allows faster access than always checking the
553 bad block information on the flash chip itself. 553 bad block information on the flash chip itself.
554 </para> 554 </para>
555 <sect2 id="Flash_based_tables"> 555 <sect2 id="Flash_based_tables">
556 <title>Flash based tables</title> 556 <title>Flash based tables</title>
557 <para> 557 <para>
558 It may be desired or neccecary to keep a bad block table in FLASH. 558 It may be desired or neccecary to keep a bad block table in FLASH.
559 For AG-AND chips this is mandatory, as they have no factory marked 559 For AG-AND chips this is mandatory, as they have no factory marked
560 bad blocks. They have factory marked good blocks. The marker pattern 560 bad blocks. They have factory marked good blocks. The marker pattern
561 is erased when the block is erased to be reused. So in case of 561 is erased when the block is erased to be reused. So in case of
562 powerloss before writing the pattern back to the chip this block 562 powerloss before writing the pattern back to the chip this block
563 would be lost and added to the bad blocks. Therefor we scan the 563 would be lost and added to the bad blocks. Therefor we scan the
564 chip(s) when we detect them the first time for good blocks and 564 chip(s) when we detect them the first time for good blocks and
565 store this information in a bad block table before erasing any 565 store this information in a bad block table before erasing any
566 of the blocks. 566 of the blocks.
567 </para> 567 </para>
568 <para> 568 <para>
569 The blocks in which the tables are stored are procteted against 569 The blocks in which the tables are stored are procteted against
570 accidental access by marking them bad in the memory bad block 570 accidental access by marking them bad in the memory bad block
571 table. The bad block table managment functions are allowed 571 table. The bad block table management functions are allowed
572 to circumvernt this protection. 572 to circumvernt this protection.
573 </para> 573 </para>
574 <para> 574 <para>
575 The simplest way to activate the FLASH based bad block table support 575 The simplest way to activate the FLASH based bad block table support
576 is to set the option NAND_USE_FLASH_BBT in the option field of 576 is to set the option NAND_USE_FLASH_BBT in the option field of
577 the nand chip structure before calling nand_scan(). For AG-AND 577 the nand chip structure before calling nand_scan(). For AG-AND
578 chips is this done by default. 578 chips is this done by default.
579 This activates the default FLASH based bad block table functionality 579 This activates the default FLASH based bad block table functionality
580 of the NAND driver. The default bad block table options are 580 of the NAND driver. The default bad block table options are
581 <itemizedlist> 581 <itemizedlist>
582 <listitem><para>Store bad block table per chip</para></listitem> 582 <listitem><para>Store bad block table per chip</para></listitem>
583 <listitem><para>Use 2 bits per block</para></listitem> 583 <listitem><para>Use 2 bits per block</para></listitem>
584 <listitem><para>Automatic placement at the end of the chip</para></listitem> 584 <listitem><para>Automatic placement at the end of the chip</para></listitem>
585 <listitem><para>Use mirrored tables with version numbers</para></listitem> 585 <listitem><para>Use mirrored tables with version numbers</para></listitem>
586 <listitem><para>Reserve 4 blocks at the end of the chip</para></listitem> 586 <listitem><para>Reserve 4 blocks at the end of the chip</para></listitem>
587 </itemizedlist> 587 </itemizedlist>
588 </para> 588 </para>
589 </sect2> 589 </sect2>
590 <sect2 id="User_defined_tables"> 590 <sect2 id="User_defined_tables">
591 <title>User defined tables</title> 591 <title>User defined tables</title>
592 <para> 592 <para>
593 User defined tables are created by filling out a 593 User defined tables are created by filling out a
594 nand_bbt_descr structure and storing the pointer in the 594 nand_bbt_descr structure and storing the pointer in the
595 nand_chip structure member bbt_td before calling nand_scan(). 595 nand_chip structure member bbt_td before calling nand_scan().
596 If a mirror table is neccecary a second structure must be 596 If a mirror table is neccecary a second structure must be
597 created and a pointer to this structure must be stored 597 created and a pointer to this structure must be stored
598 in bbt_md inside the nand_chip structure. If the bbt_md 598 in bbt_md inside the nand_chip structure. If the bbt_md
599 member is set to NULL then only the main table is used 599 member is set to NULL then only the main table is used
600 and no scan for the mirrored table is performed. 600 and no scan for the mirrored table is performed.
601 </para> 601 </para>
602 <para> 602 <para>
603 The most important field in the nand_bbt_descr structure 603 The most important field in the nand_bbt_descr structure
604 is the options field. The options define most of the 604 is the options field. The options define most of the
605 table properties. Use the predefined constants from 605 table properties. Use the predefined constants from
606 nand.h to define the options. 606 nand.h to define the options.
607 <itemizedlist> 607 <itemizedlist>
608 <listitem><para>Number of bits per block</para> 608 <listitem><para>Number of bits per block</para>
609 <para>The supported number of bits is 1, 2, 4, 8.</para></listitem> 609 <para>The supported number of bits is 1, 2, 4, 8.</para></listitem>
610 <listitem><para>Table per chip</para> 610 <listitem><para>Table per chip</para>
611 <para>Setting the constant NAND_BBT_PERCHIP selects that 611 <para>Setting the constant NAND_BBT_PERCHIP selects that
612 a bad block table is managed for each chip in a chip array. 612 a bad block table is managed for each chip in a chip array.
613 If this option is not set then a per device bad block table 613 If this option is not set then a per device bad block table
614 is used.</para></listitem> 614 is used.</para></listitem>
615 <listitem><para>Table location is absolute</para> 615 <listitem><para>Table location is absolute</para>
616 <para>Use the option constant NAND_BBT_ABSPAGE and 616 <para>Use the option constant NAND_BBT_ABSPAGE and
617 define the absolute page number where the bad block 617 define the absolute page number where the bad block
618 table starts in the field pages. If you have selected bad block 618 table starts in the field pages. If you have selected bad block
619 tables per chip and you have a multi chip array then the start page 619 tables per chip and you have a multi chip array then the start page
620 must be given for each chip in the chip array. Note: there is no scan 620 must be given for each chip in the chip array. Note: there is no scan
621 for a table ident pattern performed, so the fields 621 for a table ident pattern performed, so the fields
622 pattern, veroffs, offs, len can be left uninitialized</para></listitem> 622 pattern, veroffs, offs, len can be left uninitialized</para></listitem>
623 <listitem><para>Table location is automatically detected</para> 623 <listitem><para>Table location is automatically detected</para>
624 <para>The table can either be located in the first or the last good 624 <para>The table can either be located in the first or the last good
625 blocks of the chip (device). Set NAND_BBT_LASTBLOCK to place 625 blocks of the chip (device). Set NAND_BBT_LASTBLOCK to place
626 the bad block table at the end of the chip (device). The 626 the bad block table at the end of the chip (device). The
627 bad block tables are marked and identified by a pattern which 627 bad block tables are marked and identified by a pattern which
628 is stored in the spare area of the first page in the block which 628 is stored in the spare area of the first page in the block which
629 holds the bad block table. Store a pointer to the pattern 629 holds the bad block table. Store a pointer to the pattern
630 in the pattern field. Further the length of the pattern has to be 630 in the pattern field. Further the length of the pattern has to be
631 stored in len and the offset in the spare area must be given 631 stored in len and the offset in the spare area must be given
632 in the offs member of the nand_bbt_descr stucture. For mirrored 632 in the offs member of the nand_bbt_descr stucture. For mirrored
633 bad block tables different patterns are mandatory.</para></listitem> 633 bad block tables different patterns are mandatory.</para></listitem>
634 <listitem><para>Table creation</para> 634 <listitem><para>Table creation</para>
635 <para>Set the option NAND_BBT_CREATE to enable the table creation 635 <para>Set the option NAND_BBT_CREATE to enable the table creation
636 if no table can be found during the scan. Usually this is done only 636 if no table can be found during the scan. Usually this is done only
637 once if a new chip is found. </para></listitem> 637 once if a new chip is found. </para></listitem>
638 <listitem><para>Table write support</para> 638 <listitem><para>Table write support</para>
639 <para>Set the option NAND_BBT_WRITE to enable the table write support. 639 <para>Set the option NAND_BBT_WRITE to enable the table write support.
640 This allows the update of the bad block table(s) in case a block has 640 This allows the update of the bad block table(s) in case a block has
641 to be marked bad due to wear. The MTD interface function block_markbad 641 to be marked bad due to wear. The MTD interface function block_markbad
642 is calling the update function of the bad block table. If the write 642 is calling the update function of the bad block table. If the write
643 support is enabled then the table is updated on FLASH.</para> 643 support is enabled then the table is updated on FLASH.</para>
644 <para> 644 <para>
645 Note: Write support should only be enabled for mirrored tables with 645 Note: Write support should only be enabled for mirrored tables with
646 version control. 646 version control.
647 </para></listitem> 647 </para></listitem>
648 <listitem><para>Table version control</para> 648 <listitem><para>Table version control</para>
649 <para>Set the option NAND_BBT_VERSION to enable the table version control. 649 <para>Set the option NAND_BBT_VERSION to enable the table version control.
650 It's highly recommended to enable this for mirrored tables with write 650 It's highly recommended to enable this for mirrored tables with write
651 support. It makes sure that the risk of loosing the bad block 651 support. It makes sure that the risk of loosing the bad block
652 table information is reduced to the loss of the information about the 652 table information is reduced to the loss of the information about the
653 one worn out block which should be marked bad. The version is stored in 653 one worn out block which should be marked bad. The version is stored in
654 4 consecutive bytes in the spare area of the device. The position of 654 4 consecutive bytes in the spare area of the device. The position of
655 the version number is defined by the member veroffs in the bad block table 655 the version number is defined by the member veroffs in the bad block table
656 descriptor.</para></listitem> 656 descriptor.</para></listitem>
657 <listitem><para>Save block contents on write</para> 657 <listitem><para>Save block contents on write</para>
658 <para> 658 <para>
659 In case that the block which holds the bad block table does contain 659 In case that the block which holds the bad block table does contain
660 other useful information, set the option NAND_BBT_SAVECONTENT. When 660 other useful information, set the option NAND_BBT_SAVECONTENT. When
661 the bad block table is written then the whole block is read the bad 661 the bad block table is written then the whole block is read the bad
662 block table is updated and the block is erased and everything is 662 block table is updated and the block is erased and everything is
663 written back. If this option is not set only the bad block table 663 written back. If this option is not set only the bad block table
664 is written and everything else in the block is ignored and erased. 664 is written and everything else in the block is ignored and erased.
665 </para></listitem> 665 </para></listitem>
666 <listitem><para>Number of reserved blocks</para> 666 <listitem><para>Number of reserved blocks</para>
667 <para> 667 <para>
668 For automatic placement some blocks must be reserved for 668 For automatic placement some blocks must be reserved for
669 bad block table storage. The number of reserved blocks is defined 669 bad block table storage. The number of reserved blocks is defined
670 in the maxblocks member of the babd block table description structure. 670 in the maxblocks member of the babd block table description structure.
671 Reserving 4 blocks for mirrored tables should be a reasonable number. 671 Reserving 4 blocks for mirrored tables should be a reasonable number.
672 This also limits the number of blocks which are scanned for the bad 672 This also limits the number of blocks which are scanned for the bad
673 block table ident pattern. 673 block table ident pattern.
674 </para></listitem> 674 </para></listitem>
675 </itemizedlist> 675 </itemizedlist>
676 </para> 676 </para>
677 </sect2> 677 </sect2>
678 </sect1> 678 </sect1>
679 <sect1 id="Spare_area_placement"> 679 <sect1 id="Spare_area_placement">
680 <title>Spare area (auto)placement</title> 680 <title>Spare area (auto)placement</title>
681 <para> 681 <para>
682 The nand driver implements different possibilities for 682 The nand driver implements different possibilities for
683 placement of filesystem data in the spare area, 683 placement of filesystem data in the spare area,
684 <itemizedlist> 684 <itemizedlist>
685 <listitem><para>Placement defined by fs driver</para></listitem> 685 <listitem><para>Placement defined by fs driver</para></listitem>
686 <listitem><para>Automatic placement</para></listitem> 686 <listitem><para>Automatic placement</para></listitem>
687 </itemizedlist> 687 </itemizedlist>
688 The default placement function is automatic placement. The 688 The default placement function is automatic placement. The
689 nand driver has built in default placement schemes for the 689 nand driver has built in default placement schemes for the
690 various chiptypes. If due to hardware ECC functionality the 690 various chiptypes. If due to hardware ECC functionality the
691 default placement does not fit then the board driver can 691 default placement does not fit then the board driver can
692 provide a own placement scheme. 692 provide a own placement scheme.
693 </para> 693 </para>
694 <para> 694 <para>
695 File system drivers can provide a own placement scheme which 695 File system drivers can provide a own placement scheme which
696 is used instead of the default placement scheme. 696 is used instead of the default placement scheme.
697 </para> 697 </para>
698 <para> 698 <para>
699 Placement schemes are defined by a nand_oobinfo structure 699 Placement schemes are defined by a nand_oobinfo structure
700 <programlisting> 700 <programlisting>
701 struct nand_oobinfo { 701 struct nand_oobinfo {
702 int useecc; 702 int useecc;
703 int eccbytes; 703 int eccbytes;
704 int eccpos[24]; 704 int eccpos[24];
705 int oobfree[8][2]; 705 int oobfree[8][2];
706 }; 706 };
707 </programlisting> 707 </programlisting>
708 <itemizedlist> 708 <itemizedlist>
709 <listitem><para>useecc</para><para> 709 <listitem><para>useecc</para><para>
710 The useecc member controls the ecc and placement function. The header 710 The useecc member controls the ecc and placement function. The header
711 file include/mtd/mtd-abi.h contains constants to select ecc and 711 file include/mtd/mtd-abi.h contains constants to select ecc and
712 placement. MTD_NANDECC_OFF switches off the ecc complete. This is 712 placement. MTD_NANDECC_OFF switches off the ecc complete. This is
713 not recommended and available for testing and diagnosis only. 713 not recommended and available for testing and diagnosis only.
714 MTD_NANDECC_PLACE selects caller defined placement, MTD_NANDECC_AUTOPLACE 714 MTD_NANDECC_PLACE selects caller defined placement, MTD_NANDECC_AUTOPLACE
715 selects automatic placement. 715 selects automatic placement.
716 </para></listitem> 716 </para></listitem>
717 <listitem><para>eccbytes</para><para> 717 <listitem><para>eccbytes</para><para>
718 The eccbytes member defines the number of ecc bytes per page. 718 The eccbytes member defines the number of ecc bytes per page.
719 </para></listitem> 719 </para></listitem>
720 <listitem><para>eccpos</para><para> 720 <listitem><para>eccpos</para><para>
721 The eccpos array holds the byte offsets in the spare area where 721 The eccpos array holds the byte offsets in the spare area where
722 the ecc codes are placed. 722 the ecc codes are placed.
723 </para></listitem> 723 </para></listitem>
724 <listitem><para>oobfree</para><para> 724 <listitem><para>oobfree</para><para>
725 The oobfree array defines the areas in the spare area which can be 725 The oobfree array defines the areas in the spare area which can be
726 used for automatic placement. The information is given in the format 726 used for automatic placement. The information is given in the format
727 {offset, size}. offset defines the start of the usable area, size the 727 {offset, size}. offset defines the start of the usable area, size the
728 length in bytes. More than one area can be defined. The list is terminated 728 length in bytes. More than one area can be defined. The list is terminated
729 by an {0, 0} entry. 729 by an {0, 0} entry.
730 </para></listitem> 730 </para></listitem>
731 </itemizedlist> 731 </itemizedlist>
732 </para> 732 </para>
733 <sect2 id="Placement_defined_by_fs_driver"> 733 <sect2 id="Placement_defined_by_fs_driver">
734 <title>Placement defined by fs driver</title> 734 <title>Placement defined by fs driver</title>
735 <para> 735 <para>
736 The calling function provides a pointer to a nand_oobinfo 736 The calling function provides a pointer to a nand_oobinfo
737 structure which defines the ecc placement. For writes the 737 structure which defines the ecc placement. For writes the
738 caller must provide a spare area buffer along with the 738 caller must provide a spare area buffer along with the
739 data buffer. The spare area buffer size is (number of pages) * 739 data buffer. The spare area buffer size is (number of pages) *
740 (size of spare area). For reads the buffer size is 740 (size of spare area). For reads the buffer size is
741 (number of pages) * ((size of spare area) + (number of ecc 741 (number of pages) * ((size of spare area) + (number of ecc
742 steps per page) * sizeof (int)). The driver stores the 742 steps per page) * sizeof (int)). The driver stores the
743 result of the ecc check for each tuple in the spare buffer. 743 result of the ecc check for each tuple in the spare buffer.
744 The storage sequence is 744 The storage sequence is
745 </para> 745 </para>
746 <para> 746 <para>
747 &lt;spare data page 0&gt;&lt;ecc result 0&gt;...&lt;ecc result n&gt; 747 &lt;spare data page 0&gt;&lt;ecc result 0&gt;...&lt;ecc result n&gt;
748 </para> 748 </para>
749 <para> 749 <para>
750 ... 750 ...
751 </para> 751 </para>
752 <para> 752 <para>
753 &lt;spare data page n&gt;&lt;ecc result 0&gt;...&lt;ecc result n&gt; 753 &lt;spare data page n&gt;&lt;ecc result 0&gt;...&lt;ecc result n&gt;
754 </para> 754 </para>
755 <para> 755 <para>
756 This is a legacy mode used by YAFFS1. 756 This is a legacy mode used by YAFFS1.
757 </para> 757 </para>
758 <para> 758 <para>
759 If the spare area buffer is NULL then only the ECC placement is 759 If the spare area buffer is NULL then only the ECC placement is
760 done according to the given scheme in the nand_oobinfo structure. 760 done according to the given scheme in the nand_oobinfo structure.
761 </para> 761 </para>
762 </sect2> 762 </sect2>
763 <sect2 id="Automatic_placement"> 763 <sect2 id="Automatic_placement">
764 <title>Automatic placement</title> 764 <title>Automatic placement</title>
765 <para> 765 <para>
766 Automatic placement uses the built in defaults to place the 766 Automatic placement uses the built in defaults to place the
767 ecc bytes in the spare area. If filesystem data have to be stored / 767 ecc bytes in the spare area. If filesystem data have to be stored /
768 read into the spare area then the calling function must provide a 768 read into the spare area then the calling function must provide a
769 buffer. The buffer size per page is determined by the oobfree array in 769 buffer. The buffer size per page is determined by the oobfree array in
770 the nand_oobinfo structure. 770 the nand_oobinfo structure.
771 </para> 771 </para>
772 <para> 772 <para>
773 If the spare area buffer is NULL then only the ECC placement is 773 If the spare area buffer is NULL then only the ECC placement is
774 done according to the default builtin scheme. 774 done according to the default builtin scheme.
775 </para> 775 </para>
776 </sect2> 776 </sect2>
777 <sect2 id="User_space_placement_selection"> 777 <sect2 id="User_space_placement_selection">
778 <title>User space placement selection</title> 778 <title>User space placement selection</title>
779 <para> 779 <para>
780 All non ecc functions like mtd->read and mtd->write use an internal 780 All non ecc functions like mtd->read and mtd->write use an internal
781 structure, which can be set by an ioctl. This structure is preset 781 structure, which can be set by an ioctl. This structure is preset
782 to the autoplacement default. 782 to the autoplacement default.
783 <programlisting> 783 <programlisting>
784 ioctl (fd, MEMSETOOBSEL, oobsel); 784 ioctl (fd, MEMSETOOBSEL, oobsel);
785 </programlisting> 785 </programlisting>
786 oobsel is a pointer to a user supplied structure of type 786 oobsel is a pointer to a user supplied structure of type
787 nand_oobconfig. The contents of this structure must match the 787 nand_oobconfig. The contents of this structure must match the
788 criteria of the filesystem, which will be used. See an example in utils/nandwrite.c. 788 criteria of the filesystem, which will be used. See an example in utils/nandwrite.c.
789 </para> 789 </para>
790 </sect2> 790 </sect2>
791 </sect1> 791 </sect1>
792 <sect1 id="Spare_area_autoplacement_default"> 792 <sect1 id="Spare_area_autoplacement_default">
793 <title>Spare area autoplacement default schemes</title> 793 <title>Spare area autoplacement default schemes</title>
794 <sect2 id="pagesize_256"> 794 <sect2 id="pagesize_256">
795 <title>256 byte pagesize</title> 795 <title>256 byte pagesize</title>
796 <informaltable><tgroup cols="3"><tbody> 796 <informaltable><tgroup cols="3"><tbody>
797 <row> 797 <row>
798 <entry>Offset</entry> 798 <entry>Offset</entry>
799 <entry>Content</entry> 799 <entry>Content</entry>
800 <entry>Comment</entry> 800 <entry>Comment</entry>
801 </row> 801 </row>
802 <row> 802 <row>
803 <entry>0x00</entry> 803 <entry>0x00</entry>
804 <entry>ECC byte 0</entry> 804 <entry>ECC byte 0</entry>
805 <entry>Error correction code byte 0</entry> 805 <entry>Error correction code byte 0</entry>
806 </row> 806 </row>
807 <row> 807 <row>
808 <entry>0x01</entry> 808 <entry>0x01</entry>
809 <entry>ECC byte 1</entry> 809 <entry>ECC byte 1</entry>
810 <entry>Error correction code byte 1</entry> 810 <entry>Error correction code byte 1</entry>
811 </row> 811 </row>
812 <row> 812 <row>
813 <entry>0x02</entry> 813 <entry>0x02</entry>
814 <entry>ECC byte 2</entry> 814 <entry>ECC byte 2</entry>
815 <entry>Error correction code byte 2</entry> 815 <entry>Error correction code byte 2</entry>
816 </row> 816 </row>
817 <row> 817 <row>
818 <entry>0x03</entry> 818 <entry>0x03</entry>
819 <entry>Autoplace 0</entry> 819 <entry>Autoplace 0</entry>
820 <entry></entry> 820 <entry></entry>
821 </row> 821 </row>
822 <row> 822 <row>
823 <entry>0x04</entry> 823 <entry>0x04</entry>
824 <entry>Autoplace 1</entry> 824 <entry>Autoplace 1</entry>
825 <entry></entry> 825 <entry></entry>
826 </row> 826 </row>
827 <row> 827 <row>
828 <entry>0x05</entry> 828 <entry>0x05</entry>
829 <entry>Bad block marker</entry> 829 <entry>Bad block marker</entry>
830 <entry>If any bit in this byte is zero, then this block is bad. 830 <entry>If any bit in this byte is zero, then this block is bad.
831 This applies only to the first page in a block. In the remaining 831 This applies only to the first page in a block. In the remaining
832 pages this byte is reserved</entry> 832 pages this byte is reserved</entry>
833 </row> 833 </row>
834 <row> 834 <row>
835 <entry>0x06</entry> 835 <entry>0x06</entry>
836 <entry>Autoplace 2</entry> 836 <entry>Autoplace 2</entry>
837 <entry></entry> 837 <entry></entry>
838 </row> 838 </row>
839 <row> 839 <row>
840 <entry>0x07</entry> 840 <entry>0x07</entry>
841 <entry>Autoplace 3</entry> 841 <entry>Autoplace 3</entry>
842 <entry></entry> 842 <entry></entry>
843 </row> 843 </row>
844 </tbody></tgroup></informaltable> 844 </tbody></tgroup></informaltable>
845 </sect2> 845 </sect2>
846 <sect2 id="pagesize_512"> 846 <sect2 id="pagesize_512">
847 <title>512 byte pagesize</title> 847 <title>512 byte pagesize</title>
848 <informaltable><tgroup cols="3"><tbody> 848 <informaltable><tgroup cols="3"><tbody>
849 <row> 849 <row>
850 <entry>Offset</entry> 850 <entry>Offset</entry>
851 <entry>Content</entry> 851 <entry>Content</entry>
852 <entry>Comment</entry> 852 <entry>Comment</entry>
853 </row> 853 </row>
854 <row> 854 <row>
855 <entry>0x00</entry> 855 <entry>0x00</entry>
856 <entry>ECC byte 0</entry> 856 <entry>ECC byte 0</entry>
857 <entry>Error correction code byte 0 of the lower 256 Byte data in 857 <entry>Error correction code byte 0 of the lower 256 Byte data in
858 this page</entry> 858 this page</entry>
859 </row> 859 </row>
860 <row> 860 <row>
861 <entry>0x01</entry> 861 <entry>0x01</entry>
862 <entry>ECC byte 1</entry> 862 <entry>ECC byte 1</entry>
863 <entry>Error correction code byte 1 of the lower 256 Bytes of data 863 <entry>Error correction code byte 1 of the lower 256 Bytes of data
864 in this page</entry> 864 in this page</entry>
865 </row> 865 </row>
866 <row> 866 <row>
867 <entry>0x02</entry> 867 <entry>0x02</entry>
868 <entry>ECC byte 2</entry> 868 <entry>ECC byte 2</entry>
869 <entry>Error correction code byte 2 of the lower 256 Bytes of data 869 <entry>Error correction code byte 2 of the lower 256 Bytes of data
870 in this page</entry> 870 in this page</entry>
871 </row> 871 </row>
872 <row> 872 <row>
873 <entry>0x03</entry> 873 <entry>0x03</entry>
874 <entry>ECC byte 3</entry> 874 <entry>ECC byte 3</entry>
875 <entry>Error correction code byte 0 of the upper 256 Bytes of data 875 <entry>Error correction code byte 0 of the upper 256 Bytes of data
876 in this page</entry> 876 in this page</entry>
877 </row> 877 </row>
878 <row> 878 <row>
879 <entry>0x04</entry> 879 <entry>0x04</entry>
880 <entry>reserved</entry> 880 <entry>reserved</entry>
881 <entry>reserved</entry> 881 <entry>reserved</entry>
882 </row> 882 </row>
883 <row> 883 <row>
884 <entry>0x05</entry> 884 <entry>0x05</entry>
885 <entry>Bad block marker</entry> 885 <entry>Bad block marker</entry>
886 <entry>If any bit in this byte is zero, then this block is bad. 886 <entry>If any bit in this byte is zero, then this block is bad.
887 This applies only to the first page in a block. In the remaining 887 This applies only to the first page in a block. In the remaining
888 pages this byte is reserved</entry> 888 pages this byte is reserved</entry>
889 </row> 889 </row>
890 <row> 890 <row>
891 <entry>0x06</entry> 891 <entry>0x06</entry>
892 <entry>ECC byte 4</entry> 892 <entry>ECC byte 4</entry>
893 <entry>Error correction code byte 1 of the upper 256 Bytes of data 893 <entry>Error correction code byte 1 of the upper 256 Bytes of data
894 in this page</entry> 894 in this page</entry>
895 </row> 895 </row>
896 <row> 896 <row>
897 <entry>0x07</entry> 897 <entry>0x07</entry>
898 <entry>ECC byte 5</entry> 898 <entry>ECC byte 5</entry>
899 <entry>Error correction code byte 2 of the upper 256 Bytes of data 899 <entry>Error correction code byte 2 of the upper 256 Bytes of data
900 in this page</entry> 900 in this page</entry>
901 </row> 901 </row>
902 <row> 902 <row>
903 <entry>0x08 - 0x0F</entry> 903 <entry>0x08 - 0x0F</entry>
904 <entry>Autoplace 0 - 7</entry> 904 <entry>Autoplace 0 - 7</entry>
905 <entry></entry> 905 <entry></entry>
906 </row> 906 </row>
907 </tbody></tgroup></informaltable> 907 </tbody></tgroup></informaltable>
908 </sect2> 908 </sect2>
909 <sect2 id="pagesize_2048"> 909 <sect2 id="pagesize_2048">
910 <title>2048 byte pagesize</title> 910 <title>2048 byte pagesize</title>
911 <informaltable><tgroup cols="3"><tbody> 911 <informaltable><tgroup cols="3"><tbody>
912 <row> 912 <row>
913 <entry>Offset</entry> 913 <entry>Offset</entry>
914 <entry>Content</entry> 914 <entry>Content</entry>
915 <entry>Comment</entry> 915 <entry>Comment</entry>
916 </row> 916 </row>
917 <row> 917 <row>
918 <entry>0x00</entry> 918 <entry>0x00</entry>
919 <entry>Bad block marker</entry> 919 <entry>Bad block marker</entry>
920 <entry>If any bit in this byte is zero, then this block is bad. 920 <entry>If any bit in this byte is zero, then this block is bad.
921 This applies only to the first page in a block. In the remaining 921 This applies only to the first page in a block. In the remaining
922 pages this byte is reserved</entry> 922 pages this byte is reserved</entry>
923 </row> 923 </row>
924 <row> 924 <row>
925 <entry>0x01</entry> 925 <entry>0x01</entry>
926 <entry>Reserved</entry> 926 <entry>Reserved</entry>
927 <entry>Reserved</entry> 927 <entry>Reserved</entry>
928 </row> 928 </row>
929 <row> 929 <row>
930 <entry>0x02-0x27</entry> 930 <entry>0x02-0x27</entry>
931 <entry>Autoplace 0 - 37</entry> 931 <entry>Autoplace 0 - 37</entry>
932 <entry></entry> 932 <entry></entry>
933 </row> 933 </row>
934 <row> 934 <row>
935 <entry>0x28</entry> 935 <entry>0x28</entry>
936 <entry>ECC byte 0</entry> 936 <entry>ECC byte 0</entry>
937 <entry>Error correction code byte 0 of the first 256 Byte data in 937 <entry>Error correction code byte 0 of the first 256 Byte data in
938 this page</entry> 938 this page</entry>
939 </row> 939 </row>
940 <row> 940 <row>
941 <entry>0x29</entry> 941 <entry>0x29</entry>
942 <entry>ECC byte 1</entry> 942 <entry>ECC byte 1</entry>
943 <entry>Error correction code byte 1 of the first 256 Bytes of data 943 <entry>Error correction code byte 1 of the first 256 Bytes of data
944 in this page</entry> 944 in this page</entry>
945 </row> 945 </row>
946 <row> 946 <row>
947 <entry>0x2A</entry> 947 <entry>0x2A</entry>
948 <entry>ECC byte 2</entry> 948 <entry>ECC byte 2</entry>
949 <entry>Error correction code byte 2 of the first 256 Bytes data in 949 <entry>Error correction code byte 2 of the first 256 Bytes data in
950 this page</entry> 950 this page</entry>
951 </row> 951 </row>
952 <row> 952 <row>
953 <entry>0x2B</entry> 953 <entry>0x2B</entry>
954 <entry>ECC byte 3</entry> 954 <entry>ECC byte 3</entry>
955 <entry>Error correction code byte 0 of the second 256 Bytes of data 955 <entry>Error correction code byte 0 of the second 256 Bytes of data
956 in this page</entry> 956 in this page</entry>
957 </row> 957 </row>
958 <row> 958 <row>
959 <entry>0x2C</entry> 959 <entry>0x2C</entry>
960 <entry>ECC byte 4</entry> 960 <entry>ECC byte 4</entry>
961 <entry>Error correction code byte 1 of the second 256 Bytes of data 961 <entry>Error correction code byte 1 of the second 256 Bytes of data
962 in this page</entry> 962 in this page</entry>
963 </row> 963 </row>
964 <row> 964 <row>
965 <entry>0x2D</entry> 965 <entry>0x2D</entry>
966 <entry>ECC byte 5</entry> 966 <entry>ECC byte 5</entry>
967 <entry>Error correction code byte 2 of the second 256 Bytes of data 967 <entry>Error correction code byte 2 of the second 256 Bytes of data
968 in this page</entry> 968 in this page</entry>
969 </row> 969 </row>
970 <row> 970 <row>
971 <entry>0x2E</entry> 971 <entry>0x2E</entry>
972 <entry>ECC byte 6</entry> 972 <entry>ECC byte 6</entry>
973 <entry>Error correction code byte 0 of the third 256 Bytes of data 973 <entry>Error correction code byte 0 of the third 256 Bytes of data
974 in this page</entry> 974 in this page</entry>
975 </row> 975 </row>
976 <row> 976 <row>
977 <entry>0x2F</entry> 977 <entry>0x2F</entry>
978 <entry>ECC byte 7</entry> 978 <entry>ECC byte 7</entry>
979 <entry>Error correction code byte 1 of the third 256 Bytes of data 979 <entry>Error correction code byte 1 of the third 256 Bytes of data
980 in this page</entry> 980 in this page</entry>
981 </row> 981 </row>
982 <row> 982 <row>
983 <entry>0x30</entry> 983 <entry>0x30</entry>
984 <entry>ECC byte 8</entry> 984 <entry>ECC byte 8</entry>
985 <entry>Error correction code byte 2 of the third 256 Bytes of data 985 <entry>Error correction code byte 2 of the third 256 Bytes of data
986 in this page</entry> 986 in this page</entry>
987 </row> 987 </row>
988 <row> 988 <row>
989 <entry>0x31</entry> 989 <entry>0x31</entry>
990 <entry>ECC byte 9</entry> 990 <entry>ECC byte 9</entry>
991 <entry>Error correction code byte 0 of the fourth 256 Bytes of data 991 <entry>Error correction code byte 0 of the fourth 256 Bytes of data
992 in this page</entry> 992 in this page</entry>
993 </row> 993 </row>
994 <row> 994 <row>
995 <entry>0x32</entry> 995 <entry>0x32</entry>
996 <entry>ECC byte 10</entry> 996 <entry>ECC byte 10</entry>
997 <entry>Error correction code byte 1 of the fourth 256 Bytes of data 997 <entry>Error correction code byte 1 of the fourth 256 Bytes of data
998 in this page</entry> 998 in this page</entry>
999 </row> 999 </row>
1000 <row> 1000 <row>
1001 <entry>0x33</entry> 1001 <entry>0x33</entry>
1002 <entry>ECC byte 11</entry> 1002 <entry>ECC byte 11</entry>
1003 <entry>Error correction code byte 2 of the fourth 256 Bytes of data 1003 <entry>Error correction code byte 2 of the fourth 256 Bytes of data
1004 in this page</entry> 1004 in this page</entry>
1005 </row> 1005 </row>
1006 <row> 1006 <row>
1007 <entry>0x34</entry> 1007 <entry>0x34</entry>
1008 <entry>ECC byte 12</entry> 1008 <entry>ECC byte 12</entry>
1009 <entry>Error correction code byte 0 of the fifth 256 Bytes of data 1009 <entry>Error correction code byte 0 of the fifth 256 Bytes of data
1010 in this page</entry> 1010 in this page</entry>
1011 </row> 1011 </row>
1012 <row> 1012 <row>
1013 <entry>0x35</entry> 1013 <entry>0x35</entry>
1014 <entry>ECC byte 13</entry> 1014 <entry>ECC byte 13</entry>
1015 <entry>Error correction code byte 1 of the fifth 256 Bytes of data 1015 <entry>Error correction code byte 1 of the fifth 256 Bytes of data
1016 in this page</entry> 1016 in this page</entry>
1017 </row> 1017 </row>
1018 <row> 1018 <row>
1019 <entry>0x36</entry> 1019 <entry>0x36</entry>
1020 <entry>ECC byte 14</entry> 1020 <entry>ECC byte 14</entry>
1021 <entry>Error correction code byte 2 of the fifth 256 Bytes of data 1021 <entry>Error correction code byte 2 of the fifth 256 Bytes of data
1022 in this page</entry> 1022 in this page</entry>
1023 </row> 1023 </row>
1024 <row> 1024 <row>
1025 <entry>0x37</entry> 1025 <entry>0x37</entry>
1026 <entry>ECC byte 15</entry> 1026 <entry>ECC byte 15</entry>
1027 <entry>Error correction code byte 0 of the sixt 256 Bytes of data 1027 <entry>Error correction code byte 0 of the sixt 256 Bytes of data
1028 in this page</entry> 1028 in this page</entry>
1029 </row> 1029 </row>
1030 <row> 1030 <row>
1031 <entry>0x38</entry> 1031 <entry>0x38</entry>
1032 <entry>ECC byte 16</entry> 1032 <entry>ECC byte 16</entry>
1033 <entry>Error correction code byte 1 of the sixt 256 Bytes of data 1033 <entry>Error correction code byte 1 of the sixt 256 Bytes of data
1034 in this page</entry> 1034 in this page</entry>
1035 </row> 1035 </row>
1036 <row> 1036 <row>
1037 <entry>0x39</entry> 1037 <entry>0x39</entry>
1038 <entry>ECC byte 17</entry> 1038 <entry>ECC byte 17</entry>
1039 <entry>Error correction code byte 2 of the sixt 256 Bytes of data 1039 <entry>Error correction code byte 2 of the sixt 256 Bytes of data
1040 in this page</entry> 1040 in this page</entry>
1041 </row> 1041 </row>
1042 <row> 1042 <row>
1043 <entry>0x3A</entry> 1043 <entry>0x3A</entry>
1044 <entry>ECC byte 18</entry> 1044 <entry>ECC byte 18</entry>
1045 <entry>Error correction code byte 0 of the seventh 256 Bytes of 1045 <entry>Error correction code byte 0 of the seventh 256 Bytes of
1046 data in this page</entry> 1046 data in this page</entry>
1047 </row> 1047 </row>
1048 <row> 1048 <row>
1049 <entry>0x3B</entry> 1049 <entry>0x3B</entry>
1050 <entry>ECC byte 19</entry> 1050 <entry>ECC byte 19</entry>
1051 <entry>Error correction code byte 1 of the seventh 256 Bytes of 1051 <entry>Error correction code byte 1 of the seventh 256 Bytes of
1052 data in this page</entry> 1052 data in this page</entry>
1053 </row> 1053 </row>
1054 <row> 1054 <row>
1055 <entry>0x3C</entry> 1055 <entry>0x3C</entry>
1056 <entry>ECC byte 20</entry> 1056 <entry>ECC byte 20</entry>
1057 <entry>Error correction code byte 2 of the seventh 256 Bytes of 1057 <entry>Error correction code byte 2 of the seventh 256 Bytes of
1058 data in this page</entry> 1058 data in this page</entry>
1059 </row> 1059 </row>
1060 <row> 1060 <row>
1061 <entry>0x3D</entry> 1061 <entry>0x3D</entry>
1062 <entry>ECC byte 21</entry> 1062 <entry>ECC byte 21</entry>
1063 <entry>Error correction code byte 0 of the eigth 256 Bytes of data 1063 <entry>Error correction code byte 0 of the eigth 256 Bytes of data
1064 in this page</entry> 1064 in this page</entry>
1065 </row> 1065 </row>
1066 <row> 1066 <row>
1067 <entry>0x3E</entry> 1067 <entry>0x3E</entry>
1068 <entry>ECC byte 22</entry> 1068 <entry>ECC byte 22</entry>
1069 <entry>Error correction code byte 1 of the eigth 256 Bytes of data 1069 <entry>Error correction code byte 1 of the eigth 256 Bytes of data
1070 in this page</entry> 1070 in this page</entry>
1071 </row> 1071 </row>
1072 <row> 1072 <row>
1073 <entry>0x3F</entry> 1073 <entry>0x3F</entry>
1074 <entry>ECC byte 23</entry> 1074 <entry>ECC byte 23</entry>
1075 <entry>Error correction code byte 2 of the eigth 256 Bytes of data 1075 <entry>Error correction code byte 2 of the eigth 256 Bytes of data
1076 in this page</entry> 1076 in this page</entry>
1077 </row> 1077 </row>
1078 </tbody></tgroup></informaltable> 1078 </tbody></tgroup></informaltable>
1079 </sect2> 1079 </sect2>
1080 </sect1> 1080 </sect1>
1081 </chapter> 1081 </chapter>
1082 1082
1083 <chapter id="filesystems"> 1083 <chapter id="filesystems">
1084 <title>Filesystem support</title> 1084 <title>Filesystem support</title>
1085 <para> 1085 <para>
1086 The NAND driver provides all neccecary functions for a 1086 The NAND driver provides all neccecary functions for a
1087 filesystem via the MTD interface. 1087 filesystem via the MTD interface.
1088 </para> 1088 </para>
1089 <para> 1089 <para>
1090 Filesystems must be aware of the NAND pecularities and 1090 Filesystems must be aware of the NAND pecularities and
1091 restrictions. One major restrictions of NAND Flash is, that you cannot 1091 restrictions. One major restrictions of NAND Flash is, that you cannot
1092 write as often as you want to a page. The consecutive writes to a page, 1092 write as often as you want to a page. The consecutive writes to a page,
1093 before erasing it again, are restricted to 1-3 writes, depending on the 1093 before erasing it again, are restricted to 1-3 writes, depending on the
1094 manufacturers specifications. This applies similar to the spare area. 1094 manufacturers specifications. This applies similar to the spare area.
1095 </para> 1095 </para>
1096 <para> 1096 <para>
1097 Therefor NAND aware filesystems must either write in page size chunks 1097 Therefor NAND aware filesystems must either write in page size chunks
1098 or hold a writebuffer to collect smaller writes until they sum up to 1098 or hold a writebuffer to collect smaller writes until they sum up to
1099 pagesize. Available NAND aware filesystems: JFFS2, YAFFS. 1099 pagesize. Available NAND aware filesystems: JFFS2, YAFFS.
1100 </para> 1100 </para>
1101 <para> 1101 <para>
1102 The spare area usage to store filesystem data is controlled by 1102 The spare area usage to store filesystem data is controlled by
1103 the spare area placement functionality which is described in one 1103 the spare area placement functionality which is described in one
1104 of the earlier chapters. 1104 of the earlier chapters.
1105 </para> 1105 </para>
1106 </chapter> 1106 </chapter>
1107 <chapter id="tools"> 1107 <chapter id="tools">
1108 <title>Tools</title> 1108 <title>Tools</title>
1109 <para> 1109 <para>
1110 The MTD project provides a couple of helpful tools to handle NAND Flash. 1110 The MTD project provides a couple of helpful tools to handle NAND Flash.
1111 <itemizedlist> 1111 <itemizedlist>
1112 <listitem><para>flasherase, flasheraseall: Erase and format FLASH partitions</para></listitem> 1112 <listitem><para>flasherase, flasheraseall: Erase and format FLASH partitions</para></listitem>
1113 <listitem><para>nandwrite: write filesystem images to NAND FLASH</para></listitem> 1113 <listitem><para>nandwrite: write filesystem images to NAND FLASH</para></listitem>
1114 <listitem><para>nanddump: dump the contents of a NAND FLASH partitions</para></listitem> 1114 <listitem><para>nanddump: dump the contents of a NAND FLASH partitions</para></listitem>
1115 </itemizedlist> 1115 </itemizedlist>
1116 </para> 1116 </para>
1117 <para> 1117 <para>
1118 These tools are aware of the NAND restrictions. Please use those tools 1118 These tools are aware of the NAND restrictions. Please use those tools
1119 instead of complaining about errors which are caused by non NAND aware 1119 instead of complaining about errors which are caused by non NAND aware
1120 access methods. 1120 access methods.
1121 </para> 1121 </para>
1122 </chapter> 1122 </chapter>
1123 1123
1124 <chapter id="defines"> 1124 <chapter id="defines">
1125 <title>Constants</title> 1125 <title>Constants</title>
1126 <para> 1126 <para>
1127 This chapter describes the constants which might be relevant for a driver developer. 1127 This chapter describes the constants which might be relevant for a driver developer.
1128 </para> 1128 </para>
1129 <sect1 id="Chip_option_constants"> 1129 <sect1 id="Chip_option_constants">
1130 <title>Chip option constants</title> 1130 <title>Chip option constants</title>
1131 <sect2 id="Constants_for_chip_id_table"> 1131 <sect2 id="Constants_for_chip_id_table">
1132 <title>Constants for chip id table</title> 1132 <title>Constants for chip id table</title>
1133 <para> 1133 <para>
1134 These constants are defined in nand.h. They are ored together to describe 1134 These constants are defined in nand.h. They are ored together to describe
1135 the chip functionality. 1135 the chip functionality.
1136 <programlisting> 1136 <programlisting>
1137 /* Chip can not auto increment pages */ 1137 /* Chip can not auto increment pages */
1138 #define NAND_NO_AUTOINCR 0x00000001 1138 #define NAND_NO_AUTOINCR 0x00000001
1139 /* Buswitdh is 16 bit */ 1139 /* Buswitdh is 16 bit */
1140 #define NAND_BUSWIDTH_16 0x00000002 1140 #define NAND_BUSWIDTH_16 0x00000002
1141 /* Device supports partial programming without padding */ 1141 /* Device supports partial programming without padding */
1142 #define NAND_NO_PADDING 0x00000004 1142 #define NAND_NO_PADDING 0x00000004
1143 /* Chip has cache program function */ 1143 /* Chip has cache program function */
1144 #define NAND_CACHEPRG 0x00000008 1144 #define NAND_CACHEPRG 0x00000008
1145 /* Chip has copy back function */ 1145 /* Chip has copy back function */
1146 #define NAND_COPYBACK 0x00000010 1146 #define NAND_COPYBACK 0x00000010
1147 /* AND Chip which has 4 banks and a confusing page / block 1147 /* AND Chip which has 4 banks and a confusing page / block
1148 * assignment. See Renesas datasheet for further information */ 1148 * assignment. See Renesas datasheet for further information */
1149 #define NAND_IS_AND 0x00000020 1149 #define NAND_IS_AND 0x00000020
1150 /* Chip has a array of 4 pages which can be read without 1150 /* Chip has a array of 4 pages which can be read without
1151 * additional ready /busy waits */ 1151 * additional ready /busy waits */
1152 #define NAND_4PAGE_ARRAY 0x00000040 1152 #define NAND_4PAGE_ARRAY 0x00000040
1153 </programlisting> 1153 </programlisting>
1154 </para> 1154 </para>
1155 </sect2> 1155 </sect2>
1156 <sect2 id="Constants_for_runtime_options"> 1156 <sect2 id="Constants_for_runtime_options">
1157 <title>Constants for runtime options</title> 1157 <title>Constants for runtime options</title>
1158 <para> 1158 <para>
1159 These constants are defined in nand.h. They are ored together to describe 1159 These constants are defined in nand.h. They are ored together to describe
1160 the functionality. 1160 the functionality.
1161 <programlisting> 1161 <programlisting>
1162 /* Use a flash based bad block table. This option is parsed by the 1162 /* Use a flash based bad block table. This option is parsed by the
1163 * default bad block table function (nand_default_bbt). */ 1163 * default bad block table function (nand_default_bbt). */
1164 #define NAND_USE_FLASH_BBT 0x00010000 1164 #define NAND_USE_FLASH_BBT 0x00010000
1165 /* The hw ecc generator provides a syndrome instead a ecc value on read 1165 /* The hw ecc generator provides a syndrome instead a ecc value on read
1166 * This can only work if we have the ecc bytes directly behind the 1166 * This can only work if we have the ecc bytes directly behind the
1167 * data bytes. Applies for DOC and AG-AND Renesas HW Reed Solomon generators */ 1167 * data bytes. Applies for DOC and AG-AND Renesas HW Reed Solomon generators */
1168 #define NAND_HWECC_SYNDROME 0x00020000 1168 #define NAND_HWECC_SYNDROME 0x00020000
1169 </programlisting> 1169 </programlisting>
1170 </para> 1170 </para>
1171 </sect2> 1171 </sect2>
1172 </sect1> 1172 </sect1>
1173 1173
1174 <sect1 id="EEC_selection_constants"> 1174 <sect1 id="EEC_selection_constants">
1175 <title>ECC selection constants</title> 1175 <title>ECC selection constants</title>
1176 <para> 1176 <para>
1177 Use these constants to select the ECC algorithm. 1177 Use these constants to select the ECC algorithm.
1178 <programlisting> 1178 <programlisting>
1179 /* No ECC. Usage is not recommended ! */ 1179 /* No ECC. Usage is not recommended ! */
1180 #define NAND_ECC_NONE 0 1180 #define NAND_ECC_NONE 0
1181 /* Software ECC 3 byte ECC per 256 Byte data */ 1181 /* Software ECC 3 byte ECC per 256 Byte data */
1182 #define NAND_ECC_SOFT 1 1182 #define NAND_ECC_SOFT 1
1183 /* Hardware ECC 3 byte ECC per 256 Byte data */ 1183 /* Hardware ECC 3 byte ECC per 256 Byte data */
1184 #define NAND_ECC_HW3_256 2 1184 #define NAND_ECC_HW3_256 2
1185 /* Hardware ECC 3 byte ECC per 512 Byte data */ 1185 /* Hardware ECC 3 byte ECC per 512 Byte data */
1186 #define NAND_ECC_HW3_512 3 1186 #define NAND_ECC_HW3_512 3
1187 /* Hardware ECC 6 byte ECC per 512 Byte data */ 1187 /* Hardware ECC 6 byte ECC per 512 Byte data */
1188 #define NAND_ECC_HW6_512 4 1188 #define NAND_ECC_HW6_512 4
1189 /* Hardware ECC 6 byte ECC per 512 Byte data */ 1189 /* Hardware ECC 6 byte ECC per 512 Byte data */
1190 #define NAND_ECC_HW8_512 6 1190 #define NAND_ECC_HW8_512 6
1191 </programlisting> 1191 </programlisting>
1192 </para> 1192 </para>
1193 </sect1> 1193 </sect1>
1194 1194
1195 <sect1 id="Hardware_control_related_constants"> 1195 <sect1 id="Hardware_control_related_constants">
1196 <title>Hardware control related constants</title> 1196 <title>Hardware control related constants</title>
1197 <para> 1197 <para>
1198 These constants describe the requested hardware access function when 1198 These constants describe the requested hardware access function when
1199 the boardspecific hardware control function is called 1199 the boardspecific hardware control function is called
1200 <programlisting> 1200 <programlisting>
1201 /* Select the chip by setting nCE to low */ 1201 /* Select the chip by setting nCE to low */
1202 #define NAND_CTL_SETNCE 1 1202 #define NAND_CTL_SETNCE 1
1203 /* Deselect the chip by setting nCE to high */ 1203 /* Deselect the chip by setting nCE to high */
1204 #define NAND_CTL_CLRNCE 2 1204 #define NAND_CTL_CLRNCE 2
1205 /* Select the command latch by setting CLE to high */ 1205 /* Select the command latch by setting CLE to high */
1206 #define NAND_CTL_SETCLE 3 1206 #define NAND_CTL_SETCLE 3
1207 /* Deselect the command latch by setting CLE to low */ 1207 /* Deselect the command latch by setting CLE to low */
1208 #define NAND_CTL_CLRCLE 4 1208 #define NAND_CTL_CLRCLE 4
1209 /* Select the address latch by setting ALE to high */ 1209 /* Select the address latch by setting ALE to high */
1210 #define NAND_CTL_SETALE 5 1210 #define NAND_CTL_SETALE 5
1211 /* Deselect the address latch by setting ALE to low */ 1211 /* Deselect the address latch by setting ALE to low */
1212 #define NAND_CTL_CLRALE 6 1212 #define NAND_CTL_CLRALE 6
1213 /* Set write protection by setting WP to high. Not used! */ 1213 /* Set write protection by setting WP to high. Not used! */
1214 #define NAND_CTL_SETWP 7 1214 #define NAND_CTL_SETWP 7
1215 /* Clear write protection by setting WP to low. Not used! */ 1215 /* Clear write protection by setting WP to low. Not used! */
1216 #define NAND_CTL_CLRWP 8 1216 #define NAND_CTL_CLRWP 8
1217 </programlisting> 1217 </programlisting>
1218 </para> 1218 </para>
1219 </sect1> 1219 </sect1>
1220 1220
1221 <sect1 id="Bad_block_table_constants"> 1221 <sect1 id="Bad_block_table_constants">
1222 <title>Bad block table related constants</title> 1222 <title>Bad block table related constants</title>
1223 <para> 1223 <para>
1224 These constants describe the options used for bad block 1224 These constants describe the options used for bad block
1225 table descriptors. 1225 table descriptors.
1226 <programlisting> 1226 <programlisting>
1227 /* Options for the bad block table descriptors */ 1227 /* Options for the bad block table descriptors */
1228 1228
1229 /* The number of bits used per block in the bbt on the device */ 1229 /* The number of bits used per block in the bbt on the device */
1230 #define NAND_BBT_NRBITS_MSK 0x0000000F 1230 #define NAND_BBT_NRBITS_MSK 0x0000000F
1231 #define NAND_BBT_1BIT 0x00000001 1231 #define NAND_BBT_1BIT 0x00000001
1232 #define NAND_BBT_2BIT 0x00000002 1232 #define NAND_BBT_2BIT 0x00000002
1233 #define NAND_BBT_4BIT 0x00000004 1233 #define NAND_BBT_4BIT 0x00000004
1234 #define NAND_BBT_8BIT 0x00000008 1234 #define NAND_BBT_8BIT 0x00000008
1235 /* The bad block table is in the last good block of the device */ 1235 /* The bad block table is in the last good block of the device */
1236 #define NAND_BBT_LASTBLOCK 0x00000010 1236 #define NAND_BBT_LASTBLOCK 0x00000010
1237 /* The bbt is at the given page, else we must scan for the bbt */ 1237 /* The bbt is at the given page, else we must scan for the bbt */
1238 #define NAND_BBT_ABSPAGE 0x00000020 1238 #define NAND_BBT_ABSPAGE 0x00000020
1239 /* The bbt is at the given page, else we must scan for the bbt */ 1239 /* The bbt is at the given page, else we must scan for the bbt */
1240 #define NAND_BBT_SEARCH 0x00000040 1240 #define NAND_BBT_SEARCH 0x00000040
1241 /* bbt is stored per chip on multichip devices */ 1241 /* bbt is stored per chip on multichip devices */
1242 #define NAND_BBT_PERCHIP 0x00000080 1242 #define NAND_BBT_PERCHIP 0x00000080
1243 /* bbt has a version counter at offset veroffs */ 1243 /* bbt has a version counter at offset veroffs */
1244 #define NAND_BBT_VERSION 0x00000100 1244 #define NAND_BBT_VERSION 0x00000100
1245 /* Create a bbt if none axists */ 1245 /* Create a bbt if none axists */
1246 #define NAND_BBT_CREATE 0x00000200 1246 #define NAND_BBT_CREATE 0x00000200
1247 /* Search good / bad pattern through all pages of a block */ 1247 /* Search good / bad pattern through all pages of a block */
1248 #define NAND_BBT_SCANALLPAGES 0x00000400 1248 #define NAND_BBT_SCANALLPAGES 0x00000400
1249 /* Scan block empty during good / bad block scan */ 1249 /* Scan block empty during good / bad block scan */
1250 #define NAND_BBT_SCANEMPTY 0x00000800 1250 #define NAND_BBT_SCANEMPTY 0x00000800
1251 /* Write bbt if neccecary */ 1251 /* Write bbt if neccecary */
1252 #define NAND_BBT_WRITE 0x00001000 1252 #define NAND_BBT_WRITE 0x00001000
1253 /* Read and write back block contents when writing bbt */ 1253 /* Read and write back block contents when writing bbt */
1254 #define NAND_BBT_SAVECONTENT 0x00002000 1254 #define NAND_BBT_SAVECONTENT 0x00002000
1255 </programlisting> 1255 </programlisting>
1256 </para> 1256 </para>
1257 </sect1> 1257 </sect1>
1258 1258
1259 </chapter> 1259 </chapter>
1260 1260
1261 <chapter id="structs"> 1261 <chapter id="structs">
1262 <title>Structures</title> 1262 <title>Structures</title>
1263 <para> 1263 <para>
1264 This chapter contains the autogenerated documentation of the structures which are 1264 This chapter contains the autogenerated documentation of the structures which are
1265 used in the NAND driver and might be relevant for a driver developer. Each 1265 used in the NAND driver and might be relevant for a driver developer. Each
1266 struct member has a short description which is marked with an [XXX] identifier. 1266 struct member has a short description which is marked with an [XXX] identifier.
1267 See the chapter "Documentation hints" for an explanation. 1267 See the chapter "Documentation hints" for an explanation.
1268 </para> 1268 </para>
1269 !Iinclude/linux/mtd/nand.h 1269 !Iinclude/linux/mtd/nand.h
1270 </chapter> 1270 </chapter>
1271 1271
1272 <chapter id="pubfunctions"> 1272 <chapter id="pubfunctions">
1273 <title>Public Functions Provided</title> 1273 <title>Public Functions Provided</title>
1274 <para> 1274 <para>
1275 This chapter contains the autogenerated documentation of the NAND kernel API functions 1275 This chapter contains the autogenerated documentation of the NAND kernel API functions
1276 which are exported. Each function has a short description which is marked with an [XXX] identifier. 1276 which are exported. Each function has a short description which is marked with an [XXX] identifier.
1277 See the chapter "Documentation hints" for an explanation. 1277 See the chapter "Documentation hints" for an explanation.
1278 </para> 1278 </para>
1279 !Edrivers/mtd/nand/nand_base.c 1279 !Edrivers/mtd/nand/nand_base.c
1280 !Edrivers/mtd/nand/nand_bbt.c 1280 !Edrivers/mtd/nand/nand_bbt.c
1281 !Edrivers/mtd/nand/nand_ecc.c 1281 !Edrivers/mtd/nand/nand_ecc.c
1282 </chapter> 1282 </chapter>
1283 1283
1284 <chapter id="intfunctions"> 1284 <chapter id="intfunctions">
1285 <title>Internal Functions Provided</title> 1285 <title>Internal Functions Provided</title>
1286 <para> 1286 <para>
1287 This chapter contains the autogenerated documentation of the NAND driver internal functions. 1287 This chapter contains the autogenerated documentation of the NAND driver internal functions.
1288 Each function has a short description which is marked with an [XXX] identifier. 1288 Each function has a short description which is marked with an [XXX] identifier.
1289 See the chapter "Documentation hints" for an explanation. 1289 See the chapter "Documentation hints" for an explanation.
1290 The functions marked with [DEFAULT] might be relevant for a board driver developer. 1290 The functions marked with [DEFAULT] might be relevant for a board driver developer.
1291 </para> 1291 </para>
1292 !Idrivers/mtd/nand/nand_base.c 1292 !Idrivers/mtd/nand/nand_base.c
1293 !Idrivers/mtd/nand/nand_bbt.c 1293 !Idrivers/mtd/nand/nand_bbt.c
1294 <!-- No internal functions for kernel-doc: 1294 <!-- No internal functions for kernel-doc:
1295 X!Idrivers/mtd/nand/nand_ecc.c 1295 X!Idrivers/mtd/nand/nand_ecc.c
1296 --> 1296 -->
1297 </chapter> 1297 </chapter>
1298 1298
1299 <chapter id="credits"> 1299 <chapter id="credits">
1300 <title>Credits</title> 1300 <title>Credits</title>
1301 <para> 1301 <para>
1302 The following people have contributed to the NAND driver: 1302 The following people have contributed to the NAND driver:
1303 <orderedlist> 1303 <orderedlist>
1304 <listitem><para>Steven J. Hill<email>sjhill@realitydiluted.com</email></para></listitem> 1304 <listitem><para>Steven J. Hill<email>sjhill@realitydiluted.com</email></para></listitem>
1305 <listitem><para>David Woodhouse<email>dwmw2@infradead.org</email></para></listitem> 1305 <listitem><para>David Woodhouse<email>dwmw2@infradead.org</email></para></listitem>
1306 <listitem><para>Thomas Gleixner<email>tglx@linutronix.de</email></para></listitem> 1306 <listitem><para>Thomas Gleixner<email>tglx@linutronix.de</email></para></listitem>
1307 </orderedlist> 1307 </orderedlist>
1308 A lot of users have provided bugfixes, improvements and helping hands for testing. 1308 A lot of users have provided bugfixes, improvements and helping hands for testing.
1309 Thanks a lot. 1309 Thanks a lot.
1310 </para> 1310 </para>
1311 <para> 1311 <para>
1312 The following people have contributed to this document: 1312 The following people have contributed to this document:
1313 <orderedlist> 1313 <orderedlist>
1314 <listitem><para>Thomas Gleixner<email>tglx@linutronix.de</email></para></listitem> 1314 <listitem><para>Thomas Gleixner<email>tglx@linutronix.de</email></para></listitem>
1315 </orderedlist> 1315 </orderedlist>
1316 </para> 1316 </para>
1317 </chapter> 1317 </chapter>
1318 </book> 1318 </book>
1319 1319
Documentation/DocBook/scsi.tmpl
1 <?xml version="1.0" encoding="UTF-8"?> 1 <?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" 2 <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
3 "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []> 3 "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
4 4
5 <book id="scsimid"> 5 <book id="scsimid">
6 <bookinfo> 6 <bookinfo>
7 <title>SCSI Interfaces Guide</title> 7 <title>SCSI Interfaces Guide</title>
8 8
9 <authorgroup> 9 <authorgroup>
10 <author> 10 <author>
11 <firstname>James</firstname> 11 <firstname>James</firstname>
12 <surname>Bottomley</surname> 12 <surname>Bottomley</surname>
13 <affiliation> 13 <affiliation>
14 <address> 14 <address>
15 <email>James.Bottomley@hansenpartnership.com</email> 15 <email>James.Bottomley@hansenpartnership.com</email>
16 </address> 16 </address>
17 </affiliation> 17 </affiliation>
18 </author> 18 </author>
19 19
20 <author> 20 <author>
21 <firstname>Rob</firstname> 21 <firstname>Rob</firstname>
22 <surname>Landley</surname> 22 <surname>Landley</surname>
23 <affiliation> 23 <affiliation>
24 <address> 24 <address>
25 <email>rob@landley.net</email> 25 <email>rob@landley.net</email>
26 </address> 26 </address>
27 </affiliation> 27 </affiliation>
28 </author> 28 </author>
29 29
30 </authorgroup> 30 </authorgroup>
31 31
32 <copyright> 32 <copyright>
33 <year>2007</year> 33 <year>2007</year>
34 <holder>Linux Foundation</holder> 34 <holder>Linux Foundation</holder>
35 </copyright> 35 </copyright>
36 36
37 <legalnotice> 37 <legalnotice>
38 <para> 38 <para>
39 This documentation is free software; you can redistribute 39 This documentation is free software; you can redistribute
40 it and/or modify it under the terms of the GNU General Public 40 it and/or modify it under the terms of the GNU General Public
41 License version 2. 41 License version 2.
42 </para> 42 </para>
43 43
44 <para> 44 <para>
45 This program is distributed in the hope that it will be 45 This program is distributed in the hope that it will be
46 useful, but WITHOUT ANY WARRANTY; without even the implied 46 useful, but WITHOUT ANY WARRANTY; without even the implied
47 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 47 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
48 For more details see the file COPYING in the source 48 For more details see the file COPYING in the source
49 distribution of Linux. 49 distribution of Linux.
50 </para> 50 </para>
51 </legalnotice> 51 </legalnotice>
52 </bookinfo> 52 </bookinfo>
53 53
54 <toc></toc> 54 <toc></toc>
55 55
56 <chapter id="intro"> 56 <chapter id="intro">
57 <title>Introduction</title> 57 <title>Introduction</title>
58 <sect1 id="protocol_vs_bus"> 58 <sect1 id="protocol_vs_bus">
59 <title>Protocol vs bus</title> 59 <title>Protocol vs bus</title>
60 <para> 60 <para>
61 Once upon a time, the Small Computer Systems Interface defined both 61 Once upon a time, the Small Computer Systems Interface defined both
62 a parallel I/O bus and a data protocol to connect a wide variety of 62 a parallel I/O bus and a data protocol to connect a wide variety of
63 peripherals (disk drives, tape drives, modems, printers, scanners, 63 peripherals (disk drives, tape drives, modems, printers, scanners,
64 optical drives, test equipment, and medical devices) to a host 64 optical drives, test equipment, and medical devices) to a host
65 computer. 65 computer.
66 </para> 66 </para>
67 <para> 67 <para>
68 Although the old parallel (fast/wide/ultra) SCSI bus has largely 68 Although the old parallel (fast/wide/ultra) SCSI bus has largely
69 fallen out of use, the SCSI command set is more widely used than ever 69 fallen out of use, the SCSI command set is more widely used than ever
70 to communicate with devices over a number of different busses. 70 to communicate with devices over a number of different busses.
71 </para> 71 </para>
72 <para> 72 <para>
73 The <ulink url='http://www.t10.org/scsi-3.htm'>SCSI protocol</ulink> 73 The <ulink url='http://www.t10.org/scsi-3.htm'>SCSI protocol</ulink>
74 is a big-endian peer-to-peer packet based protocol. SCSI commands 74 is a big-endian peer-to-peer packet based protocol. SCSI commands
75 are 6, 10, 12, or 16 bytes long, often followed by an associated data 75 are 6, 10, 12, or 16 bytes long, often followed by an associated data
76 payload. 76 payload.
77 </para> 77 </para>
78 <para> 78 <para>
79 SCSI commands can be transported over just about any kind of bus, and 79 SCSI commands can be transported over just about any kind of bus, and
80 are the default protocol for storage devices attached to USB, SATA, 80 are the default protocol for storage devices attached to USB, SATA,
81 SAS, Fibre Channel, FireWire, and ATAPI devices. SCSI packets are 81 SAS, Fibre Channel, FireWire, and ATAPI devices. SCSI packets are
82 also commonly exchanged over Infiniband, 82 also commonly exchanged over Infiniband,
83 <ulink url='http://i2o.shadowconnect.com/faq.php'>I20</ulink>, TCP/IP 83 <ulink url='http://i2o.shadowconnect.com/faq.php'>I20</ulink>, TCP/IP
84 (<ulink url='http://en.wikipedia.org/wiki/ISCSI'>iSCSI</ulink>), even 84 (<ulink url='http://en.wikipedia.org/wiki/ISCSI'>iSCSI</ulink>), even
85 <ulink url='http://cyberelk.net/tim/parport/parscsi.html'>Parallel 85 <ulink url='http://cyberelk.net/tim/parport/parscsi.html'>Parallel
86 ports</ulink>. 86 ports</ulink>.
87 </para> 87 </para>
88 </sect1> 88 </sect1>
89 <sect1 id="subsystem_design"> 89 <sect1 id="subsystem_design">
90 <title>Design of the Linux SCSI subsystem</title> 90 <title>Design of the Linux SCSI subsystem</title>
91 <para> 91 <para>
92 The SCSI subsystem uses a three layer design, with upper, mid, and low 92 The SCSI subsystem uses a three layer design, with upper, mid, and low
93 layers. Every operation involving the SCSI subsystem (such as reading 93 layers. Every operation involving the SCSI subsystem (such as reading
94 a sector from a disk) uses one driver at each of the 3 levels: one 94 a sector from a disk) uses one driver at each of the 3 levels: one
95 upper layer driver, one lower layer driver, and the SCSI midlayer. 95 upper layer driver, one lower layer driver, and the SCSI midlayer.
96 </para> 96 </para>
97 <para> 97 <para>
98 The SCSI upper layer provides the interface between userspace and the 98 The SCSI upper layer provides the interface between userspace and the
99 kernel, in the form of block and char device nodes for I/O and 99 kernel, in the form of block and char device nodes for I/O and
100 ioctl(). The SCSI lower layer contains drivers for specific hardware 100 ioctl(). The SCSI lower layer contains drivers for specific hardware
101 devices. 101 devices.
102 </para> 102 </para>
103 <para> 103 <para>
104 In between is the SCSI mid-layer, analogous to a network routing 104 In between is the SCSI mid-layer, analogous to a network routing
105 layer such as the IPv4 stack. The SCSI mid-layer routes a packet 105 layer such as the IPv4 stack. The SCSI mid-layer routes a packet
106 based data protocol between the upper layer's /dev nodes and the 106 based data protocol between the upper layer's /dev nodes and the
107 corresponding devices in the lower layer. It manages command queues, 107 corresponding devices in the lower layer. It manages command queues,
108 provides error handling and power management functions, and responds 108 provides error handling and power management functions, and responds
109 to ioctl() requests. 109 to ioctl() requests.
110 </para> 110 </para>
111 </sect1> 111 </sect1>
112 </chapter> 112 </chapter>
113 113
114 <chapter id="upper_layer"> 114 <chapter id="upper_layer">
115 <title>SCSI upper layer</title> 115 <title>SCSI upper layer</title>
116 <para> 116 <para>
117 The upper layer supports the user-kernel interface by providing 117 The upper layer supports the user-kernel interface by providing
118 device nodes. 118 device nodes.
119 </para> 119 </para>
120 <sect1 id="sd"> 120 <sect1 id="sd">
121 <title>sd (SCSI Disk)</title> 121 <title>sd (SCSI Disk)</title>
122 <para>sd (sd_mod.o)</para> 122 <para>sd (sd_mod.o)</para>
123 <!-- !Idrivers/scsi/sd.c --> 123 <!-- !Idrivers/scsi/sd.c -->
124 </sect1> 124 </sect1>
125 <sect1 id="sr"> 125 <sect1 id="sr">
126 <title>sr (SCSI CD-ROM)</title> 126 <title>sr (SCSI CD-ROM)</title>
127 <para>sr (sr_mod.o)</para> 127 <para>sr (sr_mod.o)</para>
128 </sect1> 128 </sect1>
129 <sect1 id="st"> 129 <sect1 id="st">
130 <title>st (SCSI Tape)</title> 130 <title>st (SCSI Tape)</title>
131 <para>st (st.o)</para> 131 <para>st (st.o)</para>
132 </sect1> 132 </sect1>
133 <sect1 id="sg"> 133 <sect1 id="sg">
134 <title>sg (SCSI Generic)</title> 134 <title>sg (SCSI Generic)</title>
135 <para>sg (sg.o)</para> 135 <para>sg (sg.o)</para>
136 </sect1> 136 </sect1>
137 <sect1 id="ch"> 137 <sect1 id="ch">
138 <title>ch (SCSI Media Changer)</title> 138 <title>ch (SCSI Media Changer)</title>
139 <para>ch (ch.c)</para> 139 <para>ch (ch.c)</para>
140 </sect1> 140 </sect1>
141 </chapter> 141 </chapter>
142 142
143 <chapter id="mid_layer"> 143 <chapter id="mid_layer">
144 <title>SCSI mid layer</title> 144 <title>SCSI mid layer</title>
145 145
146 <sect1 id="midlayer_implementation"> 146 <sect1 id="midlayer_implementation">
147 <title>SCSI midlayer implementation</title> 147 <title>SCSI midlayer implementation</title>
148 <sect2 id="scsi_device.h"> 148 <sect2 id="scsi_device.h">
149 <title>include/scsi/scsi_device.h</title> 149 <title>include/scsi/scsi_device.h</title>
150 <para> 150 <para>
151 </para> 151 </para>
152 !Iinclude/scsi/scsi_device.h 152 !Iinclude/scsi/scsi_device.h
153 </sect2> 153 </sect2>
154 154
155 <sect2 id="scsi.c"> 155 <sect2 id="scsi.c">
156 <title>drivers/scsi/scsi.c</title> 156 <title>drivers/scsi/scsi.c</title>
157 <para>Main file for the SCSI midlayer.</para> 157 <para>Main file for the SCSI midlayer.</para>
158 !Edrivers/scsi/scsi.c 158 !Edrivers/scsi/scsi.c
159 </sect2> 159 </sect2>
160 <sect2 id="scsicam.c"> 160 <sect2 id="scsicam.c">
161 <title>drivers/scsi/scsicam.c</title> 161 <title>drivers/scsi/scsicam.c</title>
162 <para> 162 <para>
163 <ulink url='http://www.t10.org/ftp/t10/drafts/cam/cam-r12b.pdf'>SCSI 163 <ulink url='http://www.t10.org/ftp/t10/drafts/cam/cam-r12b.pdf'>SCSI
164 Common Access Method</ulink> support functions, for use with 164 Common Access Method</ulink> support functions, for use with
165 HDIO_GETGEO, etc. 165 HDIO_GETGEO, etc.
166 </para> 166 </para>
167 !Edrivers/scsi/scsicam.c 167 !Edrivers/scsi/scsicam.c
168 </sect2> 168 </sect2>
169 <sect2 id="scsi_error.c"> 169 <sect2 id="scsi_error.c">
170 <title>drivers/scsi/scsi_error.c</title> 170 <title>drivers/scsi/scsi_error.c</title>
171 <para>Common SCSI error/timeout handling routines.</para> 171 <para>Common SCSI error/timeout handling routines.</para>
172 !Edrivers/scsi/scsi_error.c 172 !Edrivers/scsi/scsi_error.c
173 </sect2> 173 </sect2>
174 <sect2 id="scsi_devinfo.c"> 174 <sect2 id="scsi_devinfo.c">
175 <title>drivers/scsi/scsi_devinfo.c</title> 175 <title>drivers/scsi/scsi_devinfo.c</title>
176 <para> 176 <para>
177 Manage scsi_dev_info_list, which tracks blacklisted and whitelisted 177 Manage scsi_dev_info_list, which tracks blacklisted and whitelisted
178 devices. 178 devices.
179 </para> 179 </para>
180 !Idrivers/scsi/scsi_devinfo.c 180 !Idrivers/scsi/scsi_devinfo.c
181 </sect2> 181 </sect2>
182 <sect2 id="scsi_ioctl.c"> 182 <sect2 id="scsi_ioctl.c">
183 <title>drivers/scsi/scsi_ioctl.c</title> 183 <title>drivers/scsi/scsi_ioctl.c</title>
184 <para> 184 <para>
185 Handle ioctl() calls for SCSI devices. 185 Handle ioctl() calls for SCSI devices.
186 </para> 186 </para>
187 !Edrivers/scsi/scsi_ioctl.c 187 !Edrivers/scsi/scsi_ioctl.c
188 </sect2> 188 </sect2>
189 <sect2 id="scsi_lib.c"> 189 <sect2 id="scsi_lib.c">
190 <title>drivers/scsi/scsi_lib.c</title> 190 <title>drivers/scsi/scsi_lib.c</title>
191 <para> 191 <para>
192 SCSI queuing library. 192 SCSI queuing library.
193 </para> 193 </para>
194 !Edrivers/scsi/scsi_lib.c 194 !Edrivers/scsi/scsi_lib.c
195 </sect2> 195 </sect2>
196 <sect2 id="scsi_lib_dma.c"> 196 <sect2 id="scsi_lib_dma.c">
197 <title>drivers/scsi/scsi_lib_dma.c</title> 197 <title>drivers/scsi/scsi_lib_dma.c</title>
198 <para> 198 <para>
199 SCSI library functions depending on DMA 199 SCSI library functions depending on DMA
200 (map and unmap scatter-gather lists). 200 (map and unmap scatter-gather lists).
201 </para> 201 </para>
202 !Edrivers/scsi/scsi_lib_dma.c 202 !Edrivers/scsi/scsi_lib_dma.c
203 </sect2> 203 </sect2>
204 <sect2 id="scsi_module.c"> 204 <sect2 id="scsi_module.c">
205 <title>drivers/scsi/scsi_module.c</title> 205 <title>drivers/scsi/scsi_module.c</title>
206 <para> 206 <para>
207 The file drivers/scsi/scsi_module.c contains legacy support for 207 The file drivers/scsi/scsi_module.c contains legacy support for
208 old-style host templates. It should never be used by any new driver. 208 old-style host templates. It should never be used by any new driver.
209 </para> 209 </para>
210 </sect2> 210 </sect2>
211 <sect2 id="scsi_proc.c"> 211 <sect2 id="scsi_proc.c">
212 <title>drivers/scsi/scsi_proc.c</title> 212 <title>drivers/scsi/scsi_proc.c</title>
213 <para> 213 <para>
214 The functions in this file provide an interface between 214 The functions in this file provide an interface between
215 the PROC file system and the SCSI device drivers 215 the PROC file system and the SCSI device drivers
216 It is mainly used for debugging, statistics and to pass 216 It is mainly used for debugging, statistics and to pass
217 information directly to the lowlevel driver. 217 information directly to the lowlevel driver.
218 218
219 I.E. plumbing to manage /proc/scsi/* 219 I.E. plumbing to manage /proc/scsi/*
220 </para> 220 </para>
221 !Idrivers/scsi/scsi_proc.c 221 !Idrivers/scsi/scsi_proc.c
222 </sect2> 222 </sect2>
223 <sect2 id="scsi_netlink.c"> 223 <sect2 id="scsi_netlink.c">
224 <title>drivers/scsi/scsi_netlink.c</title> 224 <title>drivers/scsi/scsi_netlink.c</title>
225 <para> 225 <para>
226 Infrastructure to provide async events from transports to userspace 226 Infrastructure to provide async events from transports to userspace
227 via netlink, using a single NETLINK_SCSITRANSPORT protocol for all 227 via netlink, using a single NETLINK_SCSITRANSPORT protocol for all
228 transports. 228 transports.
229 229
230 See <ulink url='http://marc.info/?l=linux-scsi&amp;m=115507374832500&amp;w=2'>the 230 See <ulink url='http://marc.info/?l=linux-scsi&amp;m=115507374832500&amp;w=2'>the
231 original patch submission</ulink> for more details. 231 original patch submission</ulink> for more details.
232 </para> 232 </para>
233 !Idrivers/scsi/scsi_netlink.c 233 !Idrivers/scsi/scsi_netlink.c
234 </sect2> 234 </sect2>
235 <sect2 id="scsi_scan.c"> 235 <sect2 id="scsi_scan.c">
236 <title>drivers/scsi/scsi_scan.c</title> 236 <title>drivers/scsi/scsi_scan.c</title>
237 <para> 237 <para>
238 Scan a host to determine which (if any) devices are attached. 238 Scan a host to determine which (if any) devices are attached.
239 239
240 The general scanning/probing algorithm is as follows, exceptions are 240 The general scanning/probing algorithm is as follows, exceptions are
241 made to it depending on device specific flags, compilation options, 241 made to it depending on device specific flags, compilation options,
242 and global variable (boot or module load time) settings. 242 and global variable (boot or module load time) settings.
243 243
244 A specific LUN is scanned via an INQUIRY command; if the LUN has a 244 A specific LUN is scanned via an INQUIRY command; if the LUN has a
245 device attached, a scsi_device is allocated and setup for it. 245 device attached, a scsi_device is allocated and setup for it.
246 246
247 For every id of every channel on the given host, start by scanning 247 For every id of every channel on the given host, start by scanning
248 LUN 0. Skip hosts that don't respond at all to a scan of LUN 0. 248 LUN 0. Skip hosts that don't respond at all to a scan of LUN 0.
249 Otherwise, if LUN 0 has a device attached, allocate and setup a 249 Otherwise, if LUN 0 has a device attached, allocate and setup a
250 scsi_device for it. If target is SCSI-3 or up, issue a REPORT LUN, 250 scsi_device for it. If target is SCSI-3 or up, issue a REPORT LUN,
251 and scan all of the LUNs returned by the REPORT LUN; else, 251 and scan all of the LUNs returned by the REPORT LUN; else,
252 sequentially scan LUNs up until some maximum is reached, or a LUN is 252 sequentially scan LUNs up until some maximum is reached, or a LUN is
253 seen that cannot have a device attached to it. 253 seen that cannot have a device attached to it.
254 </para> 254 </para>
255 !Idrivers/scsi/scsi_scan.c 255 !Idrivers/scsi/scsi_scan.c
256 </sect2> 256 </sect2>
257 <sect2 id="scsi_sysctl.c"> 257 <sect2 id="scsi_sysctl.c">
258 <title>drivers/scsi/scsi_sysctl.c</title> 258 <title>drivers/scsi/scsi_sysctl.c</title>
259 <para> 259 <para>
260 Set up the sysctl entry: "/dev/scsi/logging_level" 260 Set up the sysctl entry: "/dev/scsi/logging_level"
261 (DEV_SCSI_LOGGING_LEVEL) which sets/returns scsi_logging_level. 261 (DEV_SCSI_LOGGING_LEVEL) which sets/returns scsi_logging_level.
262 </para> 262 </para>
263 </sect2> 263 </sect2>
264 <sect2 id="scsi_sysfs.c"> 264 <sect2 id="scsi_sysfs.c">
265 <title>drivers/scsi/scsi_sysfs.c</title> 265 <title>drivers/scsi/scsi_sysfs.c</title>
266 <para> 266 <para>
267 SCSI sysfs interface routines. 267 SCSI sysfs interface routines.
268 </para> 268 </para>
269 !Edrivers/scsi/scsi_sysfs.c 269 !Edrivers/scsi/scsi_sysfs.c
270 </sect2> 270 </sect2>
271 <sect2 id="hosts.c"> 271 <sect2 id="hosts.c">
272 <title>drivers/scsi/hosts.c</title> 272 <title>drivers/scsi/hosts.c</title>
273 <para> 273 <para>
274 mid to lowlevel SCSI driver interface 274 mid to lowlevel SCSI driver interface
275 </para> 275 </para>
276 !Edrivers/scsi/hosts.c 276 !Edrivers/scsi/hosts.c
277 </sect2> 277 </sect2>
278 <sect2 id="constants.c"> 278 <sect2 id="constants.c">
279 <title>drivers/scsi/constants.c</title> 279 <title>drivers/scsi/constants.c</title>
280 <para> 280 <para>
281 mid to lowlevel SCSI driver interface 281 mid to lowlevel SCSI driver interface
282 </para> 282 </para>
283 !Edrivers/scsi/constants.c 283 !Edrivers/scsi/constants.c
284 </sect2> 284 </sect2>
285 </sect1> 285 </sect1>
286 286
287 <sect1 id="Transport_classes"> 287 <sect1 id="Transport_classes">
288 <title>Transport classes</title> 288 <title>Transport classes</title>
289 <para> 289 <para>
290 Transport classes are service libraries for drivers in the SCSI 290 Transport classes are service libraries for drivers in the SCSI
291 lower layer, which expose transport attributes in sysfs. 291 lower layer, which expose transport attributes in sysfs.
292 </para> 292 </para>
293 <sect2 id="Fibre_Channel_transport"> 293 <sect2 id="Fibre_Channel_transport">
294 <title>Fibre Channel transport</title> 294 <title>Fibre Channel transport</title>
295 <para> 295 <para>
296 The file drivers/scsi/scsi_transport_fc.c defines transport attributes 296 The file drivers/scsi/scsi_transport_fc.c defines transport attributes
297 for Fibre Channel. 297 for Fibre Channel.
298 </para> 298 </para>
299 !Edrivers/scsi/scsi_transport_fc.c 299 !Edrivers/scsi/scsi_transport_fc.c
300 </sect2> 300 </sect2>
301 <sect2 id="iSCSI_transport"> 301 <sect2 id="iSCSI_transport">
302 <title>iSCSI transport class</title> 302 <title>iSCSI transport class</title>
303 <para> 303 <para>
304 The file drivers/scsi/scsi_transport_iscsi.c defines transport 304 The file drivers/scsi/scsi_transport_iscsi.c defines transport
305 attributes for the iSCSI class, which sends SCSI packets over TCP/IP 305 attributes for the iSCSI class, which sends SCSI packets over TCP/IP
306 connections. 306 connections.
307 </para> 307 </para>
308 !Edrivers/scsi/scsi_transport_iscsi.c 308 !Edrivers/scsi/scsi_transport_iscsi.c
309 </sect2> 309 </sect2>
310 <sect2 id="SAS_transport"> 310 <sect2 id="SAS_transport">
311 <title>Serial Attached SCSI (SAS) transport class</title> 311 <title>Serial Attached SCSI (SAS) transport class</title>
312 <para> 312 <para>
313 The file drivers/scsi/scsi_transport_sas.c defines transport 313 The file drivers/scsi/scsi_transport_sas.c defines transport
314 attributes for Serial Attached SCSI, a variant of SATA aimed at 314 attributes for Serial Attached SCSI, a variant of SATA aimed at
315 large high-end systems. 315 large high-end systems.
316 </para> 316 </para>
317 <para> 317 <para>
318 The SAS transport class contains common code to deal with SAS HBAs, 318 The SAS transport class contains common code to deal with SAS HBAs,
319 an aproximated representation of SAS topologies in the driver model, 319 an aproximated representation of SAS topologies in the driver model,
320 and various sysfs attributes to expose these topologies and managment 320 and various sysfs attributes to expose these topologies and management
321 interfaces to userspace. 321 interfaces to userspace.
322 </para> 322 </para>
323 <para> 323 <para>
324 In addition to the basic SCSI core objects this transport class 324 In addition to the basic SCSI core objects this transport class
325 introduces two additional intermediate objects: The SAS PHY 325 introduces two additional intermediate objects: The SAS PHY
326 as represented by struct sas_phy defines an "outgoing" PHY on 326 as represented by struct sas_phy defines an "outgoing" PHY on
327 a SAS HBA or Expander, and the SAS remote PHY represented by 327 a SAS HBA or Expander, and the SAS remote PHY represented by
328 struct sas_rphy defines an "incoming" PHY on a SAS Expander or 328 struct sas_rphy defines an "incoming" PHY on a SAS Expander or
329 end device. Note that this is purely a software concept, the 329 end device. Note that this is purely a software concept, the
330 underlying hardware for a PHY and a remote PHY is the exactly 330 underlying hardware for a PHY and a remote PHY is the exactly
331 the same. 331 the same.
332 </para> 332 </para>
333 <para> 333 <para>
334 There is no concept of a SAS port in this code, users can see 334 There is no concept of a SAS port in this code, users can see
335 what PHYs form a wide port based on the port_identifier attribute, 335 what PHYs form a wide port based on the port_identifier attribute,
336 which is the same for all PHYs in a port. 336 which is the same for all PHYs in a port.
337 </para> 337 </para>
338 !Edrivers/scsi/scsi_transport_sas.c 338 !Edrivers/scsi/scsi_transport_sas.c
339 </sect2> 339 </sect2>
340 <sect2 id="SATA_transport"> 340 <sect2 id="SATA_transport">
341 <title>SATA transport class</title> 341 <title>SATA transport class</title>
342 <para> 342 <para>
343 The SATA transport is handled by libata, which has its own book of 343 The SATA transport is handled by libata, which has its own book of
344 documentation in this directory. 344 documentation in this directory.
345 </para> 345 </para>
346 </sect2> 346 </sect2>
347 <sect2 id="SPI_transport"> 347 <sect2 id="SPI_transport">
348 <title>Parallel SCSI (SPI) transport class</title> 348 <title>Parallel SCSI (SPI) transport class</title>
349 <para> 349 <para>
350 The file drivers/scsi/scsi_transport_spi.c defines transport 350 The file drivers/scsi/scsi_transport_spi.c defines transport
351 attributes for traditional (fast/wide/ultra) SCSI busses. 351 attributes for traditional (fast/wide/ultra) SCSI busses.
352 </para> 352 </para>
353 !Edrivers/scsi/scsi_transport_spi.c 353 !Edrivers/scsi/scsi_transport_spi.c
354 </sect2> 354 </sect2>
355 <sect2 id="SRP_transport"> 355 <sect2 id="SRP_transport">
356 <title>SCSI RDMA (SRP) transport class</title> 356 <title>SCSI RDMA (SRP) transport class</title>
357 <para> 357 <para>
358 The file drivers/scsi/scsi_transport_srp.c defines transport 358 The file drivers/scsi/scsi_transport_srp.c defines transport
359 attributes for SCSI over Remote Direct Memory Access. 359 attributes for SCSI over Remote Direct Memory Access.
360 </para> 360 </para>
361 !Edrivers/scsi/scsi_transport_srp.c 361 !Edrivers/scsi/scsi_transport_srp.c
362 </sect2> 362 </sect2>
363 </sect1> 363 </sect1>
364 364
365 </chapter> 365 </chapter>
366 366
367 <chapter id="lower_layer"> 367 <chapter id="lower_layer">
368 <title>SCSI lower layer</title> 368 <title>SCSI lower layer</title>
369 <sect1 id="hba_drivers"> 369 <sect1 id="hba_drivers">
370 <title>Host Bus Adapter transport types</title> 370 <title>Host Bus Adapter transport types</title>
371 <para> 371 <para>
372 Many modern device controllers use the SCSI command set as a protocol to 372 Many modern device controllers use the SCSI command set as a protocol to
373 communicate with their devices through many different types of physical 373 communicate with their devices through many different types of physical
374 connections. 374 connections.
375 </para> 375 </para>
376 <para> 376 <para>
377 In SCSI language a bus capable of carrying SCSI commands is 377 In SCSI language a bus capable of carrying SCSI commands is
378 called a "transport", and a controller connecting to such a bus is 378 called a "transport", and a controller connecting to such a bus is
379 called a "host bus adapter" (HBA). 379 called a "host bus adapter" (HBA).
380 </para> 380 </para>
381 <sect2 id="scsi_debug.c"> 381 <sect2 id="scsi_debug.c">
382 <title>Debug transport</title> 382 <title>Debug transport</title>
383 <para> 383 <para>
384 The file drivers/scsi/scsi_debug.c simulates a host adapter with a 384 The file drivers/scsi/scsi_debug.c simulates a host adapter with a
385 variable number of disks (or disk like devices) attached, sharing a 385 variable number of disks (or disk like devices) attached, sharing a
386 common amount of RAM. Does a lot of checking to make sure that we are 386 common amount of RAM. Does a lot of checking to make sure that we are
387 not getting blocks mixed up, and panics the kernel if anything out of 387 not getting blocks mixed up, and panics the kernel if anything out of
388 the ordinary is seen. 388 the ordinary is seen.
389 </para> 389 </para>
390 <para> 390 <para>
391 To be more realistic, the simulated devices have the transport 391 To be more realistic, the simulated devices have the transport
392 attributes of SAS disks. 392 attributes of SAS disks.
393 </para> 393 </para>
394 <para> 394 <para>
395 For documentation see 395 For documentation see
396 <ulink url='http://www.torque.net/sg/sdebug26.html'>http://www.torque.net/sg/sdebug26.html</ulink> 396 <ulink url='http://www.torque.net/sg/sdebug26.html'>http://www.torque.net/sg/sdebug26.html</ulink>
397 </para> 397 </para>
398 <!-- !Edrivers/scsi/scsi_debug.c --> 398 <!-- !Edrivers/scsi/scsi_debug.c -->
399 </sect2> 399 </sect2>
400 <sect2 id="todo"> 400 <sect2 id="todo">
401 <title>todo</title> 401 <title>todo</title>
402 <para>Parallel (fast/wide/ultra) SCSI, USB, SATA, 402 <para>Parallel (fast/wide/ultra) SCSI, USB, SATA,
403 SAS, Fibre Channel, FireWire, ATAPI devices, Infiniband, 403 SAS, Fibre Channel, FireWire, ATAPI devices, Infiniband,
404 I20, iSCSI, Parallel ports, netlink... 404 I20, iSCSI, Parallel ports, netlink...
405 </para> 405 </para>
406 </sect2> 406 </sect2>
407 </sect1> 407 </sect1>
408 </chapter> 408 </chapter>
409 </book> 409 </book>
410 410
Documentation/scsi/ChangeLog.megaraid
1 Release Date : Thu Nov 16 15:32:35 EST 2006 - 1 Release Date : Thu Nov 16 15:32:35 EST 2006 -
2 Sumant Patro <sumant.patro@lsi.com> 2 Sumant Patro <sumant.patro@lsi.com>
3 Current Version : 2.20.5.1 (scsi module), 2.20.2.6 (cmm module) 3 Current Version : 2.20.5.1 (scsi module), 2.20.2.6 (cmm module)
4 Older Version : 2.20.4.9 (scsi module), 2.20.2.6 (cmm module) 4 Older Version : 2.20.4.9 (scsi module), 2.20.2.6 (cmm module)
5 5
6 1. Changes in Initialization to fix kdump failure. 6 1. Changes in Initialization to fix kdump failure.
7 Send SYNC command on loading. 7 Send SYNC command on loading.
8 This command clears the pending commands in the adapter 8 This command clears the pending commands in the adapter
9 and re-initialize its internal RAID structure. 9 and re-initialize its internal RAID structure.
10 Without this change, megaraid driver either panics or fails to 10 Without this change, megaraid driver either panics or fails to
11 initialize the adapter during kdump's second kernel boot 11 initialize the adapter during kdump's second kernel boot
12 if there are pending commands or interrupts from other devices 12 if there are pending commands or interrupts from other devices
13 sharing the same IRQ. 13 sharing the same IRQ.
14 2. Authors email-id domain name changed from lsil.com to lsi.com. 14 2. Authors email-id domain name changed from lsil.com to lsi.com.
15 Also modified the MODULE_AUTHOR to megaraidlinux@lsi.com 15 Also modified the MODULE_AUTHOR to megaraidlinux@lsi.com
16 16
17 Release Date : Fri May 19 09:31:45 EST 2006 - Seokmann Ju <sju@lsil.com> 17 Release Date : Fri May 19 09:31:45 EST 2006 - Seokmann Ju <sju@lsil.com>
18 Current Version : 2.20.4.9 (scsi module), 2.20.2.6 (cmm module) 18 Current Version : 2.20.4.9 (scsi module), 2.20.2.6 (cmm module)
19 Older Version : 2.20.4.8 (scsi module), 2.20.2.6 (cmm module) 19 Older Version : 2.20.4.8 (scsi module), 2.20.2.6 (cmm module)
20 20
21 1. Fixed a bug in megaraid_init_mbox(). 21 1. Fixed a bug in megaraid_init_mbox().
22 Customer reported "garbage in file on x86_64 platform". 22 Customer reported "garbage in file on x86_64 platform".
23 Root Cause: the driver registered controllers as 64-bit DMA capable 23 Root Cause: the driver registered controllers as 64-bit DMA capable
24 for those which are not support it. 24 for those which are not support it.
25 Fix: Made change in the function inserting identification machanism 25 Fix: Made change in the function inserting identification machanism
26 identifying 64-bit DMA capable controllers. 26 identifying 64-bit DMA capable controllers.
27 27
28 > -----Original Message----- 28 > -----Original Message-----
29 > From: Vasily Averin [mailto:vvs@sw.ru] 29 > From: Vasily Averin [mailto:vvs@sw.ru]
30 > Sent: Thursday, May 04, 2006 2:49 PM 30 > Sent: Thursday, May 04, 2006 2:49 PM
31 > To: linux-scsi@vger.kernel.org; Kolli, Neela; Mukker, Atul; 31 > To: linux-scsi@vger.kernel.org; Kolli, Neela; Mukker, Atul;
32 > Ju, Seokmann; Bagalkote, Sreenivas; 32 > Ju, Seokmann; Bagalkote, Sreenivas;
33 > James.Bottomley@SteelEye.com; devel@openvz.org 33 > James.Bottomley@SteelEye.com; devel@openvz.org
34 > Subject: megaraid_mbox: garbage in file 34 > Subject: megaraid_mbox: garbage in file
35 > 35 >
36 > Hello all, 36 > Hello all,
37 > 37 >
38 > I've investigated customers claim on the unstable work of 38 > I've investigated customers claim on the unstable work of
39 > their node and found a 39 > their node and found a
40 > strange effect: reading from some files leads to the 40 > strange effect: reading from some files leads to the
41 > "attempt to access beyond end of device" messages. 41 > "attempt to access beyond end of device" messages.
42 > 42 >
43 > I've checked filesystem, memory on the node, motherboard BIOS 43 > I've checked filesystem, memory on the node, motherboard BIOS
44 > version, but it 44 > version, but it
45 > does not help and issue still has been reproduced by simple 45 > does not help and issue still has been reproduced by simple
46 > file reading. 46 > file reading.
47 > 47 >
48 > Reproducer is simple: 48 > Reproducer is simple:
49 > 49 >
50 > echo 0xffffffff >/proc/sys/dev/scsi/logging_level ; 50 > echo 0xffffffff >/proc/sys/dev/scsi/logging_level ;
51 > cat /vz/private/101/root/etc/ld.so.cache >/tmp/ttt ; 51 > cat /vz/private/101/root/etc/ld.so.cache >/tmp/ttt ;
52 > echo 0 >/proc/sys/dev/scsi/logging 52 > echo 0 >/proc/sys/dev/scsi/logging
53 > 53 >
54 > It leads to the following messages in dmesg 54 > It leads to the following messages in dmesg
55 > 55 >
56 > sd_init_command: disk=sda, block=871769260, count=26 56 > sd_init_command: disk=sda, block=871769260, count=26
57 > sda : block=871769260 57 > sda : block=871769260
58 > sda : reading 26/26 512 byte blocks. 58 > sda : reading 26/26 512 byte blocks.
59 > scsi_add_timer: scmd: f79ed980, time: 7500, (c02b1420) 59 > scsi_add_timer: scmd: f79ed980, time: 7500, (c02b1420)
60 > sd 0:1:0:0: send 0xf79ed980 sd 0:1:0:0: 60 > sd 0:1:0:0: send 0xf79ed980 sd 0:1:0:0:
61 > command: Read (10): 28 00 33 f6 24 ac 00 00 1a 00 61 > command: Read (10): 28 00 33 f6 24 ac 00 00 1a 00
62 > buffer = 0xf7cfb540, bufflen = 13312, done = 0xc0366b40, 62 > buffer = 0xf7cfb540, bufflen = 13312, done = 0xc0366b40,
63 > queuecommand 0xc0344010 63 > queuecommand 0xc0344010
64 > leaving scsi_dispatch_cmnd() 64 > leaving scsi_dispatch_cmnd()
65 > scsi_delete_timer: scmd: f79ed980, rtn: 1 65 > scsi_delete_timer: scmd: f79ed980, rtn: 1
66 > sd 0:1:0:0: done 0xf79ed980 SUCCESS 0 sd 0:1:0:0: 66 > sd 0:1:0:0: done 0xf79ed980 SUCCESS 0 sd 0:1:0:0:
67 > command: Read (10): 28 00 33 f6 24 ac 00 00 1a 00 67 > command: Read (10): 28 00 33 f6 24 ac 00 00 1a 00
68 > scsi host busy 1 failed 0 68 > scsi host busy 1 failed 0
69 > sd 0:1:0:0: Notifying upper driver of completion (result 0) 69 > sd 0:1:0:0: Notifying upper driver of completion (result 0)
70 > sd_rw_intr: sda: res=0x0 70 > sd_rw_intr: sda: res=0x0
71 > 26 sectors total, 13312 bytes done. 71 > 26 sectors total, 13312 bytes done.
72 > use_sg is 4 72 > use_sg is 4
73 > attempt to access beyond end of device 73 > attempt to access beyond end of device
74 > sda6: rw=0, want=1044134458, limit=951401367 74 > sda6: rw=0, want=1044134458, limit=951401367
75 > Buffer I/O error on device sda6, logical block 522067228 75 > Buffer I/O error on device sda6, logical block 522067228
76 > attempt to access beyond end of device 76 > attempt to access beyond end of device
77 77
78 2. When INQUIRY with EVPD bit set issued to the MegaRAID controller, 78 2. When INQUIRY with EVPD bit set issued to the MegaRAID controller,
79 system memory gets corrupted. 79 system memory gets corrupted.
80 Root Cause: MegaRAID F/W handle the INQUIRY with EVPD bit set 80 Root Cause: MegaRAID F/W handle the INQUIRY with EVPD bit set
81 incorrectly. 81 incorrectly.
82 Fix: MegaRAID F/W has fixed the problem and being process of release, 82 Fix: MegaRAID F/W has fixed the problem and being process of release,
83 soon. Meanwhile, driver will filter out the request. 83 soon. Meanwhile, driver will filter out the request.
84 84
85 3. One of member in the data structure of the driver leads unaligne 85 3. One of member in the data structure of the driver leads unaligne
86 issue on 64-bit platform. 86 issue on 64-bit platform.
87 Customer reporeted "kernel unaligned access addrss" issue when 87 Customer reporeted "kernel unaligned access addrss" issue when
88 application communicates with MegaRAID HBA driver. 88 application communicates with MegaRAID HBA driver.
89 Root Cause: in uioc_t structure, one of member had misaligned and it 89 Root Cause: in uioc_t structure, one of member had misaligned and it
90 led system to display the error message. 90 led system to display the error message.
91 Fix: A patch submitted to community from following folk. 91 Fix: A patch submitted to community from following folk.
92 92
93 > -----Original Message----- 93 > -----Original Message-----
94 > From: linux-scsi-owner@vger.kernel.org 94 > From: linux-scsi-owner@vger.kernel.org
95 > [mailto:linux-scsi-owner@vger.kernel.org] On Behalf Of Sakurai Hiroomi 95 > [mailto:linux-scsi-owner@vger.kernel.org] On Behalf Of Sakurai Hiroomi
96 > Sent: Wednesday, July 12, 2006 4:20 AM 96 > Sent: Wednesday, July 12, 2006 4:20 AM
97 > To: linux-scsi@vger.kernel.org; linux-kernel@vger.kernel.org 97 > To: linux-scsi@vger.kernel.org; linux-kernel@vger.kernel.org
98 > Subject: Re: Help: strange messages from kernel on IA64 platform 98 > Subject: Re: Help: strange messages from kernel on IA64 platform
99 > 99 >
100 > Hi, 100 > Hi,
101 > 101 >
102 > I saw same message. 102 > I saw same message.
103 > 103 >
104 > When GAM(Global Array Manager) is started, The following 104 > When GAM(Global Array Manager) is started, The following
105 > message output. 105 > message output.
106 > kernel: kernel unaligned access to 0xe0000001fe1080d4, 106 > kernel: kernel unaligned access to 0xe0000001fe1080d4,
107 > ip=0xa000000200053371 107 > ip=0xa000000200053371
108 > 108 >
109 > The uioc structure used by ioctl is defined by packed, 109 > The uioc structure used by ioctl is defined by packed,
110 > the allignment of each member are disturbed. 110 > the allignment of each member are disturbed.
111 > In a 64 bit structure, the allignment of member doesn't fit 64 bit 111 > In a 64 bit structure, the allignment of member doesn't fit 64 bit
112 > boundary. this causes this messages. 112 > boundary. this causes this messages.
113 > In a 32 bit structure, we don't see the message because the allinment 113 > In a 32 bit structure, we don't see the message because the allinment
114 > of member fit 32 bit boundary even if packed is specified. 114 > of member fit 32 bit boundary even if packed is specified.
115 > 115 >
116 > patch 116 > patch
117 > I Add 32 bit dummy member to fit 64 bit boundary. I tested. 117 > I Add 32 bit dummy member to fit 64 bit boundary. I tested.
118 > We confirmed this patch fix the problem by IA64 server. 118 > We confirmed this patch fix the problem by IA64 server.
119 > 119 >
120 > ************************************************************** 120 > **************************************************************
121 > **************** 121 > ****************
122 > --- linux-2.6.9/drivers/scsi/megaraid/megaraid_ioctl.h.orig 122 > --- linux-2.6.9/drivers/scsi/megaraid/megaraid_ioctl.h.orig
123 > 2006-04-03 17:13:03.000000000 +0900 123 > 2006-04-03 17:13:03.000000000 +0900
124 > +++ linux-2.6.9/drivers/scsi/megaraid/megaraid_ioctl.h 124 > +++ linux-2.6.9/drivers/scsi/megaraid/megaraid_ioctl.h
125 > 2006-04-03 17:14:09.000000000 +0900 125 > 2006-04-03 17:14:09.000000000 +0900
126 > @@ -132,6 +132,10 @@ 126 > @@ -132,6 +132,10 @@
127 > /* Driver Data: */ 127 > /* Driver Data: */
128 > void __user * user_data; 128 > void __user * user_data;
129 > uint32_t user_data_len; 129 > uint32_t user_data_len;
130 > + 130 > +
131 > + /* 64bit alignment */ 131 > + /* 64bit alignment */
132 > + uint32_t pad_0xBC; 132 > + uint32_t pad_0xBC;
133 > + 133 > +
134 > mraid_passthru_t __user *user_pthru; 134 > mraid_passthru_t __user *user_pthru;
135 > 135 >
136 > mraid_passthru_t *pthru32; 136 > mraid_passthru_t *pthru32;
137 > ************************************************************** 137 > **************************************************************
138 > **************** 138 > ****************
139 139
140 Release Date : Mon Apr 11 12:27:22 EST 2006 - Seokmann Ju <sju@lsil.com> 140 Release Date : Mon Apr 11 12:27:22 EST 2006 - Seokmann Ju <sju@lsil.com>
141 Current Version : 2.20.4.8 (scsi module), 2.20.2.6 (cmm module) 141 Current Version : 2.20.4.8 (scsi module), 2.20.2.6 (cmm module)
142 Older Version : 2.20.4.7 (scsi module), 2.20.2.6 (cmm module) 142 Older Version : 2.20.4.7 (scsi module), 2.20.2.6 (cmm module)
143 143
144 1. Fixed a bug in megaraid_reset_handler(). 144 1. Fixed a bug in megaraid_reset_handler().
145 Customer reported "Unable to handle kernel NULL pointer dereference 145 Customer reported "Unable to handle kernel NULL pointer dereference
146 at virtual address 00000000" when system goes to reset condition 146 at virtual address 00000000" when system goes to reset condition
147 for some reason. It happened randomly. 147 for some reason. It happened randomly.
148 Root Cause: in the megaraid_reset_handler(), there is possibility not 148 Root Cause: in the megaraid_reset_handler(), there is possibility not
149 returning pending packets in the pend_list if there are multiple 149 returning pending packets in the pend_list if there are multiple
150 pending packets. 150 pending packets.
151 Fix: Made the change in the driver so that it will return all packets 151 Fix: Made the change in the driver so that it will return all packets
152 in the pend_list. 152 in the pend_list.
153 153
154 2. Added change request. 154 2. Added change request.
155 As found in the following URL, rmb() only didn't help the 155 As found in the following URL, rmb() only didn't help the
156 problem. I had to increase the loop counter to 0xFFFFFF. (6 F's) 156 problem. I had to increase the loop counter to 0xFFFFFF. (6 F's)
157 http://marc.theaimsgroup.com/?l=linux-scsi&m=110971060502497&w=2 157 http://marc.theaimsgroup.com/?l=linux-scsi&m=110971060502497&w=2
158 158
159 I attached a patch for your reference, too. 159 I attached a patch for your reference, too.
160 Could you check and get this fix in your driver? 160 Could you check and get this fix in your driver?
161 161
162 Best Regards, 162 Best Regards,
163 Jun'ichi Nomura 163 Jun'ichi Nomura
164 164
165 Release Date : Fri Nov 11 12:27:22 EST 2005 - Seokmann Ju <sju@lsil.com> 165 Release Date : Fri Nov 11 12:27:22 EST 2005 - Seokmann Ju <sju@lsil.com>
166 Current Version : 2.20.4.7 (scsi module), 2.20.2.6 (cmm module) 166 Current Version : 2.20.4.7 (scsi module), 2.20.2.6 (cmm module)
167 Older Version : 2.20.4.6 (scsi module), 2.20.2.6 (cmm module) 167 Older Version : 2.20.4.6 (scsi module), 2.20.2.6 (cmm module)
168 168
169 1. Sorted out PCI IDs to remove megaraid support overlaps. 169 1. Sorted out PCI IDs to remove megaraid support overlaps.
170 Based on the patch from Daniel, sorted out PCI IDs along with 170 Based on the patch from Daniel, sorted out PCI IDs along with
171 charactor node name change from 'megadev' to 'megadev_legacy' to avoid 171 charactor node name change from 'megadev' to 'megadev_legacy' to avoid
172 conflict. 172 conflict.
173 --- 173 ---
174 Hopefully we'll be getting the build restriction zapped much sooner, 174 Hopefully we'll be getting the build restriction zapped much sooner,
175 but we should also be thinking about totally removing the hardware 175 but we should also be thinking about totally removing the hardware
176 support overlap in the megaraid drivers. 176 support overlap in the megaraid drivers.
177 177
178 This patch pencils in a date of Feb 06 for this, and performs some 178 This patch pencils in a date of Feb 06 for this, and performs some
179 printk abuse in hope that existing legacy users might pick up on what's 179 printk abuse in hope that existing legacy users might pick up on what's
180 going on. 180 going on.
181 181
182 Signed-off-by: Daniel Drake <dsd@gentoo.org> 182 Signed-off-by: Daniel Drake <dsd@gentoo.org>
183 --- 183 ---
184 184
185 2. Fixed a issue: megaraid always fails to reset handler. 185 2. Fixed a issue: megaraid always fails to reset handler.
186 --- 186 ---
187 I found that the megaraid driver always fails to reset the 187 I found that the megaraid driver always fails to reset the
188 adapter with the following message: 188 adapter with the following message:
189 megaraid: resetting the host... 189 megaraid: resetting the host...
190 megaraid mbox: reset sequence completed successfully 190 megaraid mbox: reset sequence completed successfully
191 megaraid: fast sync command timed out 191 megaraid: fast sync command timed out
192 megaraid: reservation reset failed 192 megaraid: reservation reset failed
193 when the "Cluster mode" of the adapter BIOS is enabled. 193 when the "Cluster mode" of the adapter BIOS is enabled.
194 So, whenever the reset occurs, the adapter goes to 194 So, whenever the reset occurs, the adapter goes to
195 offline and just become unavailable. 195 offline and just become unavailable.
196 196
197 Jun'ichi Nomura [mailto:jnomura@mtc.biglobe.ne.jp] 197 Jun'ichi Nomura [mailto:jnomura@mtc.biglobe.ne.jp]
198 --- 198 ---
199 199
200 Release Date : Mon Mar 07 12:27:22 EST 2005 - Seokmann Ju <sju@lsil.com> 200 Release Date : Mon Mar 07 12:27:22 EST 2005 - Seokmann Ju <sju@lsil.com>
201 Current Version : 2.20.4.6 (scsi module), 2.20.2.6 (cmm module) 201 Current Version : 2.20.4.6 (scsi module), 2.20.2.6 (cmm module)
202 Older Version : 2.20.4.5 (scsi module), 2.20.2.5 (cmm module) 202 Older Version : 2.20.4.5 (scsi module), 2.20.2.5 (cmm module)
203 203
204 1. Added IOCTL backward compatibility. 204 1. Added IOCTL backward compatibility.
205 Convert megaraid_mm driver to new compat_ioctl entry points. 205 Convert megaraid_mm driver to new compat_ioctl entry points.
206 I don't have easy access to hardware, so only compile tested. 206 I don't have easy access to hardware, so only compile tested.
207 - Signed-off-by:Andi Kleen <ak@muc.de> 207 - Signed-off-by:Andi Kleen <ak@muc.de>
208 208
209 2. megaraid_mbox fix: wrong order of arguments in memset() 209 2. megaraid_mbox fix: wrong order of arguments in memset()
210 That, BTW, shows why cross-builds are useful-the only indication of 210 That, BTW, shows why cross-builds are useful-the only indication of
211 problem had been a new warning showing up in sparse output on alpha 211 problem had been a new warning showing up in sparse output on alpha
212 build (number of exceeding 256 got truncated). 212 build (number of exceeding 256 got truncated).
213 - Signed-off-by: Al Viro 213 - Signed-off-by: Al Viro
214 <viro@parcelfarce.linux.theplanet.co.uk> 214 <viro@parcelfarce.linux.theplanet.co.uk>
215 215
216 3. Convert pci_module_init to pci_register_driver 216 3. Convert pci_module_init to pci_register_driver
217 Convert from pci_module_init to pci_register_driver 217 Convert from pci_module_init to pci_register_driver
218 (from:http://kerneljanitors.org/TODO) 218 (from:http://kerneljanitors.org/TODO)
219 - Signed-off-by: Domen Puncer <domen@coderock.org> 219 - Signed-off-by: Domen Puncer <domen@coderock.org>
220 220
221 4. Use the pre defined DMA mask constants from dma-mapping.h 221 4. Use the pre defined DMA mask constants from dma-mapping.h
222 Use the DMA_{64,32}BIT_MASK constants from dma-mapping.h when calling 222 Use the DMA_{64,32}BIT_MASK constants from dma-mapping.h when calling
223 pci_set_dma_mask() or pci_set_consistend_dma_mask(). See 223 pci_set_dma_mask() or pci_set_consistend_dma_mask(). See
224 http://marc.theaimsgroup.com/?t=108001993000001&r=1&w=2 for more 224 http://marc.theaimsgroup.com/?t=108001993000001&r=1&w=2 for more
225 details. 225 details.
226 Signed-off-by: Tobias Klauser <tklauser@nuerscht.ch> 226 Signed-off-by: Tobias Klauser <tklauser@nuerscht.ch>
227 Signed-off-by: Domen Puncer <domen@coderock.org> 227 Signed-off-by: Domen Puncer <domen@coderock.org>
228 228
229 5. Remove SSID checking for Dobson, Lindsay, and Verde based products. 229 5. Remove SSID checking for Dobson, Lindsay, and Verde based products.
230 Checking the SSVID/SSID for controllers which have Dobson, Lindsay, 230 Checking the SSVID/SSID for controllers which have Dobson, Lindsay,
231 and Verde is unnecessary because device ID has been assigned by LSI 231 and Verde is unnecessary because device ID has been assigned by LSI
232 and it is unique value. So, all controllers with these IOPs have to be 232 and it is unique value. So, all controllers with these IOPs have to be
233 supported by the driver regardless SSVID/SSID. 233 supported by the driver regardless SSVID/SSID.
234 234
235 6. Date Thu, 27 Jan 2005 04:31:09 +0100 235 6. Date Thu, 27 Jan 2005 04:31:09 +0100
236 From Herbert Poetzl <> 236 From Herbert Poetzl <>
237 Subject RFC: assert_spin_locked() for 2.6 237 Subject RFC: assert_spin_locked() for 2.6
238 238
239 Greetings! 239 Greetings!
240 240
241 overcautious programming will kill your kernel ;) 241 overcautious programming will kill your kernel ;)
242 ever thought about checking a spin_lock or even 242 ever thought about checking a spin_lock or even
243 asserting that it must be held (maybe just for 243 asserting that it must be held (maybe just for
244 spinlock debugging?) ... 244 spinlock debugging?) ...
245 245
246 there are several checks present in the kernel 246 there are several checks present in the kernel
247 where somebody does a variation on the following: 247 where somebody does a variation on the following:
248 248
249 BUG_ON(!spin_is_locked(&some_lock)); 249 BUG_ON(!spin_is_locked(&some_lock));
250 250
251 so what's wrong about that? nothing, unless you 251 so what's wrong about that? nothing, unless you
252 compile the code with CONFIG_DEBUG_SPINLOCK but 252 compile the code with CONFIG_DEBUG_SPINLOCK but
253 without CONFIG_SMP ... in which case the BUG() 253 without CONFIG_SMP ... in which case the BUG()
254 will kill your kernel ... 254 will kill your kernel ...
255 255
256 maybe it's not advised to make such assertions, 256 maybe it's not advised to make such assertions,
257 but here is a solution which works for me ... 257 but here is a solution which works for me ...
258 (compile tested for sh, x86_64 and x86, boot/run 258 (compile tested for sh, x86_64 and x86, boot/run
259 tested for x86 only) 259 tested for x86 only)
260 260
261 best, 261 best,
262 Herbert 262 Herbert
263 263
264 - Herbert Poetzl <herbert@13thfloor.at>, Thu, 27 Jan 2005 264 - Herbert Poetzl <herbert@13thfloor.at>, Thu, 27 Jan 2005
265 265
266 Release Date : Thu Feb 03 12:27:22 EST 2005 - Seokmann Ju <sju@lsil.com> 266 Release Date : Thu Feb 03 12:27:22 EST 2005 - Seokmann Ju <sju@lsil.com>
267 Current Version : 2.20.4.5 (scsi module), 2.20.2.5 (cmm module) 267 Current Version : 2.20.4.5 (scsi module), 2.20.2.5 (cmm module)
268 Older Version : 2.20.4.4 (scsi module), 2.20.2.4 (cmm module) 268 Older Version : 2.20.4.4 (scsi module), 2.20.2.4 (cmm module)
269 269
270 1. Modified name of two attributes in scsi_host_template. 270 1. Modified name of two attributes in scsi_host_template.
271 On Wed, 2005-02-02 at 10:56 -0500, Ju, Seokmann wrote: 271 On Wed, 2005-02-02 at 10:56 -0500, Ju, Seokmann wrote:
272 > + .sdev_attrs = megaraid_device_attrs, 272 > + .sdev_attrs = megaraid_device_attrs,
273 > + .shost_attrs = megaraid_class_device_attrs, 273 > + .shost_attrs = megaraid_class_device_attrs,
274 274
275 These are, perhaps, slightly confusing names. 275 These are, perhaps, slightly confusing names.
276 The terms device and class_device have well defined meanings in the 276 The terms device and class_device have well defined meanings in the
277 generic device model, neither of which is what you mean here. 277 generic device model, neither of which is what you mean here.
278 Why not simply megaraid_sdev_attrs and megaraid_shost_attrs? 278 Why not simply megaraid_sdev_attrs and megaraid_shost_attrs?
279 279
280 Other than this, it looks fine to me too. 280 Other than this, it looks fine to me too.
281 281
282 Release Date : Thu Jan 27 00:01:03 EST 2005 - Atul Mukker <atulm@lsil.com> 282 Release Date : Thu Jan 27 00:01:03 EST 2005 - Atul Mukker <atulm@lsil.com>
283 Current Version : 2.20.4.4 (scsi module), 2.20.2.5 (cmm module) 283 Current Version : 2.20.4.4 (scsi module), 2.20.2.5 (cmm module)
284 Older Version : 2.20.4.3 (scsi module), 2.20.2.4 (cmm module) 284 Older Version : 2.20.4.3 (scsi module), 2.20.2.4 (cmm module)
285 285
286 1. Bump up the version of scsi module due to its conflict. 286 1. Bump up the version of scsi module due to its conflict.
287 287
288 Release Date : Thu Jan 21 00:01:03 EST 2005 - Atul Mukker <atulm@lsil.com> 288 Release Date : Thu Jan 21 00:01:03 EST 2005 - Atul Mukker <atulm@lsil.com>
289 Current Version : 2.20.4.3 (scsi module), 2.20.2.5 (cmm module) 289 Current Version : 2.20.4.3 (scsi module), 2.20.2.5 (cmm module)
290 Older Version : 2.20.4.2 (scsi module), 2.20.2.4 (cmm module) 290 Older Version : 2.20.4.2 (scsi module), 2.20.2.4 (cmm module)
291 291
292 1. Remove driver ioctl for logical drive to scsi address translation and 292 1. Remove driver ioctl for logical drive to scsi address translation and
293 replace with the sysfs attribute. To remove drives and change 293 replace with the sysfs attribute. To remove drives and change
294 capacity, application shall now use the device attribute to get the 294 capacity, application shall now use the device attribute to get the
295 logical drive number for a scsi device. For adding newly created 295 logical drive number for a scsi device. For adding newly created
296 logical drives, class device attribute would be required to uniquely 296 logical drives, class device attribute would be required to uniquely
297 identify each controller. 297 identify each controller.
298 - Atul Mukker <atulm@lsil.com> 298 - Atul Mukker <atulm@lsil.com>
299 299
300 "James, I've been thinking about this a little more, and you may be on 300 "James, I've been thinking about this a little more, and you may be on
301 to something here. Let each driver add files as such:" 301 to something here. Let each driver add files as such:"
302 302
303 - Matt Domsch <Matt_Domsch@dell.com>, 12.15.2004 303 - Matt Domsch <Matt_Domsch@dell.com>, 12.15.2004
304 linux-scsi mailing list 304 linux-scsi mailing list
305 305
306 306
307 "Then, if you simply publish your LD number as an extra parameter of 307 "Then, if you simply publish your LD number as an extra parameter of
308 the device, you can look through /sys to find it." 308 the device, you can look through /sys to find it."
309 309
310 - James Bottomley <James.Bottomley@SteelEye.com>, 01.03.2005 310 - James Bottomley <James.Bottomley@SteelEye.com>, 01.03.2005
311 linux-scsi mailing list 311 linux-scsi mailing list
312 312
313 313
314 "I don't see why not ... it's your driver, you can publish whatever 314 "I don't see why not ... it's your driver, you can publish whatever
315 extra information you need as scsi_device attributes; that was one of 315 extra information you need as scsi_device attributes; that was one of
316 the designs of the extensible attribute system." 316 the designs of the extensible attribute system."
317 317
318 - James Bottomley <James.Bottomley@SteelEye.com>, 01.06.2005 318 - James Bottomley <James.Bottomley@SteelEye.com>, 01.06.2005
319 linux-scsi mailing list 319 linux-scsi mailing list
320 320
321 2. Add AMI megaraid support - Brian King <brking@charter.net> 321 2. Add AMI megaraid support - Brian King <brking@charter.net>
322 PCI_VENDOR_ID_AMI, PCI_DEVICE_ID_AMI_MEGARAID3, 322 PCI_VENDOR_ID_AMI, PCI_DEVICE_ID_AMI_MEGARAID3,
323 PCI_VENDOR_ID_AMI, PCI_SUBSYS_ID_PERC3_DC, 323 PCI_VENDOR_ID_AMI, PCI_SUBSYS_ID_PERC3_DC,
324 324
325 3. Make some code static - Adrian Bunk <bunk@stusta.de> 325 3. Make some code static - Adrian Bunk <bunk@stusta.de>
326 Date: Mon, 15 Nov 2004 03:14:57 +0100 326 Date: Mon, 15 Nov 2004 03:14:57 +0100
327 327
328 The patch below makes some needlessly global code static. 328 The patch below makes some needlessly global code static.
329 -wait_queue_head_t wait_q; 329 -wait_queue_head_t wait_q;
330 +static wait_queue_head_t wait_q; 330 +static wait_queue_head_t wait_q;
331 331
332 Signed-off-by: Adrian Bunk <bunk@stusta.de> 332 Signed-off-by: Adrian Bunk <bunk@stusta.de>
333 333
334 4. Added NEC ROMB support - NEC MegaRAID PCI Express ROMB controller 334 4. Added NEC ROMB support - NEC MegaRAID PCI Express ROMB controller
335 PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_MEGARAID_NEC_ROMB_2E, 335 PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_MEGARAID_NEC_ROMB_2E,
336 PCI_SUBSYS_ID_NEC, PCI_SUBSYS_ID_MEGARAID_NEC_ROMB_2E, 336 PCI_SUBSYS_ID_NEC, PCI_SUBSYS_ID_MEGARAID_NEC_ROMB_2E,
337 337
338 5. Fixed Tape drive issue : For any Direct CDB command to physical device 338 5. Fixed Tape drive issue : For any Direct CDB command to physical device
339 including tape, timeout value set by driver was 10 minutes. With this 339 including tape, timeout value set by driver was 10 minutes. With this
340 value, most of command will return within timeout. However, for those 340 value, most of command will return within timeout. However, for those
341 command like ERASE or FORMAT, it takes more than an hour depends on 341 command like ERASE or FORMAT, it takes more than an hour depends on
342 capacity of the device and the command could be terminated before it 342 capacity of the device and the command could be terminated before it
343 completes. 343 completes.
344 To address this issue, the 'timeout' field in the DCDB command will 344 To address this issue, the 'timeout' field in the DCDB command will
345 have NO TIMEOUT (i.e., 4) value as its timeout on DCDB command. 345 have NO TIMEOUT (i.e., 4) value as its timeout on DCDB command.
346 346
347 347
348 348
349 Release Date : Thu Dec 9 19:10:23 EST 2004 349 Release Date : Thu Dec 9 19:10:23 EST 2004
350 - Sreenivas Bagalkote <sreenib@lsil.com> 350 - Sreenivas Bagalkote <sreenib@lsil.com>
351 351
352 Current Version : 2.20.4.2 (scsi module), 2.20.2.4 (cmm module) 352 Current Version : 2.20.4.2 (scsi module), 2.20.2.4 (cmm module)
353 Older Version : 2.20.4.1 (scsi module), 2.20.2.3 (cmm module) 353 Older Version : 2.20.4.1 (scsi module), 2.20.2.3 (cmm module)
354 354
355 i. Introduced driver ioctl that returns scsi address for a given ld. 355 i. Introduced driver ioctl that returns scsi address for a given ld.
356 356
357 "Why can't the existing sysfs interfaces be used to do this?" 357 "Why can't the existing sysfs interfaces be used to do this?"
358 - Brian King (brking@us.ibm.com) 358 - Brian King (brking@us.ibm.com)
359 359
360 "I've looked into solving this another way, but I cannot see how 360 "I've looked into solving this another way, but I cannot see how
361 to get this driver-private mapping of logical drive number-> HCTL 361 to get this driver-private mapping of logical drive number-> HCTL
362 without putting code something like this into the driver." 362 without putting code something like this into the driver."
363 363
364 "...and by providing a mapping a function to userspace, the driver 364 "...and by providing a mapping a function to userspace, the driver
365 is free to change its mapping algorithm in the future if necessary .." 365 is free to change its mapping algorithm in the future if necessary .."
366 - Matt Domsch (Matt_Domsch@dell.com) 366 - Matt Domsch (Matt_Domsch@dell.com)
367 367
368 Release Date : Thu Dec 9 19:02:14 EST 2004 - Sreenivas Bagalkote <sreenib@lsil.com> 368 Release Date : Thu Dec 9 19:02:14 EST 2004 - Sreenivas Bagalkote <sreenib@lsil.com>
369 369
370 Current Version : 2.20.4.1 (scsi module), 2.20.2.3 (cmm module) 370 Current Version : 2.20.4.1 (scsi module), 2.20.2.3 (cmm module)
371 Older Version : 2.20.4.1 (scsi module), 2.20.2.2 (cmm module) 371 Older Version : 2.20.4.1 (scsi module), 2.20.2.2 (cmm module)
372 372
373 i. Fix a bug in kioc's dma buffer deallocation 373 i. Fix a bug in kioc's dma buffer deallocation
374 374
375 Release Date : Thu Nov 4 18:24:56 EST 2004 - Sreenivas Bagalkote <sreenib@lsil.com> 375 Release Date : Thu Nov 4 18:24:56 EST 2004 - Sreenivas Bagalkote <sreenib@lsil.com>
376 376
377 Current Version : 2.20.4.1 (scsi module), 2.20.2.2 (cmm module) 377 Current Version : 2.20.4.1 (scsi module), 2.20.2.2 (cmm module)
378 Older Version : 2.20.4.0 (scsi module), 2.20.2.1 (cmm module) 378 Older Version : 2.20.4.0 (scsi module), 2.20.2.1 (cmm module)
379 379
380 i. Handle IOCTL cmd timeouts more properly. 380 i. Handle IOCTL cmd timeouts more properly.
381 381
382 ii. pci_dma_sync_{sg,single}_for_cpu was introduced into megaraid_mbox 382 ii. pci_dma_sync_{sg,single}_for_cpu was introduced into megaraid_mbox
383 incorrectly (instead of _for_device). Changed to appropriate 383 incorrectly (instead of _for_device). Changed to appropriate
384 pci_dma_sync_{sg,single}_for_device. 384 pci_dma_sync_{sg,single}_for_device.
385 385
386 Release Date : Wed Oct 06 11:15:29 EDT 2004 - Sreenivas Bagalkote <sreenib@lsil.com> 386 Release Date : Wed Oct 06 11:15:29 EDT 2004 - Sreenivas Bagalkote <sreenib@lsil.com>
387 Current Version : 2.20.4.0 (scsi module), 2.20.2.1 (cmm module) 387 Current Version : 2.20.4.0 (scsi module), 2.20.2.1 (cmm module)
388 Older Version : 2.20.4.0 (scsi module), 2.20.2.0 (cmm module) 388 Older Version : 2.20.4.0 (scsi module), 2.20.2.0 (cmm module)
389 389
390 i. Remove CONFIG_COMPAT around register_ioctl32_conversion 390 i. Remove CONFIG_COMPAT around register_ioctl32_conversion
391 391
392 Release Date : Mon Sep 27 22:15:07 EDT 2004 - Atul Mukker <atulm@lsil.com> 392 Release Date : Mon Sep 27 22:15:07 EDT 2004 - Atul Mukker <atulm@lsil.com>
393 Current Version : 2.20.4.0 (scsi module), 2.20.2.0 (cmm module) 393 Current Version : 2.20.4.0 (scsi module), 2.20.2.0 (cmm module)
394 Older Version : 2.20.3.1 (scsi module), 2.20.2.0 (cmm module) 394 Older Version : 2.20.3.1 (scsi module), 2.20.2.0 (cmm module)
395 395
396 i. Fix data corruption. Because of a typo in the driver, the IO packets 396 i. Fix data corruption. Because of a typo in the driver, the IO packets
397 were wrongly shared by the ioctl path. This causes a whole IO command 397 were wrongly shared by the ioctl path. This causes a whole IO command
398 to be replaced by an incoming ioctl command. 398 to be replaced by an incoming ioctl command.
399 399
400 Release Date : Tue Aug 24 09:43:35 EDT 2004 - Atul Mukker <atulm@lsil.com> 400 Release Date : Tue Aug 24 09:43:35 EDT 2004 - Atul Mukker <atulm@lsil.com>
401 Current Version : 2.20.3.1 (scsi module), 2.20.2.0 (cmm module) 401 Current Version : 2.20.3.1 (scsi module), 2.20.2.0 (cmm module)
402 Older Version : 2.20.3.0 (scsi module), 2.20.2.0 (cmm module) 402 Older Version : 2.20.3.0 (scsi module), 2.20.2.0 (cmm module)
403 403
404 i. Function reordering so that inline functions are defined before they 404 i. Function reordering so that inline functions are defined before they
405 are actually used. It is now mandatory for GCC 3.4.1 (current stable) 405 are actually used. It is now mandatory for GCC 3.4.1 (current stable)
406 406
407 Declare some heavy-weight functions to be non-inlined, 407 Declare some heavy-weight functions to be non-inlined,
408 megaraid_mbox_build_cmd, megaraid_mbox_runpendq, 408 megaraid_mbox_build_cmd, megaraid_mbox_runpendq,
409 megaraid_mbox_prepare_pthru, megaraid_mbox_prepare_epthru, 409 megaraid_mbox_prepare_pthru, megaraid_mbox_prepare_epthru,
410 megaraid_busywait_mbox 410 megaraid_busywait_mbox
411 411
412 - Andrew Morton, 08.19.2004 412 - Andrew Morton, 08.19.2004
413 linux-scsi mailing list 413 linux-scsi mailing list
414 414
415 "Something else to clean up after inclusion: every instance of an 415 "Something else to clean up after inclusion: every instance of an
416 inline function is actually rendered as a full function call, because 416 inline function is actually rendered as a full function call, because
417 the function is always used before it is defined. Atul, please 417 the function is always used before it is defined. Atul, please
418 re-arrange the code to eliminate the need for most (all) of the 418 re-arrange the code to eliminate the need for most (all) of the
419 function prototypes at the top of each file, and define (not just 419 function prototypes at the top of each file, and define (not just
420 declare with a prototype) each inline function before its first use" 420 declare with a prototype) each inline function before its first use"
421 421
422 - Matt Domsch <Matt_Domsch@dell.com>, 07.27.2004 422 - Matt Domsch <Matt_Domsch@dell.com>, 07.27.2004
423 linux-scsi mailing list 423 linux-scsi mailing list
424 424
425 425
426 ii. Display elapsed time (countdown) while waiting for FW to boot. 426 ii. Display elapsed time (countdown) while waiting for FW to boot.
427 427
428 iii. Module compilation reorder in Makefile so that unresolved symbols do 428 iii. Module compilation reorder in Makefile so that unresolved symbols do
429 not occur when driver is compiled non-modular. 429 not occur when driver is compiled non-modular.
430 430
431 Patrick J. LoPresti <patl@users.sourceforge.net>, 8.22.2004 431 Patrick J. LoPresti <patl@users.sourceforge.net>, 8.22.2004
432 linux-scsi mailing list 432 linux-scsi mailing list
433 433
434 434
435 Release Date : Thu Aug 19 09:58:33 EDT 2004 - Atul Mukker <atulm@lsil.com> 435 Release Date : Thu Aug 19 09:58:33 EDT 2004 - Atul Mukker <atulm@lsil.com>
436 Current Version : 2.20.3.0 (scsi module), 2.20.2.0 (cmm module) 436 Current Version : 2.20.3.0 (scsi module), 2.20.2.0 (cmm module)
437 Older Version : 2.20.2.0 (scsi module), 2.20.1.0 (cmm module) 437 Older Version : 2.20.2.0 (scsi module), 2.20.1.0 (cmm module)
438 438
439 i. When copying the mailbox packets, copy only first 14 bytes (for 32-bit 439 i. When copying the mailbox packets, copy only first 14 bytes (for 32-bit
440 mailboxes) and only first 22 bytes (for 64-bit mailboxes). This is to 440 mailboxes) and only first 22 bytes (for 64-bit mailboxes). This is to
441 avoid getting the stale values for busy bit. We want to set the busy 441 avoid getting the stale values for busy bit. We want to set the busy
442 bit just before issuing command to the FW. 442 bit just before issuing command to the FW.
443 443
444 ii. In the reset handling, if the reseted command is not owned by the 444 ii. In the reset handling, if the reseted command is not owned by the
445 driver, do not (wrongly) print information for the "attached" driver 445 driver, do not (wrongly) print information for the "attached" driver
446 packet. 446 packet.
447 447
448 iii. Have extended wait when issuing command in synchronous mode. This is 448 iii. Have extended wait when issuing command in synchronous mode. This is
449 required for the cases where the option ROM is disabled and there is 449 required for the cases where the option ROM is disabled and there is
450 no BIOS to start the controller. The FW starts to boot after receiving 450 no BIOS to start the controller. The FW starts to boot after receiving
451 the first command from the driver. The current driver has 1 second 451 the first command from the driver. The current driver has 1 second
452 timeout for the synchronous commands, which is far less than what is 452 timeout for the synchronous commands, which is far less than what is
453 actually required. We now wait up to MBOX_RESET_TIME (180 seconds) for 453 actually required. We now wait up to MBOX_RESET_TIME (180 seconds) for
454 FW boot process. 454 FW boot process.
455 455
456 iv. In megaraid_mbox_product_info, clear the mailbox contents completely 456 iv. In megaraid_mbox_product_info, clear the mailbox contents completely
457 before preparing the command for inquiry3. This is to ensure that the 457 before preparing the command for inquiry3. This is to ensure that the
458 FW does not get junk values in the command. 458 FW does not get junk values in the command.
459 459
460 v. Do away with the redundant LSI_CONFIG_COMPAT redefinition for 460 v. Do away with the redundant LSI_CONFIG_COMPAT redefinition for
461 CONFIG_COMPAT. Replace <asm/ioctl32.h> with <linux/ioctl32.h> 461 CONFIG_COMPAT. Replace <asm/ioctl32.h> with <linux/ioctl32.h>
462 462
463 - James Bottomley <James.Bottomley@SteelEye.com>, 08.17.2004 463 - James Bottomley <James.Bottomley@SteelEye.com>, 08.17.2004
464 linux-scsi mailing list 464 linux-scsi mailing list
465 465
466 vi. Add support for 64-bit applications. Current drivers assume only 466 vi. Add support for 64-bit applications. Current drivers assume only
467 32-bit applications, even on 64-bit platforms. Use the "data" and 467 32-bit applications, even on 64-bit platforms. Use the "data" and
468 "buffer" fields of the mimd_t structure, instead of embedded 32-bit 468 "buffer" fields of the mimd_t structure, instead of embedded 32-bit
469 addresses in application mailbox and passthru structures. 469 addresses in application mailbox and passthru structures.
470 470
471 vii. Move the function declarations for the management module from 471 vii. Move the function declarations for the management module from
472 megaraid_mm.h to megaraid_mm.c 472 megaraid_mm.h to megaraid_mm.c
473 473
474 - Andrew Morton, 08.19.2004 474 - Andrew Morton, 08.19.2004
475 linux-scsi mailing list 475 linux-scsi mailing list
476 476
477 viii. Change default values for MEGARAID_NEWGEN, MEGARAID_MM, and 477 viii. Change default values for MEGARAID_NEWGEN, MEGARAID_MM, and
478 MEGARAID_MAILBOX to 'n' in Kconfig.megaraid 478 MEGARAID_MAILBOX to 'n' in Kconfig.megaraid
479 479
480 - Andrew Morton, 08.19.2004 480 - Andrew Morton, 08.19.2004
481 linux-scsi mailing list 481 linux-scsi mailing list
482 482
483 ix. replace udelay with msleep 483 ix. replace udelay with msleep
484 484
485 x. Typos corrected in comments and whitespace adjustments, explicit 485 x. Typos corrected in comments and whitespace adjustments, explicit
486 grouping of expressions. 486 grouping of expressions.
487 487
488 488
489 Release Date : Fri Jul 23 15:22:07 EDT 2004 - Atul Mukker <atulm@lsil.com> 489 Release Date : Fri Jul 23 15:22:07 EDT 2004 - Atul Mukker <atulm@lsil.com>
490 Current Version : 2.20.2.0 (scsi module), 2.20.1.0 (cmm module) 490 Current Version : 2.20.2.0 (scsi module), 2.20.1.0 (cmm module)
491 Older Version : 2.20.1.0 (scsi module), 2.20.0.0 (cmm module) 491 Older Version : 2.20.1.0 (scsi module), 2.20.0.0 (cmm module)
492 492
493 i. Add PCI ids for Acer ROMB 2E solution 493 i. Add PCI ids for Acer ROMB 2E solution
494 494
495 ii. Add PCI ids for I4 495 ii. Add PCI ids for I4
496 496
497 iii. Typo corrected for subsys id for megaraid sata 300-4x 497 iii. Typo corrected for subsys id for megaraid sata 300-4x
498 498
499 iv. Remove yield() while mailbox handshake in synchronous commands 499 iv. Remove yield() while mailbox handshake in synchronous commands
500 500
501 501
502 "My other main gripe is things like this: 502 "My other main gripe is things like this:
503 503
504 + // wait for maximum 1 second for status to post 504 + // wait for maximum 1 second for status to post
505 + for (i = 0; i < 40000; i++) { 505 + for (i = 0; i < 40000; i++) {
506 + if (mbox->numstatus != 0xFF) break; 506 + if (mbox->numstatus != 0xFF) break;
507 + udelay(25); yield(); 507 + udelay(25); yield();
508 + } 508 + }
509 509
510 which litter the driver. Use of yield() in drivers is deprecated." 510 which litter the driver. Use of yield() in drivers is deprecated."
511 511
512 - James Bottomley <James.Bottomley@SteelEye.com>, 07.14.2004 512 - James Bottomley <James.Bottomley@SteelEye.com>, 07.14.2004
513 linux-scsi mailing list 513 linux-scsi mailing list
514 514
515 v. Remove redundant __megaraid_busywait_mbox routine 515 v. Remove redundant __megaraid_busywait_mbox routine
516 516
517 vi. Fix bug in the managment module, which causes a system lockup when the 517 vi. Fix bug in the management module, which causes a system lockup when the
518 IO module is loaded and then unloaded, followed by executing any 518 IO module is loaded and then unloaded, followed by executing any
519 management utility. The current version of management module does not 519 management utility. The current version of management module does not
520 handle the adapter unregister properly. 520 handle the adapter unregister properly.
521 521
522 Specifically, it still keeps a reference to the unregistered 522 Specifically, it still keeps a reference to the unregistered
523 controllers. To avoid this, the static array adapters has been 523 controllers. To avoid this, the static array adapters has been
524 replaced by a dynamic list, which gets updated every time an adapter 524 replaced by a dynamic list, which gets updated every time an adapter
525 is added or removed. 525 is added or removed.
526 526
527 Also, during unregistration of the IO module, the resources are 527 Also, during unregistration of the IO module, the resources are
528 now released in the exact reverse order of the allocation time 528 now released in the exact reverse order of the allocation time
529 sequence. 529 sequence.
530 530
531 531
532 Release Date : Fri Jun 25 18:58:43 EDT 2004 - Atul Mukker <atulm@lsil.com> 532 Release Date : Fri Jun 25 18:58:43 EDT 2004 - Atul Mukker <atulm@lsil.com>
533 Current Version : 2.20.1.0 533 Current Version : 2.20.1.0
534 Older Version : megaraid 2.20.0.1 534 Older Version : megaraid 2.20.0.1
535 535
536 i. Stale list pointer in adapter causes kernel panic when module 536 i. Stale list pointer in adapter causes kernel panic when module
537 megaraid_mbox is unloaded 537 megaraid_mbox is unloaded
538 538
539 539
540 Release Date : Thu Jun 24 20:37:11 EDT 2004 - Atul Mukker <atulm@lsil.com> 540 Release Date : Thu Jun 24 20:37:11 EDT 2004 - Atul Mukker <atulm@lsil.com>
541 Current Version : 2.20.0.1 541 Current Version : 2.20.0.1
542 Older Version : megaraid 2.20.0.00 542 Older Version : megaraid 2.20.0.00
543 543
544 i. Modules are not 'y' by default, but depend on current definition of 544 i. Modules are not 'y' by default, but depend on current definition of
545 SCSI & PCI. 545 SCSI & PCI.
546 546
547 ii. Redundant structure mraid_driver_t removed. 547 ii. Redundant structure mraid_driver_t removed.
548 548
549 iii. Miscellaneous indentation and goto/label fixes. 549 iii. Miscellaneous indentation and goto/label fixes.
550 - Christoph Hellwig <hch@infradead.org>, 06.24.2004 linux-scsi 550 - Christoph Hellwig <hch@infradead.org>, 06.24.2004 linux-scsi
551 551
552 iv. scsi_host_put(), do just before completing HBA shutdown. 552 iv. scsi_host_put(), do just before completing HBA shutdown.
553 553
554 554
555 555
556 Release Date : Mon Jun 21 19:53:54 EDT 2004 - Atul Mukker <atulm@lsil.com> 556 Release Date : Mon Jun 21 19:53:54 EDT 2004 - Atul Mukker <atulm@lsil.com>
557 Current Version : 2.20.0.0 557 Current Version : 2.20.0.0
558 Older Version : megaraid 2.20.0.rc2 and 2.00.3 558 Older Version : megaraid 2.20.0.rc2 and 2.00.3
559 559
560 i. Independent module to interact with userland applications and 560 i. Independent module to interact with userland applications and
561 multiplex command to low level RAID module(s). 561 multiplex command to low level RAID module(s).
562 562
563 "Shared code in a third module, a "library module", is an acceptable 563 "Shared code in a third module, a "library module", is an acceptable
564 solution. modprobe automatically loads dependent modules, so users 564 solution. modprobe automatically loads dependent modules, so users
565 running "modprobe driver1" or "modprobe driver2" would automatically 565 running "modprobe driver1" or "modprobe driver2" would automatically
566 load the shared library module." 566 load the shared library module."
567 567
568 - Jeff Garzik <jgarzik@pobox.com> 02.25.2004 LKML 568 - Jeff Garzik <jgarzik@pobox.com> 02.25.2004 LKML
569 569
570 "As Jeff hinted, if your userspace<->driver API is consistent between 570 "As Jeff hinted, if your userspace<->driver API is consistent between
571 your new MPT-based RAID controllers and your existing megaraid driver, 571 your new MPT-based RAID controllers and your existing megaraid driver,
572 then perhaps you need a single small helper module (lsiioctl or some 572 then perhaps you need a single small helper module (lsiioctl or some
573 better name), loaded by both mptraid and megaraid automatically, which 573 better name), loaded by both mptraid and megaraid automatically, which
574 handles registering the /dev/megaraid node dynamically. In this case, 574 handles registering the /dev/megaraid node dynamically. In this case,
575 both mptraid and megaraid would register with lsiioctl for each 575 both mptraid and megaraid would register with lsiioctl for each
576 adapter discovered, and lsiioctl would essentially be a switch, 576 adapter discovered, and lsiioctl would essentially be a switch,
577 redirecting userspace tool ioctls to the appropriate driver." 577 redirecting userspace tool ioctls to the appropriate driver."
578 578
579 - Matt Domsch <Matt_Domsch@dell.com> 02.25.2004 LKML 579 - Matt Domsch <Matt_Domsch@dell.com> 02.25.2004 LKML
580 580
581 ii. Remove C99 initializations from pci_device id. 581 ii. Remove C99 initializations from pci_device id.
582 582
583 "pci_id_table_g would be much more readable when not using C99 583 "pci_id_table_g would be much more readable when not using C99
584 initializers. 584 initializers.
585 PCI table doesn't change, there's lots of users that prefer the more 585 PCI table doesn't change, there's lots of users that prefer the more
586 readable variant. And it's really far less and much easier to grok 586 readable variant. And it's really far less and much easier to grok
587 lines without C99 initializers." 587 lines without C99 initializers."
588 588
589 - Christoph Hellwig <hch@infradead.org>, 05.28.2004 linux-scsi 589 - Christoph Hellwig <hch@infradead.org>, 05.28.2004 linux-scsi
590 590
591 iii. Many fixes as suggested by Christoph Hellwig <hch@infradead.org> on 591 iii. Many fixes as suggested by Christoph Hellwig <hch@infradead.org> on
592 linux-scsi, 05.28.2004 592 linux-scsi, 05.28.2004
593 593
594 iv. We now support up to 32 parallel ioctl commands instead of current 1. 594 iv. We now support up to 32 parallel ioctl commands instead of current 1.
595 There is a conscious effort to let memory allocation not fail for ioctl 595 There is a conscious effort to let memory allocation not fail for ioctl
596 commands. 596 commands.
597 597
598 v. Do away with internal memory management. Use pci_pool_(create|alloc) 598 v. Do away with internal memory management. Use pci_pool_(create|alloc)
599 instead. 599 instead.
600 600
601 vi. Kill tasklet when unloading the driver. 601 vi. Kill tasklet when unloading the driver.
602 602
603 vii. Do not use "host_lock', driver has fine-grain locks now to protect all 603 vii. Do not use "host_lock', driver has fine-grain locks now to protect all
604 data structures. 604 data structures.
605 605
606 viii. Optimize the build scatter-gather list routine. The callers already 606 viii. Optimize the build scatter-gather list routine. The callers already
607 know the data transfer address and length. 607 know the data transfer address and length.
608 608
609 ix. Better implementation of error handling and recovery. Driver now 609 ix. Better implementation of error handling and recovery. Driver now
610 performs extended errors recovery for instances like scsi cable pull. 610 performs extended errors recovery for instances like scsi cable pull.
611 611
612 x. Disassociate the management commands with an overlaid scsi command. 612 x. Disassociate the management commands with an overlaid scsi command.
613 Driver now treats the management packets as special packets and has a 613 Driver now treats the management packets as special packets and has a
614 dedicated callback routine. 614 dedicated callback routine.
615 615
Documentation/sound/alsa/HD-Audio-Models.txt
1 Model name Description 1 Model name Description
2 ---------- ----------- 2 ---------- -----------
3 ALC880 3 ALC880
4 ====== 4 ======
5 3stack 3-jack in back and a headphone out 5 3stack 3-jack in back and a headphone out
6 3stack-digout 3-jack in back, a HP out and a SPDIF out 6 3stack-digout 3-jack in back, a HP out and a SPDIF out
7 5stack 5-jack in back, 2-jack in front 7 5stack 5-jack in back, 2-jack in front
8 5stack-digout 5-jack in back, 2-jack in front, a SPDIF out 8 5stack-digout 5-jack in back, 2-jack in front, a SPDIF out
9 6stack 6-jack in back, 2-jack in front 9 6stack 6-jack in back, 2-jack in front
10 6stack-digout 6-jack with a SPDIF out 10 6stack-digout 6-jack with a SPDIF out
11 w810 3-jack 11 w810 3-jack
12 z71v 3-jack (HP shared SPDIF) 12 z71v 3-jack (HP shared SPDIF)
13 asus 3-jack (ASUS Mobo) 13 asus 3-jack (ASUS Mobo)
14 asus-w1v ASUS W1V 14 asus-w1v ASUS W1V
15 asus-dig ASUS with SPDIF out 15 asus-dig ASUS with SPDIF out
16 asus-dig2 ASUS with SPDIF out (using GPIO2) 16 asus-dig2 ASUS with SPDIF out (using GPIO2)
17 uniwill 3-jack 17 uniwill 3-jack
18 fujitsu Fujitsu Laptops (Pi1536) 18 fujitsu Fujitsu Laptops (Pi1536)
19 F1734 2-jack 19 F1734 2-jack
20 lg LG laptop (m1 express dual) 20 lg LG laptop (m1 express dual)
21 lg-lw LG LW20/LW25 laptop 21 lg-lw LG LW20/LW25 laptop
22 tcl TCL S700 22 tcl TCL S700
23 clevo Clevo laptops (m520G, m665n) 23 clevo Clevo laptops (m520G, m665n)
24 medion Medion Rim 2150 24 medion Medion Rim 2150
25 test for testing/debugging purpose, almost all controls can be 25 test for testing/debugging purpose, almost all controls can be
26 adjusted. Appearing only when compiled with 26 adjusted. Appearing only when compiled with
27 $CONFIG_SND_DEBUG=y 27 $CONFIG_SND_DEBUG=y
28 auto auto-config reading BIOS (default) 28 auto auto-config reading BIOS (default)
29 29
30 ALC260 30 ALC260
31 ====== 31 ======
32 hp HP machines 32 hp HP machines
33 hp-3013 HP machines (3013-variant) 33 hp-3013 HP machines (3013-variant)
34 hp-dc7600 HP DC7600 34 hp-dc7600 HP DC7600
35 fujitsu Fujitsu S7020 35 fujitsu Fujitsu S7020
36 acer Acer TravelMate 36 acer Acer TravelMate
37 will Will laptops (PB V7900) 37 will Will laptops (PB V7900)
38 replacer Replacer 672V 38 replacer Replacer 672V
39 favorit100 Maxdata Favorit 100XS 39 favorit100 Maxdata Favorit 100XS
40 basic fixed pin assignment (old default model) 40 basic fixed pin assignment (old default model)
41 test for testing/debugging purpose, almost all controls can 41 test for testing/debugging purpose, almost all controls can
42 adjusted. Appearing only when compiled with 42 adjusted. Appearing only when compiled with
43 $CONFIG_SND_DEBUG=y 43 $CONFIG_SND_DEBUG=y
44 auto auto-config reading BIOS (default) 44 auto auto-config reading BIOS (default)
45 45
46 ALC262 46 ALC262
47 ====== 47 ======
48 fujitsu Fujitsu Laptop 48 fujitsu Fujitsu Laptop
49 hp-bpc HP xw4400/6400/8400/9400 laptops 49 hp-bpc HP xw4400/6400/8400/9400 laptops
50 hp-bpc-d7000 HP BPC D7000 50 hp-bpc-d7000 HP BPC D7000
51 hp-tc-t5735 HP Thin Client T5735 51 hp-tc-t5735 HP Thin Client T5735
52 hp-rp5700 HP RP5700 52 hp-rp5700 HP RP5700
53 benq Benq ED8 53 benq Benq ED8
54 benq-t31 Benq T31 54 benq-t31 Benq T31
55 hippo Hippo (ATI) with jack detection, Sony UX-90s 55 hippo Hippo (ATI) with jack detection, Sony UX-90s
56 hippo_1 Hippo (Benq) with jack detection 56 hippo_1 Hippo (Benq) with jack detection
57 sony-assamd Sony ASSAMD 57 sony-assamd Sony ASSAMD
58 toshiba-s06 Toshiba S06 58 toshiba-s06 Toshiba S06
59 toshiba-rx1 Toshiba RX1 59 toshiba-rx1 Toshiba RX1
60 tyan Tyan Thunder n6650W (S2915-E) 60 tyan Tyan Thunder n6650W (S2915-E)
61 ultra Samsung Q1 Ultra Vista model 61 ultra Samsung Q1 Ultra Vista model
62 lenovo-3000 Lenovo 3000 y410 62 lenovo-3000 Lenovo 3000 y410
63 nec NEC Versa S9100 63 nec NEC Versa S9100
64 basic fixed pin assignment w/o SPDIF 64 basic fixed pin assignment w/o SPDIF
65 auto auto-config reading BIOS (default) 65 auto auto-config reading BIOS (default)
66 66
67 ALC267/268 67 ALC267/268
68 ========== 68 ==========
69 quanta-il1 Quanta IL1 mini-notebook 69 quanta-il1 Quanta IL1 mini-notebook
70 3stack 3-stack model 70 3stack 3-stack model
71 toshiba Toshiba A205 71 toshiba Toshiba A205
72 acer Acer laptops 72 acer Acer laptops
73 acer-dmic Acer laptops with digital-mic 73 acer-dmic Acer laptops with digital-mic
74 acer-aspire Acer Aspire One 74 acer-aspire Acer Aspire One
75 dell Dell OEM laptops (Vostro 1200) 75 dell Dell OEM laptops (Vostro 1200)
76 zepto Zepto laptops 76 zepto Zepto laptops
77 test for testing/debugging purpose, almost all controls can 77 test for testing/debugging purpose, almost all controls can
78 adjusted. Appearing only when compiled with 78 adjusted. Appearing only when compiled with
79 $CONFIG_SND_DEBUG=y 79 $CONFIG_SND_DEBUG=y
80 auto auto-config reading BIOS (default) 80 auto auto-config reading BIOS (default)
81 81
82 ALC269 82 ALC269
83 ====== 83 ======
84 basic Basic preset 84 basic Basic preset
85 quanta Quanta FL1 85 quanta Quanta FL1
86 eeepc-p703 ASUS Eeepc P703 P900A 86 eeepc-p703 ASUS Eeepc P703 P900A
87 eeepc-p901 ASUS Eeepc P901 S101 87 eeepc-p901 ASUS Eeepc P901 S101
88 fujitsu FSC Amilo 88 fujitsu FSC Amilo
89 lifebook Fujitsu Lifebook S6420 89 lifebook Fujitsu Lifebook S6420
90 auto auto-config reading BIOS (default) 90 auto auto-config reading BIOS (default)
91 91
92 ALC662/663/272 92 ALC662/663/272
93 ============== 93 ==============
94 3stack-dig 3-stack (2-channel) with SPDIF 94 3stack-dig 3-stack (2-channel) with SPDIF
95 3stack-6ch 3-stack (6-channel) 95 3stack-6ch 3-stack (6-channel)
96 3stack-6ch-dig 3-stack (6-channel) with SPDIF 96 3stack-6ch-dig 3-stack (6-channel) with SPDIF
97 6stack-dig 6-stack with SPDIF 97 6stack-dig 6-stack with SPDIF
98 lenovo-101e Lenovo laptop 98 lenovo-101e Lenovo laptop
99 eeepc-p701 ASUS Eeepc P701 99 eeepc-p701 ASUS Eeepc P701
100 eeepc-ep20 ASUS Eeepc EP20 100 eeepc-ep20 ASUS Eeepc EP20
101 ecs ECS/Foxconn mobo 101 ecs ECS/Foxconn mobo
102 m51va ASUS M51VA 102 m51va ASUS M51VA
103 g71v ASUS G71V 103 g71v ASUS G71V
104 h13 ASUS H13 104 h13 ASUS H13
105 g50v ASUS G50V 105 g50v ASUS G50V
106 asus-mode1 ASUS 106 asus-mode1 ASUS
107 asus-mode2 ASUS 107 asus-mode2 ASUS
108 asus-mode3 ASUS 108 asus-mode3 ASUS
109 asus-mode4 ASUS 109 asus-mode4 ASUS
110 asus-mode5 ASUS 110 asus-mode5 ASUS
111 asus-mode6 ASUS 111 asus-mode6 ASUS
112 dell Dell with ALC272 112 dell Dell with ALC272
113 dell-zm1 Dell ZM1 with ALC272 113 dell-zm1 Dell ZM1 with ALC272
114 samsung-nc10 Samsung NC10 mini notebook 114 samsung-nc10 Samsung NC10 mini notebook
115 auto auto-config reading BIOS (default) 115 auto auto-config reading BIOS (default)
116 116
117 ALC882/883/885/888/889 117 ALC882/883/885/888/889
118 ====================== 118 ======================
119 3stack-dig 3-jack with SPDIF I/O 119 3stack-dig 3-jack with SPDIF I/O
120 6stack-dig 6-jack digital with SPDIF I/O 120 6stack-dig 6-jack digital with SPDIF I/O
121 arima Arima W820Di1 121 arima Arima W820Di1
122 targa Targa T8, MSI-1049 T8 122 targa Targa T8, MSI-1049 T8
123 asus-a7j ASUS A7J 123 asus-a7j ASUS A7J
124 asus-a7m ASUS A7M 124 asus-a7m ASUS A7M
125 macpro MacPro support 125 macpro MacPro support
126 mb5 Macbook 5,1 126 mb5 Macbook 5,1
127 mbp3 Macbook Pro rev3 127 mbp3 Macbook Pro rev3
128 imac24 iMac 24'' with jack detection 128 imac24 iMac 24'' with jack detection
129 w2jc ASUS W2JC 129 w2jc ASUS W2JC
130 3stack-2ch-dig 3-jack with SPDIF I/O (ALC883) 130 3stack-2ch-dig 3-jack with SPDIF I/O (ALC883)
131 alc883-6stack-dig 6-jack digital with SPDIF I/O (ALC883) 131 alc883-6stack-dig 6-jack digital with SPDIF I/O (ALC883)
132 3stack-6ch 3-jack 6-channel 132 3stack-6ch 3-jack 6-channel
133 3stack-6ch-dig 3-jack 6-channel with SPDIF I/O 133 3stack-6ch-dig 3-jack 6-channel with SPDIF I/O
134 6stack-dig-demo 6-jack digital for Intel demo board 134 6stack-dig-demo 6-jack digital for Intel demo board
135 acer Acer laptops (Travelmate 3012WTMi, Aspire 5600, etc) 135 acer Acer laptops (Travelmate 3012WTMi, Aspire 5600, etc)
136 acer-aspire Acer Aspire 9810 136 acer-aspire Acer Aspire 9810
137 acer-aspire-4930g Acer Aspire 4930G 137 acer-aspire-4930g Acer Aspire 4930G
138 acer-aspire-6530g Acer Aspire 6530G 138 acer-aspire-6530g Acer Aspire 6530G
139 acer-aspire-7730g Acer Aspire 7730G 139 acer-aspire-7730g Acer Aspire 7730G
140 acer-aspire-8930g Acer Aspire 8930G 140 acer-aspire-8930g Acer Aspire 8930G
141 medion Medion Laptops 141 medion Medion Laptops
142 medion-md2 Medion MD2 142 medion-md2 Medion MD2
143 targa-dig Targa/MSI 143 targa-dig Targa/MSI
144 targa-2ch-dig Targa/MSI with 2-channel 144 targa-2ch-dig Targa/MSI with 2-channel
145 targa-8ch-dig Targa/MSI with 8-channel (MSI GX620) 145 targa-8ch-dig Targa/MSI with 8-channel (MSI GX620)
146 laptop-eapd 3-jack with SPDIF I/O and EAPD (Clevo M540JE, M550JE) 146 laptop-eapd 3-jack with SPDIF I/O and EAPD (Clevo M540JE, M550JE)
147 lenovo-101e Lenovo 101E 147 lenovo-101e Lenovo 101E
148 lenovo-nb0763 Lenovo NB0763 148 lenovo-nb0763 Lenovo NB0763
149 lenovo-ms7195-dig Lenovo MS7195 149 lenovo-ms7195-dig Lenovo MS7195
150 lenovo-sky Lenovo Sky 150 lenovo-sky Lenovo Sky
151 haier-w66 Haier W66 151 haier-w66 Haier W66
152 3stack-hp HP machines with 3stack (Lucknow, Samba boards) 152 3stack-hp HP machines with 3stack (Lucknow, Samba boards)
153 6stack-dell Dell machines with 6stack (Inspiron 530) 153 6stack-dell Dell machines with 6stack (Inspiron 530)
154 mitac Mitac 8252D 154 mitac Mitac 8252D
155 clevo-m540r Clevo M540R (6ch + digital) 155 clevo-m540r Clevo M540R (6ch + digital)
156 clevo-m720 Clevo M720 laptop series 156 clevo-m720 Clevo M720 laptop series
157 fujitsu-pi2515 Fujitsu AMILO Pi2515 157 fujitsu-pi2515 Fujitsu AMILO Pi2515
158 fujitsu-xa3530 Fujitsu AMILO XA3530 158 fujitsu-xa3530 Fujitsu AMILO XA3530
159 3stack-6ch-intel Intel DG33* boards 159 3stack-6ch-intel Intel DG33* boards
160 intel-alc889a Intel IbexPeak with ALC889A 160 intel-alc889a Intel IbexPeak with ALC889A
161 intel-x58 Intel DX58 with ALC889 161 intel-x58 Intel DX58 with ALC889
162 asus-p5q ASUS P5Q-EM boards 162 asus-p5q ASUS P5Q-EM boards
163 mb31 MacBook 3,1 163 mb31 MacBook 3,1
164 sony-vaio-tt Sony VAIO TT 164 sony-vaio-tt Sony VAIO TT
165 auto auto-config reading BIOS (default) 165 auto auto-config reading BIOS (default)
166 166
167 ALC861/660 167 ALC861/660
168 ========== 168 ==========
169 3stack 3-jack 169 3stack 3-jack
170 3stack-dig 3-jack with SPDIF I/O 170 3stack-dig 3-jack with SPDIF I/O
171 6stack-dig 6-jack with SPDIF I/O 171 6stack-dig 6-jack with SPDIF I/O
172 3stack-660 3-jack (for ALC660) 172 3stack-660 3-jack (for ALC660)
173 uniwill-m31 Uniwill M31 laptop 173 uniwill-m31 Uniwill M31 laptop
174 toshiba Toshiba laptop support 174 toshiba Toshiba laptop support
175 asus Asus laptop support 175 asus Asus laptop support
176 asus-laptop ASUS F2/F3 laptops 176 asus-laptop ASUS F2/F3 laptops
177 auto auto-config reading BIOS (default) 177 auto auto-config reading BIOS (default)
178 178
179 ALC861VD/660VD 179 ALC861VD/660VD
180 ============== 180 ==============
181 3stack 3-jack 181 3stack 3-jack
182 3stack-dig 3-jack with SPDIF OUT 182 3stack-dig 3-jack with SPDIF OUT
183 6stack-dig 6-jack with SPDIF OUT 183 6stack-dig 6-jack with SPDIF OUT
184 3stack-660 3-jack (for ALC660VD) 184 3stack-660 3-jack (for ALC660VD)
185 3stack-660-digout 3-jack with SPDIF OUT (for ALC660VD) 185 3stack-660-digout 3-jack with SPDIF OUT (for ALC660VD)
186 lenovo Lenovo 3000 C200 186 lenovo Lenovo 3000 C200
187 dallas Dallas laptops 187 dallas Dallas laptops
188 hp HP TX1000 188 hp HP TX1000
189 asus-v1s ASUS V1Sn 189 asus-v1s ASUS V1Sn
190 auto auto-config reading BIOS (default) 190 auto auto-config reading BIOS (default)
191 191
192 CMI9880 192 CMI9880
193 ======= 193 =======
194 minimal 3-jack in back 194 minimal 3-jack in back
195 min_fp 3-jack in back, 2-jack in front 195 min_fp 3-jack in back, 2-jack in front
196 full 6-jack in back, 2-jack in front 196 full 6-jack in back, 2-jack in front
197 full_dig 6-jack in back, 2-jack in front, SPDIF I/O 197 full_dig 6-jack in back, 2-jack in front, SPDIF I/O
198 allout 5-jack in back, 2-jack in front, SPDIF out 198 allout 5-jack in back, 2-jack in front, SPDIF out
199 auto auto-config reading BIOS (default) 199 auto auto-config reading BIOS (default)
200 200
201 AD1882 / AD1882A 201 AD1882 / AD1882A
202 ================ 202 ================
203 3stack 3-stack mode (default) 203 3stack 3-stack mode (default)
204 6stack 6-stack mode 204 6stack 6-stack mode
205 205
206 AD1884A / AD1883 / AD1984A / AD1984B 206 AD1884A / AD1883 / AD1984A / AD1984B
207 ==================================== 207 ====================================
208 desktop 3-stack desktop (default) 208 desktop 3-stack desktop (default)
209 laptop laptop with HP jack sensing 209 laptop laptop with HP jack sensing
210 mobile mobile devices with HP jack sensing 210 mobile mobile devices with HP jack sensing
211 thinkpad Lenovo Thinkpad X300 211 thinkpad Lenovo Thinkpad X300
212 212
213 AD1884 213 AD1884
214 ====== 214 ======
215 N/A 215 N/A
216 216
217 AD1981 217 AD1981
218 ====== 218 ======
219 basic 3-jack (default) 219 basic 3-jack (default)
220 hp HP nx6320 220 hp HP nx6320
221 thinkpad Lenovo Thinkpad T60/X60/Z60 221 thinkpad Lenovo Thinkpad T60/X60/Z60
222 toshiba Toshiba U205 222 toshiba Toshiba U205
223 223
224 AD1983 224 AD1983
225 ====== 225 ======
226 N/A 226 N/A
227 227
228 AD1984 228 AD1984
229 ====== 229 ======
230 basic default configuration 230 basic default configuration
231 thinkpad Lenovo Thinkpad T61/X61 231 thinkpad Lenovo Thinkpad T61/X61
232 dell_desktop Dell T3400 232 dell_desktop Dell T3400
233 233
234 AD1986A 234 AD1986A
235 ======= 235 =======
236 6stack 6-jack, separate surrounds (default) 236 6stack 6-jack, separate surrounds (default)
237 3stack 3-stack, shared surrounds 237 3stack 3-stack, shared surrounds
238 laptop 2-channel only (FSC V2060, Samsung M50) 238 laptop 2-channel only (FSC V2060, Samsung M50)
239 laptop-eapd 2-channel with EAPD (ASUS A6J) 239 laptop-eapd 2-channel with EAPD (ASUS A6J)
240 laptop-automute 2-channel with EAPD and HP-automute (Lenovo N100) 240 laptop-automute 2-channel with EAPD and HP-automute (Lenovo N100)
241 ultra 2-channel with EAPD (Samsung Ultra tablet PC) 241 ultra 2-channel with EAPD (Samsung Ultra tablet PC)
242 samsung 2-channel with EAPD (Samsung R65) 242 samsung 2-channel with EAPD (Samsung R65)
243 samsung-p50 2-channel with HP-automute (Samsung P50) 243 samsung-p50 2-channel with HP-automute (Samsung P50)
244 244
245 AD1988/AD1988B/AD1989A/AD1989B 245 AD1988/AD1988B/AD1989A/AD1989B
246 ============================== 246 ==============================
247 6stack 6-jack 247 6stack 6-jack
248 6stack-dig ditto with SPDIF 248 6stack-dig ditto with SPDIF
249 3stack 3-jack 249 3stack 3-jack
250 3stack-dig ditto with SPDIF 250 3stack-dig ditto with SPDIF
251 laptop 3-jack with hp-jack automute 251 laptop 3-jack with hp-jack automute
252 laptop-dig ditto with SPDIF 252 laptop-dig ditto with SPDIF
253 auto auto-config reading BIOS (default) 253 auto auto-config reading BIOS (default)
254 254
255 Conexant 5045 255 Conexant 5045
256 ============= 256 =============
257 laptop-hpsense Laptop with HP sense (old model laptop) 257 laptop-hpsense Laptop with HP sense (old model laptop)
258 laptop-micsense Laptop with Mic sense (old model fujitsu) 258 laptop-micsense Laptop with Mic sense (old model fujitsu)
259 laptop-hpmicsense Laptop with HP and Mic senses 259 laptop-hpmicsense Laptop with HP and Mic senses
260 benq Benq R55E 260 benq Benq R55E
261 laptop-hp530 HP 530 laptop 261 laptop-hp530 HP 530 laptop
262 test for testing/debugging purpose, almost all controls 262 test for testing/debugging purpose, almost all controls
263 can be adjusted. Appearing only when compiled with 263 can be adjusted. Appearing only when compiled with
264 $CONFIG_SND_DEBUG=y 264 $CONFIG_SND_DEBUG=y
265 265
266 Conexant 5047 266 Conexant 5047
267 ============= 267 =============
268 laptop Basic Laptop config 268 laptop Basic Laptop config
269 laptop-hp Laptop config for some HP models (subdevice 30A5) 269 laptop-hp Laptop config for some HP models (subdevice 30A5)
270 laptop-eapd Laptop config with EAPD support 270 laptop-eapd Laptop config with EAPD support
271 test for testing/debugging purpose, almost all controls 271 test for testing/debugging purpose, almost all controls
272 can be adjusted. Appearing only when compiled with 272 can be adjusted. Appearing only when compiled with
273 $CONFIG_SND_DEBUG=y 273 $CONFIG_SND_DEBUG=y
274 274
275 Conexant 5051 275 Conexant 5051
276 ============= 276 =============
277 laptop Basic Laptop config (default) 277 laptop Basic Laptop config (default)
278 hp HP Spartan laptop 278 hp HP Spartan laptop
279 hp-dv6736 HP dv6736 279 hp-dv6736 HP dv6736
280 lenovo-x200 Lenovo X200 laptop 280 lenovo-x200 Lenovo X200 laptop
281 281
282 Conexant 5066 282 Conexant 5066
283 ============= 283 =============
284 laptop Basic Laptop config (default) 284 laptop Basic Laptop config (default)
285 dell-laptop Dell laptops 285 dell-laptop Dell laptops
286 olpc-xo-1_5 OLPC XO 1.5 286 olpc-xo-1_5 OLPC XO 1.5
287 287
288 STAC9200 288 STAC9200
289 ======== 289 ========
290 ref Reference board 290 ref Reference board
291 oqo OQO Model 2 291 oqo OQO Model 2
292 dell-d21 Dell (unknown) 292 dell-d21 Dell (unknown)
293 dell-d22 Dell (unknown) 293 dell-d22 Dell (unknown)
294 dell-d23 Dell (unknown) 294 dell-d23 Dell (unknown)
295 dell-m21 Dell Inspiron 630m, Dell Inspiron 640m 295 dell-m21 Dell Inspiron 630m, Dell Inspiron 640m
296 dell-m22 Dell Latitude D620, Dell Latitude D820 296 dell-m22 Dell Latitude D620, Dell Latitude D820
297 dell-m23 Dell XPS M1710, Dell Precision M90 297 dell-m23 Dell XPS M1710, Dell Precision M90
298 dell-m24 Dell Latitude 120L 298 dell-m24 Dell Latitude 120L
299 dell-m25 Dell Inspiron E1505n 299 dell-m25 Dell Inspiron E1505n
300 dell-m26 Dell Inspiron 1501 300 dell-m26 Dell Inspiron 1501
301 dell-m27 Dell Inspiron E1705/9400 301 dell-m27 Dell Inspiron E1705/9400
302 gateway-m4 Gateway laptops with EAPD control 302 gateway-m4 Gateway laptops with EAPD control
303 gateway-m4-2 Gateway laptops with EAPD control 303 gateway-m4-2 Gateway laptops with EAPD control
304 panasonic Panasonic CF-74 304 panasonic Panasonic CF-74
305 auto BIOS setup (default) 305 auto BIOS setup (default)
306 306
307 STAC9205/9254 307 STAC9205/9254
308 ============= 308 =============
309 ref Reference board 309 ref Reference board
310 dell-m42 Dell (unknown) 310 dell-m42 Dell (unknown)
311 dell-m43 Dell Precision 311 dell-m43 Dell Precision
312 dell-m44 Dell Inspiron 312 dell-m44 Dell Inspiron
313 eapd Keep EAPD on (e.g. Gateway T1616) 313 eapd Keep EAPD on (e.g. Gateway T1616)
314 auto BIOS setup (default) 314 auto BIOS setup (default)
315 315
316 STAC9220/9221 316 STAC9220/9221
317 ============= 317 =============
318 ref Reference board 318 ref Reference board
319 3stack D945 3stack 319 3stack D945 3stack
320 5stack D945 5stack + SPDIF 320 5stack D945 5stack + SPDIF
321 intel-mac-v1 Intel Mac Type 1 321 intel-mac-v1 Intel Mac Type 1
322 intel-mac-v2 Intel Mac Type 2 322 intel-mac-v2 Intel Mac Type 2
323 intel-mac-v3 Intel Mac Type 3 323 intel-mac-v3 Intel Mac Type 3
324 intel-mac-v4 Intel Mac Type 4 324 intel-mac-v4 Intel Mac Type 4
325 intel-mac-v5 Intel Mac Type 5 325 intel-mac-v5 Intel Mac Type 5
326 intel-mac-auto Intel Mac (detect type according to subsystem id) 326 intel-mac-auto Intel Mac (detect type according to subsystem id)
327 macmini Intel Mac Mini (equivalent with type 3) 327 macmini Intel Mac Mini (equivalent with type 3)
328 macbook Intel Mac Book (eq. type 5) 328 macbook Intel Mac Book (eq. type 5)
329 macbook-pro-v1 Intel Mac Book Pro 1st generation (eq. type 3) 329 macbook-pro-v1 Intel Mac Book Pro 1st generation (eq. type 3)
330 macbook-pro Intel Mac Book Pro 2nd generation (eq. type 3) 330 macbook-pro Intel Mac Book Pro 2nd generation (eq. type 3)
331 imac-intel Intel iMac (eq. type 2) 331 imac-intel Intel iMac (eq. type 2)
332 imac-intel-20 Intel iMac (newer version) (eq. type 3) 332 imac-intel-20 Intel iMac (newer version) (eq. type 3)
333 ecs202 ECS/PC chips 333 ecs202 ECS/PC chips
334 dell-d81 Dell (unknown) 334 dell-d81 Dell (unknown)
335 dell-d82 Dell (unknown) 335 dell-d82 Dell (unknown)
336 dell-m81 Dell (unknown) 336 dell-m81 Dell (unknown)
337 dell-m82 Dell XPS M1210 337 dell-m82 Dell XPS M1210
338 auto BIOS setup (default) 338 auto BIOS setup (default)
339 339
340 STAC9202/9250/9251 340 STAC9202/9250/9251
341 ================== 341 ==================
342 ref Reference board, base config 342 ref Reference board, base config
343 m1 Some Gateway MX series laptops (NX560XL) 343 m1 Some Gateway MX series laptops (NX560XL)
344 m1-2 Some Gateway MX series laptops (MX6453) 344 m1-2 Some Gateway MX series laptops (MX6453)
345 m2 Some Gateway MX series laptops (M255) 345 m2 Some Gateway MX series laptops (M255)
346 m2-2 Some Gateway MX series laptops 346 m2-2 Some Gateway MX series laptops
347 m3 Some Gateway MX series laptops 347 m3 Some Gateway MX series laptops
348 m5 Some Gateway MX series laptops (MP6954) 348 m5 Some Gateway MX series laptops (MP6954)
349 m6 Some Gateway NX series laptops 349 m6 Some Gateway NX series laptops
350 auto BIOS setup (default) 350 auto BIOS setup (default)
351 351
352 STAC9227/9228/9229/927x 352 STAC9227/9228/9229/927x
353 ======================= 353 =======================
354 ref Reference board 354 ref Reference board
355 ref-no-jd Reference board without HP/Mic jack detection 355 ref-no-jd Reference board without HP/Mic jack detection
356 3stack D965 3stack 356 3stack D965 3stack
357 5stack D965 5stack + SPDIF 357 5stack D965 5stack + SPDIF
358 5stack-no-fp D965 5stack without front panel 358 5stack-no-fp D965 5stack without front panel
359 dell-3stack Dell Dimension E520 359 dell-3stack Dell Dimension E520
360 dell-bios Fixes with Dell BIOS setup 360 dell-bios Fixes with Dell BIOS setup
361 auto BIOS setup (default) 361 auto BIOS setup (default)
362 362
363 STAC92HD71B* 363 STAC92HD71B*
364 ============ 364 ============
365 ref Reference board 365 ref Reference board
366 dell-m4-1 Dell desktops 366 dell-m4-1 Dell desktops
367 dell-m4-2 Dell desktops 367 dell-m4-2 Dell desktops
368 dell-m4-3 Dell desktops 368 dell-m4-3 Dell desktops
369 hp-m4 HP mini 1000 369 hp-m4 HP mini 1000
370 hp-dv5 HP dv series 370 hp-dv5 HP dv series
371 hp-hdx HP HDX series 371 hp-hdx HP HDX series
372 hp-dv4-1222nr HP dv4-1222nr (with LED support) 372 hp-dv4-1222nr HP dv4-1222nr (with LED support)
373 auto BIOS setup (default) 373 auto BIOS setup (default)
374 374
375 STAC92HD73* 375 STAC92HD73*
376 =========== 376 ===========
377 ref Reference board 377 ref Reference board
378 no-jd BIOS setup but without jack-detection 378 no-jd BIOS setup but without jack-detection
379 intel Intel DG45* mobos 379 intel Intel DG45* mobos
380 dell-m6-amic Dell desktops/laptops with analog mics 380 dell-m6-amic Dell desktops/laptops with analog mics
381 dell-m6-dmic Dell desktops/laptops with digital mics 381 dell-m6-dmic Dell desktops/laptops with digital mics
382 dell-m6 Dell desktops/laptops with both type of mics 382 dell-m6 Dell desktops/laptops with both type of mics
383 dell-eq Dell desktops/laptops 383 dell-eq Dell desktops/laptops
384 alienware Alienware M17x 384 alienware Alienware M17x
385 auto BIOS setup (default) 385 auto BIOS setup (default)
386 386
387 STAC92HD83* 387 STAC92HD83*
388 =========== 388 ===========
389 ref Reference board 389 ref Reference board
390 mic-ref Reference board with power managment for ports 390 mic-ref Reference board with power management for ports
391 dell-s14 Dell laptop 391 dell-s14 Dell laptop
392 auto BIOS setup (default) 392 auto BIOS setup (default)
393 393
394 STAC9872 394 STAC9872
395 ======== 395 ========
396 vaio VAIO laptop without SPDIF 396 vaio VAIO laptop without SPDIF
397 auto BIOS setup (default) 397 auto BIOS setup (default)
398 398
399 Cirrus Logic CS4206/4207 399 Cirrus Logic CS4206/4207
400 ======================== 400 ========================
401 mbp55 MacBook Pro 5,5 401 mbp55 MacBook Pro 5,5
402 auto BIOS setup (default) 402 auto BIOS setup (default)
403 403
Documentation/trace/ftrace.txt
1 ftrace - Function Tracer 1 ftrace - Function Tracer
2 ======================== 2 ========================
3 3
4 Copyright 2008 Red Hat Inc. 4 Copyright 2008 Red Hat Inc.
5 Author: Steven Rostedt <srostedt@redhat.com> 5 Author: Steven Rostedt <srostedt@redhat.com>
6 License: The GNU Free Documentation License, Version 1.2 6 License: The GNU Free Documentation License, Version 1.2
7 (dual licensed under the GPL v2) 7 (dual licensed under the GPL v2)
8 Reviewers: Elias Oltmanns, Randy Dunlap, Andrew Morton, 8 Reviewers: Elias Oltmanns, Randy Dunlap, Andrew Morton,
9 John Kacur, and David Teigland. 9 John Kacur, and David Teigland.
10 Written for: 2.6.28-rc2 10 Written for: 2.6.28-rc2
11 11
12 Introduction 12 Introduction
13 ------------ 13 ------------
14 14
15 Ftrace is an internal tracer designed to help out developers and 15 Ftrace is an internal tracer designed to help out developers and
16 designers of systems to find what is going on inside the kernel. 16 designers of systems to find what is going on inside the kernel.
17 It can be used for debugging or analyzing latencies and 17 It can be used for debugging or analyzing latencies and
18 performance issues that take place outside of user-space. 18 performance issues that take place outside of user-space.
19 19
20 Although ftrace is the function tracer, it also includes an 20 Although ftrace is the function tracer, it also includes an
21 infrastructure that allows for other types of tracing. Some of 21 infrastructure that allows for other types of tracing. Some of
22 the tracers that are currently in ftrace include a tracer to 22 the tracers that are currently in ftrace include a tracer to
23 trace context switches, the time it takes for a high priority 23 trace context switches, the time it takes for a high priority
24 task to run after it was woken up, the time interrupts are 24 task to run after it was woken up, the time interrupts are
25 disabled, and more (ftrace allows for tracer plugins, which 25 disabled, and more (ftrace allows for tracer plugins, which
26 means that the list of tracers can always grow). 26 means that the list of tracers can always grow).
27 27
28 28
29 Implementation Details 29 Implementation Details
30 ---------------------- 30 ----------------------
31 31
32 See ftrace-design.txt for details for arch porters and such. 32 See ftrace-design.txt for details for arch porters and such.
33 33
34 34
35 The File System 35 The File System
36 --------------- 36 ---------------
37 37
38 Ftrace uses the debugfs file system to hold the control files as 38 Ftrace uses the debugfs file system to hold the control files as
39 well as the files to display output. 39 well as the files to display output.
40 40
41 When debugfs is configured into the kernel (which selecting any ftrace 41 When debugfs is configured into the kernel (which selecting any ftrace
42 option will do) the directory /sys/kernel/debug will be created. To mount 42 option will do) the directory /sys/kernel/debug will be created. To mount
43 this directory, you can add to your /etc/fstab file: 43 this directory, you can add to your /etc/fstab file:
44 44
45 debugfs /sys/kernel/debug debugfs defaults 0 0 45 debugfs /sys/kernel/debug debugfs defaults 0 0
46 46
47 Or you can mount it at run time with: 47 Or you can mount it at run time with:
48 48
49 mount -t debugfs nodev /sys/kernel/debug 49 mount -t debugfs nodev /sys/kernel/debug
50 50
51 For quicker access to that directory you may want to make a soft link to 51 For quicker access to that directory you may want to make a soft link to
52 it: 52 it:
53 53
54 ln -s /sys/kernel/debug /debug 54 ln -s /sys/kernel/debug /debug
55 55
56 Any selected ftrace option will also create a directory called tracing 56 Any selected ftrace option will also create a directory called tracing
57 within the debugfs. The rest of the document will assume that you are in 57 within the debugfs. The rest of the document will assume that you are in
58 the ftrace directory (cd /sys/kernel/debug/tracing) and will only concentrate 58 the ftrace directory (cd /sys/kernel/debug/tracing) and will only concentrate
59 on the files within that directory and not distract from the content with 59 on the files within that directory and not distract from the content with
60 the extended "/sys/kernel/debug/tracing" path name. 60 the extended "/sys/kernel/debug/tracing" path name.
61 61
62 That's it! (assuming that you have ftrace configured into your kernel) 62 That's it! (assuming that you have ftrace configured into your kernel)
63 63
64 After mounting the debugfs, you can see a directory called 64 After mounting the debugfs, you can see a directory called
65 "tracing". This directory contains the control and output files 65 "tracing". This directory contains the control and output files
66 of ftrace. Here is a list of some of the key files: 66 of ftrace. Here is a list of some of the key files:
67 67
68 68
69 Note: all time values are in microseconds. 69 Note: all time values are in microseconds.
70 70
71 current_tracer: 71 current_tracer:
72 72
73 This is used to set or display the current tracer 73 This is used to set or display the current tracer
74 that is configured. 74 that is configured.
75 75
76 available_tracers: 76 available_tracers:
77 77
78 This holds the different types of tracers that 78 This holds the different types of tracers that
79 have been compiled into the kernel. The 79 have been compiled into the kernel. The
80 tracers listed here can be configured by 80 tracers listed here can be configured by
81 echoing their name into current_tracer. 81 echoing their name into current_tracer.
82 82
83 tracing_enabled: 83 tracing_enabled:
84 84
85 This sets or displays whether the current_tracer 85 This sets or displays whether the current_tracer
86 is activated and tracing or not. Echo 0 into this 86 is activated and tracing or not. Echo 0 into this
87 file to disable the tracer or 1 to enable it. 87 file to disable the tracer or 1 to enable it.
88 88
89 trace: 89 trace:
90 90
91 This file holds the output of the trace in a human 91 This file holds the output of the trace in a human
92 readable format (described below). 92 readable format (described below).
93 93
94 trace_pipe: 94 trace_pipe:
95 95
96 The output is the same as the "trace" file but this 96 The output is the same as the "trace" file but this
97 file is meant to be streamed with live tracing. 97 file is meant to be streamed with live tracing.
98 Reads from this file will block until new data is 98 Reads from this file will block until new data is
99 retrieved. Unlike the "trace" file, this file is a 99 retrieved. Unlike the "trace" file, this file is a
100 consumer. This means reading from this file causes 100 consumer. This means reading from this file causes
101 sequential reads to display more current data. Once 101 sequential reads to display more current data. Once
102 data is read from this file, it is consumed, and 102 data is read from this file, it is consumed, and
103 will not be read again with a sequential read. The 103 will not be read again with a sequential read. The
104 "trace" file is static, and if the tracer is not 104 "trace" file is static, and if the tracer is not
105 adding more data,they will display the same 105 adding more data,they will display the same
106 information every time they are read. 106 information every time they are read.
107 107
108 trace_options: 108 trace_options:
109 109
110 This file lets the user control the amount of data 110 This file lets the user control the amount of data
111 that is displayed in one of the above output 111 that is displayed in one of the above output
112 files. 112 files.
113 113
114 tracing_max_latency: 114 tracing_max_latency:
115 115
116 Some of the tracers record the max latency. 116 Some of the tracers record the max latency.
117 For example, the time interrupts are disabled. 117 For example, the time interrupts are disabled.
118 This time is saved in this file. The max trace 118 This time is saved in this file. The max trace
119 will also be stored, and displayed by "trace". 119 will also be stored, and displayed by "trace".
120 A new max trace will only be recorded if the 120 A new max trace will only be recorded if the
121 latency is greater than the value in this 121 latency is greater than the value in this
122 file. (in microseconds) 122 file. (in microseconds)
123 123
124 buffer_size_kb: 124 buffer_size_kb:
125 125
126 This sets or displays the number of kilobytes each CPU 126 This sets or displays the number of kilobytes each CPU
127 buffer can hold. The tracer buffers are the same size 127 buffer can hold. The tracer buffers are the same size
128 for each CPU. The displayed number is the size of the 128 for each CPU. The displayed number is the size of the
129 CPU buffer and not total size of all buffers. The 129 CPU buffer and not total size of all buffers. The
130 trace buffers are allocated in pages (blocks of memory 130 trace buffers are allocated in pages (blocks of memory
131 that the kernel uses for allocation, usually 4 KB in size). 131 that the kernel uses for allocation, usually 4 KB in size).
132 If the last page allocated has room for more bytes 132 If the last page allocated has room for more bytes
133 than requested, the rest of the page will be used, 133 than requested, the rest of the page will be used,
134 making the actual allocation bigger than requested. 134 making the actual allocation bigger than requested.
135 ( Note, the size may not be a multiple of the page size 135 ( Note, the size may not be a multiple of the page size
136 due to buffer managment overhead. ) 136 due to buffer management overhead. )
137 137
138 This can only be updated when the current_tracer 138 This can only be updated when the current_tracer
139 is set to "nop". 139 is set to "nop".
140 140
141 tracing_cpumask: 141 tracing_cpumask:
142 142
143 This is a mask that lets the user only trace 143 This is a mask that lets the user only trace
144 on specified CPUS. The format is a hex string 144 on specified CPUS. The format is a hex string
145 representing the CPUS. 145 representing the CPUS.
146 146
147 set_ftrace_filter: 147 set_ftrace_filter:
148 148
149 When dynamic ftrace is configured in (see the 149 When dynamic ftrace is configured in (see the
150 section below "dynamic ftrace"), the code is dynamically 150 section below "dynamic ftrace"), the code is dynamically
151 modified (code text rewrite) to disable calling of the 151 modified (code text rewrite) to disable calling of the
152 function profiler (mcount). This lets tracing be configured 152 function profiler (mcount). This lets tracing be configured
153 in with practically no overhead in performance. This also 153 in with practically no overhead in performance. This also
154 has a side effect of enabling or disabling specific functions 154 has a side effect of enabling or disabling specific functions
155 to be traced. Echoing names of functions into this file 155 to be traced. Echoing names of functions into this file
156 will limit the trace to only those functions. 156 will limit the trace to only those functions.
157 157
158 set_ftrace_notrace: 158 set_ftrace_notrace:
159 159
160 This has an effect opposite to that of 160 This has an effect opposite to that of
161 set_ftrace_filter. Any function that is added here will not 161 set_ftrace_filter. Any function that is added here will not
162 be traced. If a function exists in both set_ftrace_filter 162 be traced. If a function exists in both set_ftrace_filter
163 and set_ftrace_notrace, the function will _not_ be traced. 163 and set_ftrace_notrace, the function will _not_ be traced.
164 164
165 set_ftrace_pid: 165 set_ftrace_pid:
166 166
167 Have the function tracer only trace a single thread. 167 Have the function tracer only trace a single thread.
168 168
169 set_graph_function: 169 set_graph_function:
170 170
171 Set a "trigger" function where tracing should start 171 Set a "trigger" function where tracing should start
172 with the function graph tracer (See the section 172 with the function graph tracer (See the section
173 "dynamic ftrace" for more details). 173 "dynamic ftrace" for more details).
174 174
175 available_filter_functions: 175 available_filter_functions:
176 176
177 This lists the functions that ftrace 177 This lists the functions that ftrace
178 has processed and can trace. These are the function 178 has processed and can trace. These are the function
179 names that you can pass to "set_ftrace_filter" or 179 names that you can pass to "set_ftrace_filter" or
180 "set_ftrace_notrace". (See the section "dynamic ftrace" 180 "set_ftrace_notrace". (See the section "dynamic ftrace"
181 below for more details.) 181 below for more details.)
182 182
183 183
184 The Tracers 184 The Tracers
185 ----------- 185 -----------
186 186
187 Here is the list of current tracers that may be configured. 187 Here is the list of current tracers that may be configured.
188 188
189 "function" 189 "function"
190 190
191 Function call tracer to trace all kernel functions. 191 Function call tracer to trace all kernel functions.
192 192
193 "function_graph" 193 "function_graph"
194 194
195 Similar to the function tracer except that the 195 Similar to the function tracer except that the
196 function tracer probes the functions on their entry 196 function tracer probes the functions on their entry
197 whereas the function graph tracer traces on both entry 197 whereas the function graph tracer traces on both entry
198 and exit of the functions. It then provides the ability 198 and exit of the functions. It then provides the ability
199 to draw a graph of function calls similar to C code 199 to draw a graph of function calls similar to C code
200 source. 200 source.
201 201
202 "sched_switch" 202 "sched_switch"
203 203
204 Traces the context switches and wakeups between tasks. 204 Traces the context switches and wakeups between tasks.
205 205
206 "irqsoff" 206 "irqsoff"
207 207
208 Traces the areas that disable interrupts and saves 208 Traces the areas that disable interrupts and saves
209 the trace with the longest max latency. 209 the trace with the longest max latency.
210 See tracing_max_latency. When a new max is recorded, 210 See tracing_max_latency. When a new max is recorded,
211 it replaces the old trace. It is best to view this 211 it replaces the old trace. It is best to view this
212 trace with the latency-format option enabled. 212 trace with the latency-format option enabled.
213 213
214 "preemptoff" 214 "preemptoff"
215 215
216 Similar to irqsoff but traces and records the amount of 216 Similar to irqsoff but traces and records the amount of
217 time for which preemption is disabled. 217 time for which preemption is disabled.
218 218
219 "preemptirqsoff" 219 "preemptirqsoff"
220 220
221 Similar to irqsoff and preemptoff, but traces and 221 Similar to irqsoff and preemptoff, but traces and
222 records the largest time for which irqs and/or preemption 222 records the largest time for which irqs and/or preemption
223 is disabled. 223 is disabled.
224 224
225 "wakeup" 225 "wakeup"
226 226
227 Traces and records the max latency that it takes for 227 Traces and records the max latency that it takes for
228 the highest priority task to get scheduled after 228 the highest priority task to get scheduled after
229 it has been woken up. 229 it has been woken up.
230 230
231 "hw-branch-tracer" 231 "hw-branch-tracer"
232 232
233 Uses the BTS CPU feature on x86 CPUs to traces all 233 Uses the BTS CPU feature on x86 CPUs to traces all
234 branches executed. 234 branches executed.
235 235
236 "nop" 236 "nop"
237 237
238 This is the "trace nothing" tracer. To remove all 238 This is the "trace nothing" tracer. To remove all
239 tracers from tracing simply echo "nop" into 239 tracers from tracing simply echo "nop" into
240 current_tracer. 240 current_tracer.
241 241
242 242
243 Examples of using the tracer 243 Examples of using the tracer
244 ---------------------------- 244 ----------------------------
245 245
246 Here are typical examples of using the tracers when controlling 246 Here are typical examples of using the tracers when controlling
247 them only with the debugfs interface (without using any 247 them only with the debugfs interface (without using any
248 user-land utilities). 248 user-land utilities).
249 249
250 Output format: 250 Output format:
251 -------------- 251 --------------
252 252
253 Here is an example of the output format of the file "trace" 253 Here is an example of the output format of the file "trace"
254 254
255 -------- 255 --------
256 # tracer: function 256 # tracer: function
257 # 257 #
258 # TASK-PID CPU# TIMESTAMP FUNCTION 258 # TASK-PID CPU# TIMESTAMP FUNCTION
259 # | | | | | 259 # | | | | |
260 bash-4251 [01] 10152.583854: path_put <-path_walk 260 bash-4251 [01] 10152.583854: path_put <-path_walk
261 bash-4251 [01] 10152.583855: dput <-path_put 261 bash-4251 [01] 10152.583855: dput <-path_put
262 bash-4251 [01] 10152.583855: _atomic_dec_and_lock <-dput 262 bash-4251 [01] 10152.583855: _atomic_dec_and_lock <-dput
263 -------- 263 --------
264 264
265 A header is printed with the tracer name that is represented by 265 A header is printed with the tracer name that is represented by
266 the trace. In this case the tracer is "function". Then a header 266 the trace. In this case the tracer is "function". Then a header
267 showing the format. Task name "bash", the task PID "4251", the 267 showing the format. Task name "bash", the task PID "4251", the
268 CPU that it was running on "01", the timestamp in <secs>.<usecs> 268 CPU that it was running on "01", the timestamp in <secs>.<usecs>
269 format, the function name that was traced "path_put" and the 269 format, the function name that was traced "path_put" and the
270 parent function that called this function "path_walk". The 270 parent function that called this function "path_walk". The
271 timestamp is the time at which the function was entered. 271 timestamp is the time at which the function was entered.
272 272
273 The sched_switch tracer also includes tracing of task wakeups 273 The sched_switch tracer also includes tracing of task wakeups
274 and context switches. 274 and context switches.
275 275
276 ksoftirqd/1-7 [01] 1453.070013: 7:115:R + 2916:115:S 276 ksoftirqd/1-7 [01] 1453.070013: 7:115:R + 2916:115:S
277 ksoftirqd/1-7 [01] 1453.070013: 7:115:R + 10:115:S 277 ksoftirqd/1-7 [01] 1453.070013: 7:115:R + 10:115:S
278 ksoftirqd/1-7 [01] 1453.070013: 7:115:R ==> 10:115:R 278 ksoftirqd/1-7 [01] 1453.070013: 7:115:R ==> 10:115:R
279 events/1-10 [01] 1453.070013: 10:115:S ==> 2916:115:R 279 events/1-10 [01] 1453.070013: 10:115:S ==> 2916:115:R
280 kondemand/1-2916 [01] 1453.070013: 2916:115:S ==> 7:115:R 280 kondemand/1-2916 [01] 1453.070013: 2916:115:S ==> 7:115:R
281 ksoftirqd/1-7 [01] 1453.070013: 7:115:S ==> 0:140:R 281 ksoftirqd/1-7 [01] 1453.070013: 7:115:S ==> 0:140:R
282 282
283 Wake ups are represented by a "+" and the context switches are 283 Wake ups are represented by a "+" and the context switches are
284 shown as "==>". The format is: 284 shown as "==>". The format is:
285 285
286 Context switches: 286 Context switches:
287 287
288 Previous task Next Task 288 Previous task Next Task
289 289
290 <pid>:<prio>:<state> ==> <pid>:<prio>:<state> 290 <pid>:<prio>:<state> ==> <pid>:<prio>:<state>
291 291
292 Wake ups: 292 Wake ups:
293 293
294 Current task Task waking up 294 Current task Task waking up
295 295
296 <pid>:<prio>:<state> + <pid>:<prio>:<state> 296 <pid>:<prio>:<state> + <pid>:<prio>:<state>
297 297
298 The prio is the internal kernel priority, which is the inverse 298 The prio is the internal kernel priority, which is the inverse
299 of the priority that is usually displayed by user-space tools. 299 of the priority that is usually displayed by user-space tools.
300 Zero represents the highest priority (99). Prio 100 starts the 300 Zero represents the highest priority (99). Prio 100 starts the
301 "nice" priorities with 100 being equal to nice -20 and 139 being 301 "nice" priorities with 100 being equal to nice -20 and 139 being
302 nice 19. The prio "140" is reserved for the idle task which is 302 nice 19. The prio "140" is reserved for the idle task which is
303 the lowest priority thread (pid 0). 303 the lowest priority thread (pid 0).
304 304
305 305
306 Latency trace format 306 Latency trace format
307 -------------------- 307 --------------------
308 308
309 When the latency-format option is enabled, the trace file gives 309 When the latency-format option is enabled, the trace file gives
310 somewhat more information to see why a latency happened. 310 somewhat more information to see why a latency happened.
311 Here is a typical trace. 311 Here is a typical trace.
312 312
313 # tracer: irqsoff 313 # tracer: irqsoff
314 # 314 #
315 irqsoff latency trace v1.1.5 on 2.6.26-rc8 315 irqsoff latency trace v1.1.5 on 2.6.26-rc8
316 -------------------------------------------------------------------- 316 --------------------------------------------------------------------
317 latency: 97 us, #3/3, CPU#0 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:2) 317 latency: 97 us, #3/3, CPU#0 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:2)
318 ----------------- 318 -----------------
319 | task: swapper-0 (uid:0 nice:0 policy:0 rt_prio:0) 319 | task: swapper-0 (uid:0 nice:0 policy:0 rt_prio:0)
320 ----------------- 320 -----------------
321 => started at: apic_timer_interrupt 321 => started at: apic_timer_interrupt
322 => ended at: do_softirq 322 => ended at: do_softirq
323 323
324 # _------=> CPU# 324 # _------=> CPU#
325 # / _-----=> irqs-off 325 # / _-----=> irqs-off
326 # | / _----=> need-resched 326 # | / _----=> need-resched
327 # || / _---=> hardirq/softirq 327 # || / _---=> hardirq/softirq
328 # ||| / _--=> preempt-depth 328 # ||| / _--=> preempt-depth
329 # |||| / 329 # |||| /
330 # ||||| delay 330 # ||||| delay
331 # cmd pid ||||| time | caller 331 # cmd pid ||||| time | caller
332 # \ / ||||| \ | / 332 # \ / ||||| \ | /
333 <idle>-0 0d..1 0us+: trace_hardirqs_off_thunk (apic_timer_interrupt) 333 <idle>-0 0d..1 0us+: trace_hardirqs_off_thunk (apic_timer_interrupt)
334 <idle>-0 0d.s. 97us : __do_softirq (do_softirq) 334 <idle>-0 0d.s. 97us : __do_softirq (do_softirq)
335 <idle>-0 0d.s1 98us : trace_hardirqs_on (do_softirq) 335 <idle>-0 0d.s1 98us : trace_hardirqs_on (do_softirq)
336 336
337 337
338 This shows that the current tracer is "irqsoff" tracing the time 338 This shows that the current tracer is "irqsoff" tracing the time
339 for which interrupts were disabled. It gives the trace version 339 for which interrupts were disabled. It gives the trace version
340 and the version of the kernel upon which this was executed on 340 and the version of the kernel upon which this was executed on
341 (2.6.26-rc8). Then it displays the max latency in microsecs (97 341 (2.6.26-rc8). Then it displays the max latency in microsecs (97
342 us). The number of trace entries displayed and the total number 342 us). The number of trace entries displayed and the total number
343 recorded (both are three: #3/3). The type of preemption that was 343 recorded (both are three: #3/3). The type of preemption that was
344 used (PREEMPT). VP, KP, SP, and HP are always zero and are 344 used (PREEMPT). VP, KP, SP, and HP are always zero and are
345 reserved for later use. #P is the number of online CPUS (#P:2). 345 reserved for later use. #P is the number of online CPUS (#P:2).
346 346
347 The task is the process that was running when the latency 347 The task is the process that was running when the latency
348 occurred. (swapper pid: 0). 348 occurred. (swapper pid: 0).
349 349
350 The start and stop (the functions in which the interrupts were 350 The start and stop (the functions in which the interrupts were
351 disabled and enabled respectively) that caused the latencies: 351 disabled and enabled respectively) that caused the latencies:
352 352
353 apic_timer_interrupt is where the interrupts were disabled. 353 apic_timer_interrupt is where the interrupts were disabled.
354 do_softirq is where they were enabled again. 354 do_softirq is where they were enabled again.
355 355
356 The next lines after the header are the trace itself. The header 356 The next lines after the header are the trace itself. The header
357 explains which is which. 357 explains which is which.
358 358
359 cmd: The name of the process in the trace. 359 cmd: The name of the process in the trace.
360 360
361 pid: The PID of that process. 361 pid: The PID of that process.
362 362
363 CPU#: The CPU which the process was running on. 363 CPU#: The CPU which the process was running on.
364 364
365 irqs-off: 'd' interrupts are disabled. '.' otherwise. 365 irqs-off: 'd' interrupts are disabled. '.' otherwise.
366 Note: If the architecture does not support a way to 366 Note: If the architecture does not support a way to
367 read the irq flags variable, an 'X' will always 367 read the irq flags variable, an 'X' will always
368 be printed here. 368 be printed here.
369 369
370 need-resched: 'N' task need_resched is set, '.' otherwise. 370 need-resched: 'N' task need_resched is set, '.' otherwise.
371 371
372 hardirq/softirq: 372 hardirq/softirq:
373 'H' - hard irq occurred inside a softirq. 373 'H' - hard irq occurred inside a softirq.
374 'h' - hard irq is running 374 'h' - hard irq is running
375 's' - soft irq is running 375 's' - soft irq is running
376 '.' - normal context. 376 '.' - normal context.
377 377
378 preempt-depth: The level of preempt_disabled 378 preempt-depth: The level of preempt_disabled
379 379
380 The above is mostly meaningful for kernel developers. 380 The above is mostly meaningful for kernel developers.
381 381
382 time: When the latency-format option is enabled, the trace file 382 time: When the latency-format option is enabled, the trace file
383 output includes a timestamp relative to the start of the 383 output includes a timestamp relative to the start of the
384 trace. This differs from the output when latency-format 384 trace. This differs from the output when latency-format
385 is disabled, which includes an absolute timestamp. 385 is disabled, which includes an absolute timestamp.
386 386
387 delay: This is just to help catch your eye a bit better. And 387 delay: This is just to help catch your eye a bit better. And
388 needs to be fixed to be only relative to the same CPU. 388 needs to be fixed to be only relative to the same CPU.
389 The marks are determined by the difference between this 389 The marks are determined by the difference between this
390 current trace and the next trace. 390 current trace and the next trace.
391 '!' - greater than preempt_mark_thresh (default 100) 391 '!' - greater than preempt_mark_thresh (default 100)
392 '+' - greater than 1 microsecond 392 '+' - greater than 1 microsecond
393 ' ' - less than or equal to 1 microsecond. 393 ' ' - less than or equal to 1 microsecond.
394 394
395 The rest is the same as the 'trace' file. 395 The rest is the same as the 'trace' file.
396 396
397 397
398 trace_options 398 trace_options
399 ------------- 399 -------------
400 400
401 The trace_options file is used to control what gets printed in 401 The trace_options file is used to control what gets printed in
402 the trace output. To see what is available, simply cat the file: 402 the trace output. To see what is available, simply cat the file:
403 403
404 cat trace_options 404 cat trace_options
405 print-parent nosym-offset nosym-addr noverbose noraw nohex nobin \ 405 print-parent nosym-offset nosym-addr noverbose noraw nohex nobin \
406 noblock nostacktrace nosched-tree nouserstacktrace nosym-userobj 406 noblock nostacktrace nosched-tree nouserstacktrace nosym-userobj
407 407
408 To disable one of the options, echo in the option prepended with 408 To disable one of the options, echo in the option prepended with
409 "no". 409 "no".
410 410
411 echo noprint-parent > trace_options 411 echo noprint-parent > trace_options
412 412
413 To enable an option, leave off the "no". 413 To enable an option, leave off the "no".
414 414
415 echo sym-offset > trace_options 415 echo sym-offset > trace_options
416 416
417 Here are the available options: 417 Here are the available options:
418 418
419 print-parent - On function traces, display the calling (parent) 419 print-parent - On function traces, display the calling (parent)
420 function as well as the function being traced. 420 function as well as the function being traced.
421 421
422 print-parent: 422 print-parent:
423 bash-4000 [01] 1477.606694: simple_strtoul <-strict_strtoul 423 bash-4000 [01] 1477.606694: simple_strtoul <-strict_strtoul
424 424
425 noprint-parent: 425 noprint-parent:
426 bash-4000 [01] 1477.606694: simple_strtoul 426 bash-4000 [01] 1477.606694: simple_strtoul
427 427
428 428
429 sym-offset - Display not only the function name, but also the 429 sym-offset - Display not only the function name, but also the
430 offset in the function. For example, instead of 430 offset in the function. For example, instead of
431 seeing just "ktime_get", you will see 431 seeing just "ktime_get", you will see
432 "ktime_get+0xb/0x20". 432 "ktime_get+0xb/0x20".
433 433
434 sym-offset: 434 sym-offset:
435 bash-4000 [01] 1477.606694: simple_strtoul+0x6/0xa0 435 bash-4000 [01] 1477.606694: simple_strtoul+0x6/0xa0
436 436
437 sym-addr - this will also display the function address as well 437 sym-addr - this will also display the function address as well
438 as the function name. 438 as the function name.
439 439
440 sym-addr: 440 sym-addr:
441 bash-4000 [01] 1477.606694: simple_strtoul <c0339346> 441 bash-4000 [01] 1477.606694: simple_strtoul <c0339346>
442 442
443 verbose - This deals with the trace file when the 443 verbose - This deals with the trace file when the
444 latency-format option is enabled. 444 latency-format option is enabled.
445 445
446 bash 4000 1 0 00000000 00010a95 [58127d26] 1720.415ms \ 446 bash 4000 1 0 00000000 00010a95 [58127d26] 1720.415ms \
447 (+0.000ms): simple_strtoul (strict_strtoul) 447 (+0.000ms): simple_strtoul (strict_strtoul)
448 448
449 raw - This will display raw numbers. This option is best for 449 raw - This will display raw numbers. This option is best for
450 use with user applications that can translate the raw 450 use with user applications that can translate the raw
451 numbers better than having it done in the kernel. 451 numbers better than having it done in the kernel.
452 452
453 hex - Similar to raw, but the numbers will be in a hexadecimal 453 hex - Similar to raw, but the numbers will be in a hexadecimal
454 format. 454 format.
455 455
456 bin - This will print out the formats in raw binary. 456 bin - This will print out the formats in raw binary.
457 457
458 block - TBD (needs update) 458 block - TBD (needs update)
459 459
460 stacktrace - This is one of the options that changes the trace 460 stacktrace - This is one of the options that changes the trace
461 itself. When a trace is recorded, so is the stack 461 itself. When a trace is recorded, so is the stack
462 of functions. This allows for back traces of 462 of functions. This allows for back traces of
463 trace sites. 463 trace sites.
464 464
465 userstacktrace - This option changes the trace. It records a 465 userstacktrace - This option changes the trace. It records a
466 stacktrace of the current userspace thread. 466 stacktrace of the current userspace thread.
467 467
468 sym-userobj - when user stacktrace are enabled, look up which 468 sym-userobj - when user stacktrace are enabled, look up which
469 object the address belongs to, and print a 469 object the address belongs to, and print a
470 relative address. This is especially useful when 470 relative address. This is especially useful when
471 ASLR is on, otherwise you don't get a chance to 471 ASLR is on, otherwise you don't get a chance to
472 resolve the address to object/file/line after 472 resolve the address to object/file/line after
473 the app is no longer running 473 the app is no longer running
474 474
475 The lookup is performed when you read 475 The lookup is performed when you read
476 trace,trace_pipe. Example: 476 trace,trace_pipe. Example:
477 477
478 a.out-1623 [000] 40874.465068: /root/a.out[+0x480] <-/root/a.out[+0 478 a.out-1623 [000] 40874.465068: /root/a.out[+0x480] <-/root/a.out[+0
479 x494] <- /root/a.out[+0x4a8] <- /lib/libc-2.7.so[+0x1e1a6] 479 x494] <- /root/a.out[+0x4a8] <- /lib/libc-2.7.so[+0x1e1a6]
480 480
481 sched-tree - trace all tasks that are on the runqueue, at 481 sched-tree - trace all tasks that are on the runqueue, at
482 every scheduling event. Will add overhead if 482 every scheduling event. Will add overhead if
483 there's a lot of tasks running at once. 483 there's a lot of tasks running at once.
484 484
485 latency-format - This option changes the trace. When 485 latency-format - This option changes the trace. When
486 it is enabled, the trace displays 486 it is enabled, the trace displays
487 additional information about the 487 additional information about the
488 latencies, as described in "Latency 488 latencies, as described in "Latency
489 trace format". 489 trace format".
490 490
491 sched_switch 491 sched_switch
492 ------------ 492 ------------
493 493
494 This tracer simply records schedule switches. Here is an example 494 This tracer simply records schedule switches. Here is an example
495 of how to use it. 495 of how to use it.
496 496
497 # echo sched_switch > current_tracer 497 # echo sched_switch > current_tracer
498 # echo 1 > tracing_enabled 498 # echo 1 > tracing_enabled
499 # sleep 1 499 # sleep 1
500 # echo 0 > tracing_enabled 500 # echo 0 > tracing_enabled
501 # cat trace 501 # cat trace
502 502
503 # tracer: sched_switch 503 # tracer: sched_switch
504 # 504 #
505 # TASK-PID CPU# TIMESTAMP FUNCTION 505 # TASK-PID CPU# TIMESTAMP FUNCTION
506 # | | | | | 506 # | | | | |
507 bash-3997 [01] 240.132281: 3997:120:R + 4055:120:R 507 bash-3997 [01] 240.132281: 3997:120:R + 4055:120:R
508 bash-3997 [01] 240.132284: 3997:120:R ==> 4055:120:R 508 bash-3997 [01] 240.132284: 3997:120:R ==> 4055:120:R
509 sleep-4055 [01] 240.132371: 4055:120:S ==> 3997:120:R 509 sleep-4055 [01] 240.132371: 4055:120:S ==> 3997:120:R
510 bash-3997 [01] 240.132454: 3997:120:R + 4055:120:S 510 bash-3997 [01] 240.132454: 3997:120:R + 4055:120:S
511 bash-3997 [01] 240.132457: 3997:120:R ==> 4055:120:R 511 bash-3997 [01] 240.132457: 3997:120:R ==> 4055:120:R
512 sleep-4055 [01] 240.132460: 4055:120:D ==> 3997:120:R 512 sleep-4055 [01] 240.132460: 4055:120:D ==> 3997:120:R
513 bash-3997 [01] 240.132463: 3997:120:R + 4055:120:D 513 bash-3997 [01] 240.132463: 3997:120:R + 4055:120:D
514 bash-3997 [01] 240.132465: 3997:120:R ==> 4055:120:R 514 bash-3997 [01] 240.132465: 3997:120:R ==> 4055:120:R
515 <idle>-0 [00] 240.132589: 0:140:R + 4:115:S 515 <idle>-0 [00] 240.132589: 0:140:R + 4:115:S
516 <idle>-0 [00] 240.132591: 0:140:R ==> 4:115:R 516 <idle>-0 [00] 240.132591: 0:140:R ==> 4:115:R
517 ksoftirqd/0-4 [00] 240.132595: 4:115:S ==> 0:140:R 517 ksoftirqd/0-4 [00] 240.132595: 4:115:S ==> 0:140:R
518 <idle>-0 [00] 240.132598: 0:140:R + 4:115:S 518 <idle>-0 [00] 240.132598: 0:140:R + 4:115:S
519 <idle>-0 [00] 240.132599: 0:140:R ==> 4:115:R 519 <idle>-0 [00] 240.132599: 0:140:R ==> 4:115:R
520 ksoftirqd/0-4 [00] 240.132603: 4:115:S ==> 0:140:R 520 ksoftirqd/0-4 [00] 240.132603: 4:115:S ==> 0:140:R
521 sleep-4055 [01] 240.133058: 4055:120:S ==> 3997:120:R 521 sleep-4055 [01] 240.133058: 4055:120:S ==> 3997:120:R
522 [...] 522 [...]
523 523
524 524
525 As we have discussed previously about this format, the header 525 As we have discussed previously about this format, the header
526 shows the name of the trace and points to the options. The 526 shows the name of the trace and points to the options. The
527 "FUNCTION" is a misnomer since here it represents the wake ups 527 "FUNCTION" is a misnomer since here it represents the wake ups
528 and context switches. 528 and context switches.
529 529
530 The sched_switch file only lists the wake ups (represented with 530 The sched_switch file only lists the wake ups (represented with
531 '+') and context switches ('==>') with the previous task or 531 '+') and context switches ('==>') with the previous task or
532 current task first followed by the next task or task waking up. 532 current task first followed by the next task or task waking up.
533 The format for both of these is PID:KERNEL-PRIO:TASK-STATE. 533 The format for both of these is PID:KERNEL-PRIO:TASK-STATE.
534 Remember that the KERNEL-PRIO is the inverse of the actual 534 Remember that the KERNEL-PRIO is the inverse of the actual
535 priority with zero (0) being the highest priority and the nice 535 priority with zero (0) being the highest priority and the nice
536 values starting at 100 (nice -20). Below is a quick chart to map 536 values starting at 100 (nice -20). Below is a quick chart to map
537 the kernel priority to user land priorities. 537 the kernel priority to user land priorities.
538 538
539 Kernel Space User Space 539 Kernel Space User Space
540 =============================================================== 540 ===============================================================
541 0(high) to 98(low) user RT priority 99(high) to 1(low) 541 0(high) to 98(low) user RT priority 99(high) to 1(low)
542 with SCHED_RR or SCHED_FIFO 542 with SCHED_RR or SCHED_FIFO
543 --------------------------------------------------------------- 543 ---------------------------------------------------------------
544 99 sched_priority is not used in scheduling 544 99 sched_priority is not used in scheduling
545 decisions(it must be specified as 0) 545 decisions(it must be specified as 0)
546 --------------------------------------------------------------- 546 ---------------------------------------------------------------
547 100(high) to 139(low) user nice -20(high) to 19(low) 547 100(high) to 139(low) user nice -20(high) to 19(low)
548 --------------------------------------------------------------- 548 ---------------------------------------------------------------
549 140 idle task priority 549 140 idle task priority
550 --------------------------------------------------------------- 550 ---------------------------------------------------------------
551 551
552 The task states are: 552 The task states are:
553 553
554 R - running : wants to run, may not actually be running 554 R - running : wants to run, may not actually be running
555 S - sleep : process is waiting to be woken up (handles signals) 555 S - sleep : process is waiting to be woken up (handles signals)
556 D - disk sleep (uninterruptible sleep) : process must be woken up 556 D - disk sleep (uninterruptible sleep) : process must be woken up
557 (ignores signals) 557 (ignores signals)
558 T - stopped : process suspended 558 T - stopped : process suspended
559 t - traced : process is being traced (with something like gdb) 559 t - traced : process is being traced (with something like gdb)
560 Z - zombie : process waiting to be cleaned up 560 Z - zombie : process waiting to be cleaned up
561 X - unknown 561 X - unknown
562 562
563 563
564 ftrace_enabled 564 ftrace_enabled
565 -------------- 565 --------------
566 566
567 The following tracers (listed below) give different output 567 The following tracers (listed below) give different output
568 depending on whether or not the sysctl ftrace_enabled is set. To 568 depending on whether or not the sysctl ftrace_enabled is set. To
569 set ftrace_enabled, one can either use the sysctl function or 569 set ftrace_enabled, one can either use the sysctl function or
570 set it via the proc file system interface. 570 set it via the proc file system interface.
571 571
572 sysctl kernel.ftrace_enabled=1 572 sysctl kernel.ftrace_enabled=1
573 573
574 or 574 or
575 575
576 echo 1 > /proc/sys/kernel/ftrace_enabled 576 echo 1 > /proc/sys/kernel/ftrace_enabled
577 577
578 To disable ftrace_enabled simply replace the '1' with '0' in the 578 To disable ftrace_enabled simply replace the '1' with '0' in the
579 above commands. 579 above commands.
580 580
581 When ftrace_enabled is set the tracers will also record the 581 When ftrace_enabled is set the tracers will also record the
582 functions that are within the trace. The descriptions of the 582 functions that are within the trace. The descriptions of the
583 tracers will also show an example with ftrace enabled. 583 tracers will also show an example with ftrace enabled.
584 584
585 585
586 irqsoff 586 irqsoff
587 ------- 587 -------
588 588
589 When interrupts are disabled, the CPU can not react to any other 589 When interrupts are disabled, the CPU can not react to any other
590 external event (besides NMIs and SMIs). This prevents the timer 590 external event (besides NMIs and SMIs). This prevents the timer
591 interrupt from triggering or the mouse interrupt from letting 591 interrupt from triggering or the mouse interrupt from letting
592 the kernel know of a new mouse event. The result is a latency 592 the kernel know of a new mouse event. The result is a latency
593 with the reaction time. 593 with the reaction time.
594 594
595 The irqsoff tracer tracks the time for which interrupts are 595 The irqsoff tracer tracks the time for which interrupts are
596 disabled. When a new maximum latency is hit, the tracer saves 596 disabled. When a new maximum latency is hit, the tracer saves
597 the trace leading up to that latency point so that every time a 597 the trace leading up to that latency point so that every time a
598 new maximum is reached, the old saved trace is discarded and the 598 new maximum is reached, the old saved trace is discarded and the
599 new trace is saved. 599 new trace is saved.
600 600
601 To reset the maximum, echo 0 into tracing_max_latency. Here is 601 To reset the maximum, echo 0 into tracing_max_latency. Here is
602 an example: 602 an example:
603 603
604 # echo irqsoff > current_tracer 604 # echo irqsoff > current_tracer
605 # echo latency-format > trace_options 605 # echo latency-format > trace_options
606 # echo 0 > tracing_max_latency 606 # echo 0 > tracing_max_latency
607 # echo 1 > tracing_enabled 607 # echo 1 > tracing_enabled
608 # ls -ltr 608 # ls -ltr
609 [...] 609 [...]
610 # echo 0 > tracing_enabled 610 # echo 0 > tracing_enabled
611 # cat trace 611 # cat trace
612 # tracer: irqsoff 612 # tracer: irqsoff
613 # 613 #
614 irqsoff latency trace v1.1.5 on 2.6.26 614 irqsoff latency trace v1.1.5 on 2.6.26
615 -------------------------------------------------------------------- 615 --------------------------------------------------------------------
616 latency: 12 us, #3/3, CPU#1 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:2) 616 latency: 12 us, #3/3, CPU#1 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:2)
617 ----------------- 617 -----------------
618 | task: bash-3730 (uid:0 nice:0 policy:0 rt_prio:0) 618 | task: bash-3730 (uid:0 nice:0 policy:0 rt_prio:0)
619 ----------------- 619 -----------------
620 => started at: sys_setpgid 620 => started at: sys_setpgid
621 => ended at: sys_setpgid 621 => ended at: sys_setpgid
622 622
623 # _------=> CPU# 623 # _------=> CPU#
624 # / _-----=> irqs-off 624 # / _-----=> irqs-off
625 # | / _----=> need-resched 625 # | / _----=> need-resched
626 # || / _---=> hardirq/softirq 626 # || / _---=> hardirq/softirq
627 # ||| / _--=> preempt-depth 627 # ||| / _--=> preempt-depth
628 # |||| / 628 # |||| /
629 # ||||| delay 629 # ||||| delay
630 # cmd pid ||||| time | caller 630 # cmd pid ||||| time | caller
631 # \ / ||||| \ | / 631 # \ / ||||| \ | /
632 bash-3730 1d... 0us : _write_lock_irq (sys_setpgid) 632 bash-3730 1d... 0us : _write_lock_irq (sys_setpgid)
633 bash-3730 1d..1 1us+: _write_unlock_irq (sys_setpgid) 633 bash-3730 1d..1 1us+: _write_unlock_irq (sys_setpgid)
634 bash-3730 1d..2 14us : trace_hardirqs_on (sys_setpgid) 634 bash-3730 1d..2 14us : trace_hardirqs_on (sys_setpgid)
635 635
636 636
637 Here we see that that we had a latency of 12 microsecs (which is 637 Here we see that that we had a latency of 12 microsecs (which is
638 very good). The _write_lock_irq in sys_setpgid disabled 638 very good). The _write_lock_irq in sys_setpgid disabled
639 interrupts. The difference between the 12 and the displayed 639 interrupts. The difference between the 12 and the displayed
640 timestamp 14us occurred because the clock was incremented 640 timestamp 14us occurred because the clock was incremented
641 between the time of recording the max latency and the time of 641 between the time of recording the max latency and the time of
642 recording the function that had that latency. 642 recording the function that had that latency.
643 643
644 Note the above example had ftrace_enabled not set. If we set the 644 Note the above example had ftrace_enabled not set. If we set the
645 ftrace_enabled, we get a much larger output: 645 ftrace_enabled, we get a much larger output:
646 646
647 # tracer: irqsoff 647 # tracer: irqsoff
648 # 648 #
649 irqsoff latency trace v1.1.5 on 2.6.26-rc8 649 irqsoff latency trace v1.1.5 on 2.6.26-rc8
650 -------------------------------------------------------------------- 650 --------------------------------------------------------------------
651 latency: 50 us, #101/101, CPU#0 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:2) 651 latency: 50 us, #101/101, CPU#0 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:2)
652 ----------------- 652 -----------------
653 | task: ls-4339 (uid:0 nice:0 policy:0 rt_prio:0) 653 | task: ls-4339 (uid:0 nice:0 policy:0 rt_prio:0)
654 ----------------- 654 -----------------
655 => started at: __alloc_pages_internal 655 => started at: __alloc_pages_internal
656 => ended at: __alloc_pages_internal 656 => ended at: __alloc_pages_internal
657 657
658 # _------=> CPU# 658 # _------=> CPU#
659 # / _-----=> irqs-off 659 # / _-----=> irqs-off
660 # | / _----=> need-resched 660 # | / _----=> need-resched
661 # || / _---=> hardirq/softirq 661 # || / _---=> hardirq/softirq
662 # ||| / _--=> preempt-depth 662 # ||| / _--=> preempt-depth
663 # |||| / 663 # |||| /
664 # ||||| delay 664 # ||||| delay
665 # cmd pid ||||| time | caller 665 # cmd pid ||||| time | caller
666 # \ / ||||| \ | / 666 # \ / ||||| \ | /
667 ls-4339 0...1 0us+: get_page_from_freelist (__alloc_pages_internal) 667 ls-4339 0...1 0us+: get_page_from_freelist (__alloc_pages_internal)
668 ls-4339 0d..1 3us : rmqueue_bulk (get_page_from_freelist) 668 ls-4339 0d..1 3us : rmqueue_bulk (get_page_from_freelist)
669 ls-4339 0d..1 3us : _spin_lock (rmqueue_bulk) 669 ls-4339 0d..1 3us : _spin_lock (rmqueue_bulk)
670 ls-4339 0d..1 4us : add_preempt_count (_spin_lock) 670 ls-4339 0d..1 4us : add_preempt_count (_spin_lock)
671 ls-4339 0d..2 4us : __rmqueue (rmqueue_bulk) 671 ls-4339 0d..2 4us : __rmqueue (rmqueue_bulk)
672 ls-4339 0d..2 5us : __rmqueue_smallest (__rmqueue) 672 ls-4339 0d..2 5us : __rmqueue_smallest (__rmqueue)
673 ls-4339 0d..2 5us : __mod_zone_page_state (__rmqueue_smallest) 673 ls-4339 0d..2 5us : __mod_zone_page_state (__rmqueue_smallest)
674 ls-4339 0d..2 6us : __rmqueue (rmqueue_bulk) 674 ls-4339 0d..2 6us : __rmqueue (rmqueue_bulk)
675 ls-4339 0d..2 6us : __rmqueue_smallest (__rmqueue) 675 ls-4339 0d..2 6us : __rmqueue_smallest (__rmqueue)
676 ls-4339 0d..2 7us : __mod_zone_page_state (__rmqueue_smallest) 676 ls-4339 0d..2 7us : __mod_zone_page_state (__rmqueue_smallest)
677 ls-4339 0d..2 7us : __rmqueue (rmqueue_bulk) 677 ls-4339 0d..2 7us : __rmqueue (rmqueue_bulk)
678 ls-4339 0d..2 8us : __rmqueue_smallest (__rmqueue) 678 ls-4339 0d..2 8us : __rmqueue_smallest (__rmqueue)
679 [...] 679 [...]
680 ls-4339 0d..2 46us : __rmqueue_smallest (__rmqueue) 680 ls-4339 0d..2 46us : __rmqueue_smallest (__rmqueue)
681 ls-4339 0d..2 47us : __mod_zone_page_state (__rmqueue_smallest) 681 ls-4339 0d..2 47us : __mod_zone_page_state (__rmqueue_smallest)
682 ls-4339 0d..2 47us : __rmqueue (rmqueue_bulk) 682 ls-4339 0d..2 47us : __rmqueue (rmqueue_bulk)
683 ls-4339 0d..2 48us : __rmqueue_smallest (__rmqueue) 683 ls-4339 0d..2 48us : __rmqueue_smallest (__rmqueue)
684 ls-4339 0d..2 48us : __mod_zone_page_state (__rmqueue_smallest) 684 ls-4339 0d..2 48us : __mod_zone_page_state (__rmqueue_smallest)
685 ls-4339 0d..2 49us : _spin_unlock (rmqueue_bulk) 685 ls-4339 0d..2 49us : _spin_unlock (rmqueue_bulk)
686 ls-4339 0d..2 49us : sub_preempt_count (_spin_unlock) 686 ls-4339 0d..2 49us : sub_preempt_count (_spin_unlock)
687 ls-4339 0d..1 50us : get_page_from_freelist (__alloc_pages_internal) 687 ls-4339 0d..1 50us : get_page_from_freelist (__alloc_pages_internal)
688 ls-4339 0d..2 51us : trace_hardirqs_on (__alloc_pages_internal) 688 ls-4339 0d..2 51us : trace_hardirqs_on (__alloc_pages_internal)
689 689
690 690
691 691
692 Here we traced a 50 microsecond latency. But we also see all the 692 Here we traced a 50 microsecond latency. But we also see all the
693 functions that were called during that time. Note that by 693 functions that were called during that time. Note that by
694 enabling function tracing, we incur an added overhead. This 694 enabling function tracing, we incur an added overhead. This
695 overhead may extend the latency times. But nevertheless, this 695 overhead may extend the latency times. But nevertheless, this
696 trace has provided some very helpful debugging information. 696 trace has provided some very helpful debugging information.
697 697
698 698
699 preemptoff 699 preemptoff
700 ---------- 700 ----------
701 701
702 When preemption is disabled, we may be able to receive 702 When preemption is disabled, we may be able to receive
703 interrupts but the task cannot be preempted and a higher 703 interrupts but the task cannot be preempted and a higher
704 priority task must wait for preemption to be enabled again 704 priority task must wait for preemption to be enabled again
705 before it can preempt a lower priority task. 705 before it can preempt a lower priority task.
706 706
707 The preemptoff tracer traces the places that disable preemption. 707 The preemptoff tracer traces the places that disable preemption.
708 Like the irqsoff tracer, it records the maximum latency for 708 Like the irqsoff tracer, it records the maximum latency for
709 which preemption was disabled. The control of preemptoff tracer 709 which preemption was disabled. The control of preemptoff tracer
710 is much like the irqsoff tracer. 710 is much like the irqsoff tracer.
711 711
712 # echo preemptoff > current_tracer 712 # echo preemptoff > current_tracer
713 # echo latency-format > trace_options 713 # echo latency-format > trace_options
714 # echo 0 > tracing_max_latency 714 # echo 0 > tracing_max_latency
715 # echo 1 > tracing_enabled 715 # echo 1 > tracing_enabled
716 # ls -ltr 716 # ls -ltr
717 [...] 717 [...]
718 # echo 0 > tracing_enabled 718 # echo 0 > tracing_enabled
719 # cat trace 719 # cat trace
720 # tracer: preemptoff 720 # tracer: preemptoff
721 # 721 #
722 preemptoff latency trace v1.1.5 on 2.6.26-rc8 722 preemptoff latency trace v1.1.5 on 2.6.26-rc8
723 -------------------------------------------------------------------- 723 --------------------------------------------------------------------
724 latency: 29 us, #3/3, CPU#0 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:2) 724 latency: 29 us, #3/3, CPU#0 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:2)
725 ----------------- 725 -----------------
726 | task: sshd-4261 (uid:0 nice:0 policy:0 rt_prio:0) 726 | task: sshd-4261 (uid:0 nice:0 policy:0 rt_prio:0)
727 ----------------- 727 -----------------
728 => started at: do_IRQ 728 => started at: do_IRQ
729 => ended at: __do_softirq 729 => ended at: __do_softirq
730 730
731 # _------=> CPU# 731 # _------=> CPU#
732 # / _-----=> irqs-off 732 # / _-----=> irqs-off
733 # | / _----=> need-resched 733 # | / _----=> need-resched
734 # || / _---=> hardirq/softirq 734 # || / _---=> hardirq/softirq
735 # ||| / _--=> preempt-depth 735 # ||| / _--=> preempt-depth
736 # |||| / 736 # |||| /
737 # ||||| delay 737 # ||||| delay
738 # cmd pid ||||| time | caller 738 # cmd pid ||||| time | caller
739 # \ / ||||| \ | / 739 # \ / ||||| \ | /
740 sshd-4261 0d.h. 0us+: irq_enter (do_IRQ) 740 sshd-4261 0d.h. 0us+: irq_enter (do_IRQ)
741 sshd-4261 0d.s. 29us : _local_bh_enable (__do_softirq) 741 sshd-4261 0d.s. 29us : _local_bh_enable (__do_softirq)
742 sshd-4261 0d.s1 30us : trace_preempt_on (__do_softirq) 742 sshd-4261 0d.s1 30us : trace_preempt_on (__do_softirq)
743 743
744 744
745 This has some more changes. Preemption was disabled when an 745 This has some more changes. Preemption was disabled when an
746 interrupt came in (notice the 'h'), and was enabled while doing 746 interrupt came in (notice the 'h'), and was enabled while doing
747 a softirq. (notice the 's'). But we also see that interrupts 747 a softirq. (notice the 's'). But we also see that interrupts
748 have been disabled when entering the preempt off section and 748 have been disabled when entering the preempt off section and
749 leaving it (the 'd'). We do not know if interrupts were enabled 749 leaving it (the 'd'). We do not know if interrupts were enabled
750 in the mean time. 750 in the mean time.
751 751
752 # tracer: preemptoff 752 # tracer: preemptoff
753 # 753 #
754 preemptoff latency trace v1.1.5 on 2.6.26-rc8 754 preemptoff latency trace v1.1.5 on 2.6.26-rc8
755 -------------------------------------------------------------------- 755 --------------------------------------------------------------------
756 latency: 63 us, #87/87, CPU#0 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:2) 756 latency: 63 us, #87/87, CPU#0 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:2)
757 ----------------- 757 -----------------
758 | task: sshd-4261 (uid:0 nice:0 policy:0 rt_prio:0) 758 | task: sshd-4261 (uid:0 nice:0 policy:0 rt_prio:0)
759 ----------------- 759 -----------------
760 => started at: remove_wait_queue 760 => started at: remove_wait_queue
761 => ended at: __do_softirq 761 => ended at: __do_softirq
762 762
763 # _------=> CPU# 763 # _------=> CPU#
764 # / _-----=> irqs-off 764 # / _-----=> irqs-off
765 # | / _----=> need-resched 765 # | / _----=> need-resched
766 # || / _---=> hardirq/softirq 766 # || / _---=> hardirq/softirq
767 # ||| / _--=> preempt-depth 767 # ||| / _--=> preempt-depth
768 # |||| / 768 # |||| /
769 # ||||| delay 769 # ||||| delay
770 # cmd pid ||||| time | caller 770 # cmd pid ||||| time | caller
771 # \ / ||||| \ | / 771 # \ / ||||| \ | /
772 sshd-4261 0d..1 0us : _spin_lock_irqsave (remove_wait_queue) 772 sshd-4261 0d..1 0us : _spin_lock_irqsave (remove_wait_queue)
773 sshd-4261 0d..1 1us : _spin_unlock_irqrestore (remove_wait_queue) 773 sshd-4261 0d..1 1us : _spin_unlock_irqrestore (remove_wait_queue)
774 sshd-4261 0d..1 2us : do_IRQ (common_interrupt) 774 sshd-4261 0d..1 2us : do_IRQ (common_interrupt)
775 sshd-4261 0d..1 2us : irq_enter (do_IRQ) 775 sshd-4261 0d..1 2us : irq_enter (do_IRQ)
776 sshd-4261 0d..1 2us : idle_cpu (irq_enter) 776 sshd-4261 0d..1 2us : idle_cpu (irq_enter)
777 sshd-4261 0d..1 3us : add_preempt_count (irq_enter) 777 sshd-4261 0d..1 3us : add_preempt_count (irq_enter)
778 sshd-4261 0d.h1 3us : idle_cpu (irq_enter) 778 sshd-4261 0d.h1 3us : idle_cpu (irq_enter)
779 sshd-4261 0d.h. 4us : handle_fasteoi_irq (do_IRQ) 779 sshd-4261 0d.h. 4us : handle_fasteoi_irq (do_IRQ)
780 [...] 780 [...]
781 sshd-4261 0d.h. 12us : add_preempt_count (_spin_lock) 781 sshd-4261 0d.h. 12us : add_preempt_count (_spin_lock)
782 sshd-4261 0d.h1 12us : ack_ioapic_quirk_irq (handle_fasteoi_irq) 782 sshd-4261 0d.h1 12us : ack_ioapic_quirk_irq (handle_fasteoi_irq)
783 sshd-4261 0d.h1 13us : move_native_irq (ack_ioapic_quirk_irq) 783 sshd-4261 0d.h1 13us : move_native_irq (ack_ioapic_quirk_irq)
784 sshd-4261 0d.h1 13us : _spin_unlock (handle_fasteoi_irq) 784 sshd-4261 0d.h1 13us : _spin_unlock (handle_fasteoi_irq)
785 sshd-4261 0d.h1 14us : sub_preempt_count (_spin_unlock) 785 sshd-4261 0d.h1 14us : sub_preempt_count (_spin_unlock)
786 sshd-4261 0d.h1 14us : irq_exit (do_IRQ) 786 sshd-4261 0d.h1 14us : irq_exit (do_IRQ)
787 sshd-4261 0d.h1 15us : sub_preempt_count (irq_exit) 787 sshd-4261 0d.h1 15us : sub_preempt_count (irq_exit)
788 sshd-4261 0d..2 15us : do_softirq (irq_exit) 788 sshd-4261 0d..2 15us : do_softirq (irq_exit)
789 sshd-4261 0d... 15us : __do_softirq (do_softirq) 789 sshd-4261 0d... 15us : __do_softirq (do_softirq)
790 sshd-4261 0d... 16us : __local_bh_disable (__do_softirq) 790 sshd-4261 0d... 16us : __local_bh_disable (__do_softirq)
791 sshd-4261 0d... 16us+: add_preempt_count (__local_bh_disable) 791 sshd-4261 0d... 16us+: add_preempt_count (__local_bh_disable)
792 sshd-4261 0d.s4 20us : add_preempt_count (__local_bh_disable) 792 sshd-4261 0d.s4 20us : add_preempt_count (__local_bh_disable)
793 sshd-4261 0d.s4 21us : sub_preempt_count (local_bh_enable) 793 sshd-4261 0d.s4 21us : sub_preempt_count (local_bh_enable)
794 sshd-4261 0d.s5 21us : sub_preempt_count (local_bh_enable) 794 sshd-4261 0d.s5 21us : sub_preempt_count (local_bh_enable)
795 [...] 795 [...]
796 sshd-4261 0d.s6 41us : add_preempt_count (__local_bh_disable) 796 sshd-4261 0d.s6 41us : add_preempt_count (__local_bh_disable)
797 sshd-4261 0d.s6 42us : sub_preempt_count (local_bh_enable) 797 sshd-4261 0d.s6 42us : sub_preempt_count (local_bh_enable)
798 sshd-4261 0d.s7 42us : sub_preempt_count (local_bh_enable) 798 sshd-4261 0d.s7 42us : sub_preempt_count (local_bh_enable)
799 sshd-4261 0d.s5 43us : add_preempt_count (__local_bh_disable) 799 sshd-4261 0d.s5 43us : add_preempt_count (__local_bh_disable)
800 sshd-4261 0d.s5 43us : sub_preempt_count (local_bh_enable_ip) 800 sshd-4261 0d.s5 43us : sub_preempt_count (local_bh_enable_ip)
801 sshd-4261 0d.s6 44us : sub_preempt_count (local_bh_enable_ip) 801 sshd-4261 0d.s6 44us : sub_preempt_count (local_bh_enable_ip)
802 sshd-4261 0d.s5 44us : add_preempt_count (__local_bh_disable) 802 sshd-4261 0d.s5 44us : add_preempt_count (__local_bh_disable)
803 sshd-4261 0d.s5 45us : sub_preempt_count (local_bh_enable) 803 sshd-4261 0d.s5 45us : sub_preempt_count (local_bh_enable)
804 [...] 804 [...]
805 sshd-4261 0d.s. 63us : _local_bh_enable (__do_softirq) 805 sshd-4261 0d.s. 63us : _local_bh_enable (__do_softirq)
806 sshd-4261 0d.s1 64us : trace_preempt_on (__do_softirq) 806 sshd-4261 0d.s1 64us : trace_preempt_on (__do_softirq)
807 807
808 808
809 The above is an example of the preemptoff trace with 809 The above is an example of the preemptoff trace with
810 ftrace_enabled set. Here we see that interrupts were disabled 810 ftrace_enabled set. Here we see that interrupts were disabled
811 the entire time. The irq_enter code lets us know that we entered 811 the entire time. The irq_enter code lets us know that we entered
812 an interrupt 'h'. Before that, the functions being traced still 812 an interrupt 'h'. Before that, the functions being traced still
813 show that it is not in an interrupt, but we can see from the 813 show that it is not in an interrupt, but we can see from the
814 functions themselves that this is not the case. 814 functions themselves that this is not the case.
815 815
816 Notice that __do_softirq when called does not have a 816 Notice that __do_softirq when called does not have a
817 preempt_count. It may seem that we missed a preempt enabling. 817 preempt_count. It may seem that we missed a preempt enabling.
818 What really happened is that the preempt count is held on the 818 What really happened is that the preempt count is held on the
819 thread's stack and we switched to the softirq stack (4K stacks 819 thread's stack and we switched to the softirq stack (4K stacks
820 in effect). The code does not copy the preempt count, but 820 in effect). The code does not copy the preempt count, but
821 because interrupts are disabled, we do not need to worry about 821 because interrupts are disabled, we do not need to worry about
822 it. Having a tracer like this is good for letting people know 822 it. Having a tracer like this is good for letting people know
823 what really happens inside the kernel. 823 what really happens inside the kernel.
824 824
825 825
826 preemptirqsoff 826 preemptirqsoff
827 -------------- 827 --------------
828 828
829 Knowing the locations that have interrupts disabled or 829 Knowing the locations that have interrupts disabled or
830 preemption disabled for the longest times is helpful. But 830 preemption disabled for the longest times is helpful. But
831 sometimes we would like to know when either preemption and/or 831 sometimes we would like to know when either preemption and/or
832 interrupts are disabled. 832 interrupts are disabled.
833 833
834 Consider the following code: 834 Consider the following code:
835 835
836 local_irq_disable(); 836 local_irq_disable();
837 call_function_with_irqs_off(); 837 call_function_with_irqs_off();
838 preempt_disable(); 838 preempt_disable();
839 call_function_with_irqs_and_preemption_off(); 839 call_function_with_irqs_and_preemption_off();
840 local_irq_enable(); 840 local_irq_enable();
841 call_function_with_preemption_off(); 841 call_function_with_preemption_off();
842 preempt_enable(); 842 preempt_enable();
843 843
844 The irqsoff tracer will record the total length of 844 The irqsoff tracer will record the total length of
845 call_function_with_irqs_off() and 845 call_function_with_irqs_off() and
846 call_function_with_irqs_and_preemption_off(). 846 call_function_with_irqs_and_preemption_off().
847 847
848 The preemptoff tracer will record the total length of 848 The preemptoff tracer will record the total length of
849 call_function_with_irqs_and_preemption_off() and 849 call_function_with_irqs_and_preemption_off() and
850 call_function_with_preemption_off(). 850 call_function_with_preemption_off().
851 851
852 But neither will trace the time that interrupts and/or 852 But neither will trace the time that interrupts and/or
853 preemption is disabled. This total time is the time that we can 853 preemption is disabled. This total time is the time that we can
854 not schedule. To record this time, use the preemptirqsoff 854 not schedule. To record this time, use the preemptirqsoff
855 tracer. 855 tracer.
856 856
857 Again, using this trace is much like the irqsoff and preemptoff 857 Again, using this trace is much like the irqsoff and preemptoff
858 tracers. 858 tracers.
859 859
860 # echo preemptirqsoff > current_tracer 860 # echo preemptirqsoff > current_tracer
861 # echo latency-format > trace_options 861 # echo latency-format > trace_options
862 # echo 0 > tracing_max_latency 862 # echo 0 > tracing_max_latency
863 # echo 1 > tracing_enabled 863 # echo 1 > tracing_enabled
864 # ls -ltr 864 # ls -ltr
865 [...] 865 [...]
866 # echo 0 > tracing_enabled 866 # echo 0 > tracing_enabled
867 # cat trace 867 # cat trace
868 # tracer: preemptirqsoff 868 # tracer: preemptirqsoff
869 # 869 #
870 preemptirqsoff latency trace v1.1.5 on 2.6.26-rc8 870 preemptirqsoff latency trace v1.1.5 on 2.6.26-rc8
871 -------------------------------------------------------------------- 871 --------------------------------------------------------------------
872 latency: 293 us, #3/3, CPU#0 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:2) 872 latency: 293 us, #3/3, CPU#0 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:2)
873 ----------------- 873 -----------------
874 | task: ls-4860 (uid:0 nice:0 policy:0 rt_prio:0) 874 | task: ls-4860 (uid:0 nice:0 policy:0 rt_prio:0)
875 ----------------- 875 -----------------
876 => started at: apic_timer_interrupt 876 => started at: apic_timer_interrupt
877 => ended at: __do_softirq 877 => ended at: __do_softirq
878 878
879 # _------=> CPU# 879 # _------=> CPU#
880 # / _-----=> irqs-off 880 # / _-----=> irqs-off
881 # | / _----=> need-resched 881 # | / _----=> need-resched
882 # || / _---=> hardirq/softirq 882 # || / _---=> hardirq/softirq
883 # ||| / _--=> preempt-depth 883 # ||| / _--=> preempt-depth
884 # |||| / 884 # |||| /
885 # ||||| delay 885 # ||||| delay
886 # cmd pid ||||| time | caller 886 # cmd pid ||||| time | caller
887 # \ / ||||| \ | / 887 # \ / ||||| \ | /
888 ls-4860 0d... 0us!: trace_hardirqs_off_thunk (apic_timer_interrupt) 888 ls-4860 0d... 0us!: trace_hardirqs_off_thunk (apic_timer_interrupt)
889 ls-4860 0d.s. 294us : _local_bh_enable (__do_softirq) 889 ls-4860 0d.s. 294us : _local_bh_enable (__do_softirq)
890 ls-4860 0d.s1 294us : trace_preempt_on (__do_softirq) 890 ls-4860 0d.s1 294us : trace_preempt_on (__do_softirq)
891 891
892 892
893 893
894 The trace_hardirqs_off_thunk is called from assembly on x86 when 894 The trace_hardirqs_off_thunk is called from assembly on x86 when
895 interrupts are disabled in the assembly code. Without the 895 interrupts are disabled in the assembly code. Without the
896 function tracing, we do not know if interrupts were enabled 896 function tracing, we do not know if interrupts were enabled
897 within the preemption points. We do see that it started with 897 within the preemption points. We do see that it started with
898 preemption enabled. 898 preemption enabled.
899 899
900 Here is a trace with ftrace_enabled set: 900 Here is a trace with ftrace_enabled set:
901 901
902 902
903 # tracer: preemptirqsoff 903 # tracer: preemptirqsoff
904 # 904 #
905 preemptirqsoff latency trace v1.1.5 on 2.6.26-rc8 905 preemptirqsoff latency trace v1.1.5 on 2.6.26-rc8
906 -------------------------------------------------------------------- 906 --------------------------------------------------------------------
907 latency: 105 us, #183/183, CPU#0 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:2) 907 latency: 105 us, #183/183, CPU#0 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:2)
908 ----------------- 908 -----------------
909 | task: sshd-4261 (uid:0 nice:0 policy:0 rt_prio:0) 909 | task: sshd-4261 (uid:0 nice:0 policy:0 rt_prio:0)
910 ----------------- 910 -----------------
911 => started at: write_chan 911 => started at: write_chan
912 => ended at: __do_softirq 912 => ended at: __do_softirq
913 913
914 # _------=> CPU# 914 # _------=> CPU#
915 # / _-----=> irqs-off 915 # / _-----=> irqs-off
916 # | / _----=> need-resched 916 # | / _----=> need-resched
917 # || / _---=> hardirq/softirq 917 # || / _---=> hardirq/softirq
918 # ||| / _--=> preempt-depth 918 # ||| / _--=> preempt-depth
919 # |||| / 919 # |||| /
920 # ||||| delay 920 # ||||| delay
921 # cmd pid ||||| time | caller 921 # cmd pid ||||| time | caller
922 # \ / ||||| \ | / 922 # \ / ||||| \ | /
923 ls-4473 0.N.. 0us : preempt_schedule (write_chan) 923 ls-4473 0.N.. 0us : preempt_schedule (write_chan)
924 ls-4473 0dN.1 1us : _spin_lock (schedule) 924 ls-4473 0dN.1 1us : _spin_lock (schedule)
925 ls-4473 0dN.1 2us : add_preempt_count (_spin_lock) 925 ls-4473 0dN.1 2us : add_preempt_count (_spin_lock)
926 ls-4473 0d..2 2us : put_prev_task_fair (schedule) 926 ls-4473 0d..2 2us : put_prev_task_fair (schedule)
927 [...] 927 [...]
928 ls-4473 0d..2 13us : set_normalized_timespec (ktime_get_ts) 928 ls-4473 0d..2 13us : set_normalized_timespec (ktime_get_ts)
929 ls-4473 0d..2 13us : __switch_to (schedule) 929 ls-4473 0d..2 13us : __switch_to (schedule)
930 sshd-4261 0d..2 14us : finish_task_switch (schedule) 930 sshd-4261 0d..2 14us : finish_task_switch (schedule)
931 sshd-4261 0d..2 14us : _spin_unlock_irq (finish_task_switch) 931 sshd-4261 0d..2 14us : _spin_unlock_irq (finish_task_switch)
932 sshd-4261 0d..1 15us : add_preempt_count (_spin_lock_irqsave) 932 sshd-4261 0d..1 15us : add_preempt_count (_spin_lock_irqsave)
933 sshd-4261 0d..2 16us : _spin_unlock_irqrestore (hrtick_set) 933 sshd-4261 0d..2 16us : _spin_unlock_irqrestore (hrtick_set)
934 sshd-4261 0d..2 16us : do_IRQ (common_interrupt) 934 sshd-4261 0d..2 16us : do_IRQ (common_interrupt)
935 sshd-4261 0d..2 17us : irq_enter (do_IRQ) 935 sshd-4261 0d..2 17us : irq_enter (do_IRQ)
936 sshd-4261 0d..2 17us : idle_cpu (irq_enter) 936 sshd-4261 0d..2 17us : idle_cpu (irq_enter)
937 sshd-4261 0d..2 18us : add_preempt_count (irq_enter) 937 sshd-4261 0d..2 18us : add_preempt_count (irq_enter)
938 sshd-4261 0d.h2 18us : idle_cpu (irq_enter) 938 sshd-4261 0d.h2 18us : idle_cpu (irq_enter)
939 sshd-4261 0d.h. 18us : handle_fasteoi_irq (do_IRQ) 939 sshd-4261 0d.h. 18us : handle_fasteoi_irq (do_IRQ)
940 sshd-4261 0d.h. 19us : _spin_lock (handle_fasteoi_irq) 940 sshd-4261 0d.h. 19us : _spin_lock (handle_fasteoi_irq)
941 sshd-4261 0d.h. 19us : add_preempt_count (_spin_lock) 941 sshd-4261 0d.h. 19us : add_preempt_count (_spin_lock)
942 sshd-4261 0d.h1 20us : _spin_unlock (handle_fasteoi_irq) 942 sshd-4261 0d.h1 20us : _spin_unlock (handle_fasteoi_irq)
943 sshd-4261 0d.h1 20us : sub_preempt_count (_spin_unlock) 943 sshd-4261 0d.h1 20us : sub_preempt_count (_spin_unlock)
944 [...] 944 [...]
945 sshd-4261 0d.h1 28us : _spin_unlock (handle_fasteoi_irq) 945 sshd-4261 0d.h1 28us : _spin_unlock (handle_fasteoi_irq)
946 sshd-4261 0d.h1 29us : sub_preempt_count (_spin_unlock) 946 sshd-4261 0d.h1 29us : sub_preempt_count (_spin_unlock)
947 sshd-4261 0d.h2 29us : irq_exit (do_IRQ) 947 sshd-4261 0d.h2 29us : irq_exit (do_IRQ)
948 sshd-4261 0d.h2 29us : sub_preempt_count (irq_exit) 948 sshd-4261 0d.h2 29us : sub_preempt_count (irq_exit)
949 sshd-4261 0d..3 30us : do_softirq (irq_exit) 949 sshd-4261 0d..3 30us : do_softirq (irq_exit)
950 sshd-4261 0d... 30us : __do_softirq (do_softirq) 950 sshd-4261 0d... 30us : __do_softirq (do_softirq)
951 sshd-4261 0d... 31us : __local_bh_disable (__do_softirq) 951 sshd-4261 0d... 31us : __local_bh_disable (__do_softirq)
952 sshd-4261 0d... 31us+: add_preempt_count (__local_bh_disable) 952 sshd-4261 0d... 31us+: add_preempt_count (__local_bh_disable)
953 sshd-4261 0d.s4 34us : add_preempt_count (__local_bh_disable) 953 sshd-4261 0d.s4 34us : add_preempt_count (__local_bh_disable)
954 [...] 954 [...]
955 sshd-4261 0d.s3 43us : sub_preempt_count (local_bh_enable_ip) 955 sshd-4261 0d.s3 43us : sub_preempt_count (local_bh_enable_ip)
956 sshd-4261 0d.s4 44us : sub_preempt_count (local_bh_enable_ip) 956 sshd-4261 0d.s4 44us : sub_preempt_count (local_bh_enable_ip)
957 sshd-4261 0d.s3 44us : smp_apic_timer_interrupt (apic_timer_interrupt) 957 sshd-4261 0d.s3 44us : smp_apic_timer_interrupt (apic_timer_interrupt)
958 sshd-4261 0d.s3 45us : irq_enter (smp_apic_timer_interrupt) 958 sshd-4261 0d.s3 45us : irq_enter (smp_apic_timer_interrupt)
959 sshd-4261 0d.s3 45us : idle_cpu (irq_enter) 959 sshd-4261 0d.s3 45us : idle_cpu (irq_enter)
960 sshd-4261 0d.s3 46us : add_preempt_count (irq_enter) 960 sshd-4261 0d.s3 46us : add_preempt_count (irq_enter)
961 sshd-4261 0d.H3 46us : idle_cpu (irq_enter) 961 sshd-4261 0d.H3 46us : idle_cpu (irq_enter)
962 sshd-4261 0d.H3 47us : hrtimer_interrupt (smp_apic_timer_interrupt) 962 sshd-4261 0d.H3 47us : hrtimer_interrupt (smp_apic_timer_interrupt)
963 sshd-4261 0d.H3 47us : ktime_get (hrtimer_interrupt) 963 sshd-4261 0d.H3 47us : ktime_get (hrtimer_interrupt)
964 [...] 964 [...]
965 sshd-4261 0d.H3 81us : tick_program_event (hrtimer_interrupt) 965 sshd-4261 0d.H3 81us : tick_program_event (hrtimer_interrupt)
966 sshd-4261 0d.H3 82us : ktime_get (tick_program_event) 966 sshd-4261 0d.H3 82us : ktime_get (tick_program_event)
967 sshd-4261 0d.H3 82us : ktime_get_ts (ktime_get) 967 sshd-4261 0d.H3 82us : ktime_get_ts (ktime_get)
968 sshd-4261 0d.H3 83us : getnstimeofday (ktime_get_ts) 968 sshd-4261 0d.H3 83us : getnstimeofday (ktime_get_ts)
969 sshd-4261 0d.H3 83us : set_normalized_timespec (ktime_get_ts) 969 sshd-4261 0d.H3 83us : set_normalized_timespec (ktime_get_ts)
970 sshd-4261 0d.H3 84us : clockevents_program_event (tick_program_event) 970 sshd-4261 0d.H3 84us : clockevents_program_event (tick_program_event)
971 sshd-4261 0d.H3 84us : lapic_next_event (clockevents_program_event) 971 sshd-4261 0d.H3 84us : lapic_next_event (clockevents_program_event)
972 sshd-4261 0d.H3 85us : irq_exit (smp_apic_timer_interrupt) 972 sshd-4261 0d.H3 85us : irq_exit (smp_apic_timer_interrupt)
973 sshd-4261 0d.H3 85us : sub_preempt_count (irq_exit) 973 sshd-4261 0d.H3 85us : sub_preempt_count (irq_exit)
974 sshd-4261 0d.s4 86us : sub_preempt_count (irq_exit) 974 sshd-4261 0d.s4 86us : sub_preempt_count (irq_exit)
975 sshd-4261 0d.s3 86us : add_preempt_count (__local_bh_disable) 975 sshd-4261 0d.s3 86us : add_preempt_count (__local_bh_disable)
976 [...] 976 [...]
977 sshd-4261 0d.s1 98us : sub_preempt_count (net_rx_action) 977 sshd-4261 0d.s1 98us : sub_preempt_count (net_rx_action)
978 sshd-4261 0d.s. 99us : add_preempt_count (_spin_lock_irq) 978 sshd-4261 0d.s. 99us : add_preempt_count (_spin_lock_irq)
979 sshd-4261 0d.s1 99us+: _spin_unlock_irq (run_timer_softirq) 979 sshd-4261 0d.s1 99us+: _spin_unlock_irq (run_timer_softirq)
980 sshd-4261 0d.s. 104us : _local_bh_enable (__do_softirq) 980 sshd-4261 0d.s. 104us : _local_bh_enable (__do_softirq)
981 sshd-4261 0d.s. 104us : sub_preempt_count (_local_bh_enable) 981 sshd-4261 0d.s. 104us : sub_preempt_count (_local_bh_enable)
982 sshd-4261 0d.s. 105us : _local_bh_enable (__do_softirq) 982 sshd-4261 0d.s. 105us : _local_bh_enable (__do_softirq)
983 sshd-4261 0d.s1 105us : trace_preempt_on (__do_softirq) 983 sshd-4261 0d.s1 105us : trace_preempt_on (__do_softirq)
984 984
985 985
986 This is a very interesting trace. It started with the preemption 986 This is a very interesting trace. It started with the preemption
987 of the ls task. We see that the task had the "need_resched" bit 987 of the ls task. We see that the task had the "need_resched" bit
988 set via the 'N' in the trace. Interrupts were disabled before 988 set via the 'N' in the trace. Interrupts were disabled before
989 the spin_lock at the beginning of the trace. We see that a 989 the spin_lock at the beginning of the trace. We see that a
990 schedule took place to run sshd. When the interrupts were 990 schedule took place to run sshd. When the interrupts were
991 enabled, we took an interrupt. On return from the interrupt 991 enabled, we took an interrupt. On return from the interrupt
992 handler, the softirq ran. We took another interrupt while 992 handler, the softirq ran. We took another interrupt while
993 running the softirq as we see from the capital 'H'. 993 running the softirq as we see from the capital 'H'.
994 994
995 995
996 wakeup 996 wakeup
997 ------ 997 ------
998 998
999 In a Real-Time environment it is very important to know the 999 In a Real-Time environment it is very important to know the
1000 wakeup time it takes for the highest priority task that is woken 1000 wakeup time it takes for the highest priority task that is woken
1001 up to the time that it executes. This is also known as "schedule 1001 up to the time that it executes. This is also known as "schedule
1002 latency". I stress the point that this is about RT tasks. It is 1002 latency". I stress the point that this is about RT tasks. It is
1003 also important to know the scheduling latency of non-RT tasks, 1003 also important to know the scheduling latency of non-RT tasks,
1004 but the average schedule latency is better for non-RT tasks. 1004 but the average schedule latency is better for non-RT tasks.
1005 Tools like LatencyTop are more appropriate for such 1005 Tools like LatencyTop are more appropriate for such
1006 measurements. 1006 measurements.
1007 1007
1008 Real-Time environments are interested in the worst case latency. 1008 Real-Time environments are interested in the worst case latency.
1009 That is the longest latency it takes for something to happen, 1009 That is the longest latency it takes for something to happen,
1010 and not the average. We can have a very fast scheduler that may 1010 and not the average. We can have a very fast scheduler that may
1011 only have a large latency once in a while, but that would not 1011 only have a large latency once in a while, but that would not
1012 work well with Real-Time tasks. The wakeup tracer was designed 1012 work well with Real-Time tasks. The wakeup tracer was designed
1013 to record the worst case wakeups of RT tasks. Non-RT tasks are 1013 to record the worst case wakeups of RT tasks. Non-RT tasks are
1014 not recorded because the tracer only records one worst case and 1014 not recorded because the tracer only records one worst case and
1015 tracing non-RT tasks that are unpredictable will overwrite the 1015 tracing non-RT tasks that are unpredictable will overwrite the
1016 worst case latency of RT tasks. 1016 worst case latency of RT tasks.
1017 1017
1018 Since this tracer only deals with RT tasks, we will run this 1018 Since this tracer only deals with RT tasks, we will run this
1019 slightly differently than we did with the previous tracers. 1019 slightly differently than we did with the previous tracers.
1020 Instead of performing an 'ls', we will run 'sleep 1' under 1020 Instead of performing an 'ls', we will run 'sleep 1' under
1021 'chrt' which changes the priority of the task. 1021 'chrt' which changes the priority of the task.
1022 1022
1023 # echo wakeup > current_tracer 1023 # echo wakeup > current_tracer
1024 # echo latency-format > trace_options 1024 # echo latency-format > trace_options
1025 # echo 0 > tracing_max_latency 1025 # echo 0 > tracing_max_latency
1026 # echo 1 > tracing_enabled 1026 # echo 1 > tracing_enabled
1027 # chrt -f 5 sleep 1 1027 # chrt -f 5 sleep 1
1028 # echo 0 > tracing_enabled 1028 # echo 0 > tracing_enabled
1029 # cat trace 1029 # cat trace
1030 # tracer: wakeup 1030 # tracer: wakeup
1031 # 1031 #
1032 wakeup latency trace v1.1.5 on 2.6.26-rc8 1032 wakeup latency trace v1.1.5 on 2.6.26-rc8
1033 -------------------------------------------------------------------- 1033 --------------------------------------------------------------------
1034 latency: 4 us, #2/2, CPU#1 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:2) 1034 latency: 4 us, #2/2, CPU#1 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:2)
1035 ----------------- 1035 -----------------
1036 | task: sleep-4901 (uid:0 nice:0 policy:1 rt_prio:5) 1036 | task: sleep-4901 (uid:0 nice:0 policy:1 rt_prio:5)
1037 ----------------- 1037 -----------------
1038 1038
1039 # _------=> CPU# 1039 # _------=> CPU#
1040 # / _-----=> irqs-off 1040 # / _-----=> irqs-off
1041 # | / _----=> need-resched 1041 # | / _----=> need-resched
1042 # || / _---=> hardirq/softirq 1042 # || / _---=> hardirq/softirq
1043 # ||| / _--=> preempt-depth 1043 # ||| / _--=> preempt-depth
1044 # |||| / 1044 # |||| /
1045 # ||||| delay 1045 # ||||| delay
1046 # cmd pid ||||| time | caller 1046 # cmd pid ||||| time | caller
1047 # \ / ||||| \ | / 1047 # \ / ||||| \ | /
1048 <idle>-0 1d.h4 0us+: try_to_wake_up (wake_up_process) 1048 <idle>-0 1d.h4 0us+: try_to_wake_up (wake_up_process)
1049 <idle>-0 1d..4 4us : schedule (cpu_idle) 1049 <idle>-0 1d..4 4us : schedule (cpu_idle)
1050 1050
1051 1051
1052 Running this on an idle system, we see that it only took 4 1052 Running this on an idle system, we see that it only took 4
1053 microseconds to perform the task switch. Note, since the trace 1053 microseconds to perform the task switch. Note, since the trace
1054 marker in the schedule is before the actual "switch", we stop 1054 marker in the schedule is before the actual "switch", we stop
1055 the tracing when the recorded task is about to schedule in. This 1055 the tracing when the recorded task is about to schedule in. This
1056 may change if we add a new marker at the end of the scheduler. 1056 may change if we add a new marker at the end of the scheduler.
1057 1057
1058 Notice that the recorded task is 'sleep' with the PID of 4901 1058 Notice that the recorded task is 'sleep' with the PID of 4901
1059 and it has an rt_prio of 5. This priority is user-space priority 1059 and it has an rt_prio of 5. This priority is user-space priority
1060 and not the internal kernel priority. The policy is 1 for 1060 and not the internal kernel priority. The policy is 1 for
1061 SCHED_FIFO and 2 for SCHED_RR. 1061 SCHED_FIFO and 2 for SCHED_RR.
1062 1062
1063 Doing the same with chrt -r 5 and ftrace_enabled set. 1063 Doing the same with chrt -r 5 and ftrace_enabled set.
1064 1064
1065 # tracer: wakeup 1065 # tracer: wakeup
1066 # 1066 #
1067 wakeup latency trace v1.1.5 on 2.6.26-rc8 1067 wakeup latency trace v1.1.5 on 2.6.26-rc8
1068 -------------------------------------------------------------------- 1068 --------------------------------------------------------------------
1069 latency: 50 us, #60/60, CPU#1 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:2) 1069 latency: 50 us, #60/60, CPU#1 | (M:preempt VP:0, KP:0, SP:0 HP:0 #P:2)
1070 ----------------- 1070 -----------------
1071 | task: sleep-4068 (uid:0 nice:0 policy:2 rt_prio:5) 1071 | task: sleep-4068 (uid:0 nice:0 policy:2 rt_prio:5)
1072 ----------------- 1072 -----------------
1073 1073
1074 # _------=> CPU# 1074 # _------=> CPU#
1075 # / _-----=> irqs-off 1075 # / _-----=> irqs-off
1076 # | / _----=> need-resched 1076 # | / _----=> need-resched
1077 # || / _---=> hardirq/softirq 1077 # || / _---=> hardirq/softirq
1078 # ||| / _--=> preempt-depth 1078 # ||| / _--=> preempt-depth
1079 # |||| / 1079 # |||| /
1080 # ||||| delay 1080 # ||||| delay
1081 # cmd pid ||||| time | caller 1081 # cmd pid ||||| time | caller
1082 # \ / ||||| \ | / 1082 # \ / ||||| \ | /
1083 ksoftirq-7 1d.H3 0us : try_to_wake_up (wake_up_process) 1083 ksoftirq-7 1d.H3 0us : try_to_wake_up (wake_up_process)
1084 ksoftirq-7 1d.H4 1us : sub_preempt_count (marker_probe_cb) 1084 ksoftirq-7 1d.H4 1us : sub_preempt_count (marker_probe_cb)
1085 ksoftirq-7 1d.H3 2us : check_preempt_wakeup (try_to_wake_up) 1085 ksoftirq-7 1d.H3 2us : check_preempt_wakeup (try_to_wake_up)
1086 ksoftirq-7 1d.H3 3us : update_curr (check_preempt_wakeup) 1086 ksoftirq-7 1d.H3 3us : update_curr (check_preempt_wakeup)
1087 ksoftirq-7 1d.H3 4us : calc_delta_mine (update_curr) 1087 ksoftirq-7 1d.H3 4us : calc_delta_mine (update_curr)
1088 ksoftirq-7 1d.H3 5us : __resched_task (check_preempt_wakeup) 1088 ksoftirq-7 1d.H3 5us : __resched_task (check_preempt_wakeup)
1089 ksoftirq-7 1d.H3 6us : task_wake_up_rt (try_to_wake_up) 1089 ksoftirq-7 1d.H3 6us : task_wake_up_rt (try_to_wake_up)
1090 ksoftirq-7 1d.H3 7us : _spin_unlock_irqrestore (try_to_wake_up) 1090 ksoftirq-7 1d.H3 7us : _spin_unlock_irqrestore (try_to_wake_up)
1091 [...] 1091 [...]
1092 ksoftirq-7 1d.H2 17us : irq_exit (smp_apic_timer_interrupt) 1092 ksoftirq-7 1d.H2 17us : irq_exit (smp_apic_timer_interrupt)
1093 ksoftirq-7 1d.H2 18us : sub_preempt_count (irq_exit) 1093 ksoftirq-7 1d.H2 18us : sub_preempt_count (irq_exit)
1094 ksoftirq-7 1d.s3 19us : sub_preempt_count (irq_exit) 1094 ksoftirq-7 1d.s3 19us : sub_preempt_count (irq_exit)
1095 ksoftirq-7 1..s2 20us : rcu_process_callbacks (__do_softirq) 1095 ksoftirq-7 1..s2 20us : rcu_process_callbacks (__do_softirq)
1096 [...] 1096 [...]
1097 ksoftirq-7 1..s2 26us : __rcu_process_callbacks (rcu_process_callbacks) 1097 ksoftirq-7 1..s2 26us : __rcu_process_callbacks (rcu_process_callbacks)
1098 ksoftirq-7 1d.s2 27us : _local_bh_enable (__do_softirq) 1098 ksoftirq-7 1d.s2 27us : _local_bh_enable (__do_softirq)
1099 ksoftirq-7 1d.s2 28us : sub_preempt_count (_local_bh_enable) 1099 ksoftirq-7 1d.s2 28us : sub_preempt_count (_local_bh_enable)
1100 ksoftirq-7 1.N.3 29us : sub_preempt_count (ksoftirqd) 1100 ksoftirq-7 1.N.3 29us : sub_preempt_count (ksoftirqd)
1101 ksoftirq-7 1.N.2 30us : _cond_resched (ksoftirqd) 1101 ksoftirq-7 1.N.2 30us : _cond_resched (ksoftirqd)
1102 ksoftirq-7 1.N.2 31us : __cond_resched (_cond_resched) 1102 ksoftirq-7 1.N.2 31us : __cond_resched (_cond_resched)
1103 ksoftirq-7 1.N.2 32us : add_preempt_count (__cond_resched) 1103 ksoftirq-7 1.N.2 32us : add_preempt_count (__cond_resched)
1104 ksoftirq-7 1.N.2 33us : schedule (__cond_resched) 1104 ksoftirq-7 1.N.2 33us : schedule (__cond_resched)
1105 ksoftirq-7 1.N.2 33us : add_preempt_count (schedule) 1105 ksoftirq-7 1.N.2 33us : add_preempt_count (schedule)
1106 ksoftirq-7 1.N.3 34us : hrtick_clear (schedule) 1106 ksoftirq-7 1.N.3 34us : hrtick_clear (schedule)
1107 ksoftirq-7 1dN.3 35us : _spin_lock (schedule) 1107 ksoftirq-7 1dN.3 35us : _spin_lock (schedule)
1108 ksoftirq-7 1dN.3 36us : add_preempt_count (_spin_lock) 1108 ksoftirq-7 1dN.3 36us : add_preempt_count (_spin_lock)
1109 ksoftirq-7 1d..4 37us : put_prev_task_fair (schedule) 1109 ksoftirq-7 1d..4 37us : put_prev_task_fair (schedule)
1110 ksoftirq-7 1d..4 38us : update_curr (put_prev_task_fair) 1110 ksoftirq-7 1d..4 38us : update_curr (put_prev_task_fair)
1111 [...] 1111 [...]
1112 ksoftirq-7 1d..5 47us : _spin_trylock (tracing_record_cmdline) 1112 ksoftirq-7 1d..5 47us : _spin_trylock (tracing_record_cmdline)
1113 ksoftirq-7 1d..5 48us : add_preempt_count (_spin_trylock) 1113 ksoftirq-7 1d..5 48us : add_preempt_count (_spin_trylock)
1114 ksoftirq-7 1d..6 49us : _spin_unlock (tracing_record_cmdline) 1114 ksoftirq-7 1d..6 49us : _spin_unlock (tracing_record_cmdline)
1115 ksoftirq-7 1d..6 49us : sub_preempt_count (_spin_unlock) 1115 ksoftirq-7 1d..6 49us : sub_preempt_count (_spin_unlock)
1116 ksoftirq-7 1d..4 50us : schedule (__cond_resched) 1116 ksoftirq-7 1d..4 50us : schedule (__cond_resched)
1117 1117
1118 The interrupt went off while running ksoftirqd. This task runs 1118 The interrupt went off while running ksoftirqd. This task runs
1119 at SCHED_OTHER. Why did not we see the 'N' set early? This may 1119 at SCHED_OTHER. Why did not we see the 'N' set early? This may
1120 be a harmless bug with x86_32 and 4K stacks. On x86_32 with 4K 1120 be a harmless bug with x86_32 and 4K stacks. On x86_32 with 4K
1121 stacks configured, the interrupt and softirq run with their own 1121 stacks configured, the interrupt and softirq run with their own
1122 stack. Some information is held on the top of the task's stack 1122 stack. Some information is held on the top of the task's stack
1123 (need_resched and preempt_count are both stored there). The 1123 (need_resched and preempt_count are both stored there). The
1124 setting of the NEED_RESCHED bit is done directly to the task's 1124 setting of the NEED_RESCHED bit is done directly to the task's
1125 stack, but the reading of the NEED_RESCHED is done by looking at 1125 stack, but the reading of the NEED_RESCHED is done by looking at
1126 the current stack, which in this case is the stack for the hard 1126 the current stack, which in this case is the stack for the hard
1127 interrupt. This hides the fact that NEED_RESCHED has been set. 1127 interrupt. This hides the fact that NEED_RESCHED has been set.
1128 We do not see the 'N' until we switch back to the task's 1128 We do not see the 'N' until we switch back to the task's
1129 assigned stack. 1129 assigned stack.
1130 1130
1131 function 1131 function
1132 -------- 1132 --------
1133 1133
1134 This tracer is the function tracer. Enabling the function tracer 1134 This tracer is the function tracer. Enabling the function tracer
1135 can be done from the debug file system. Make sure the 1135 can be done from the debug file system. Make sure the
1136 ftrace_enabled is set; otherwise this tracer is a nop. 1136 ftrace_enabled is set; otherwise this tracer is a nop.
1137 1137
1138 # sysctl kernel.ftrace_enabled=1 1138 # sysctl kernel.ftrace_enabled=1
1139 # echo function > current_tracer 1139 # echo function > current_tracer
1140 # echo 1 > tracing_enabled 1140 # echo 1 > tracing_enabled
1141 # usleep 1 1141 # usleep 1
1142 # echo 0 > tracing_enabled 1142 # echo 0 > tracing_enabled
1143 # cat trace 1143 # cat trace
1144 # tracer: function 1144 # tracer: function
1145 # 1145 #
1146 # TASK-PID CPU# TIMESTAMP FUNCTION 1146 # TASK-PID CPU# TIMESTAMP FUNCTION
1147 # | | | | | 1147 # | | | | |
1148 bash-4003 [00] 123.638713: finish_task_switch <-schedule 1148 bash-4003 [00] 123.638713: finish_task_switch <-schedule
1149 bash-4003 [00] 123.638714: _spin_unlock_irq <-finish_task_switch 1149 bash-4003 [00] 123.638714: _spin_unlock_irq <-finish_task_switch
1150 bash-4003 [00] 123.638714: sub_preempt_count <-_spin_unlock_irq 1150 bash-4003 [00] 123.638714: sub_preempt_count <-_spin_unlock_irq
1151 bash-4003 [00] 123.638715: hrtick_set <-schedule 1151 bash-4003 [00] 123.638715: hrtick_set <-schedule
1152 bash-4003 [00] 123.638715: _spin_lock_irqsave <-hrtick_set 1152 bash-4003 [00] 123.638715: _spin_lock_irqsave <-hrtick_set
1153 bash-4003 [00] 123.638716: add_preempt_count <-_spin_lock_irqsave 1153 bash-4003 [00] 123.638716: add_preempt_count <-_spin_lock_irqsave
1154 bash-4003 [00] 123.638716: _spin_unlock_irqrestore <-hrtick_set 1154 bash-4003 [00] 123.638716: _spin_unlock_irqrestore <-hrtick_set
1155 bash-4003 [00] 123.638717: sub_preempt_count <-_spin_unlock_irqrestore 1155 bash-4003 [00] 123.638717: sub_preempt_count <-_spin_unlock_irqrestore
1156 bash-4003 [00] 123.638717: hrtick_clear <-hrtick_set 1156 bash-4003 [00] 123.638717: hrtick_clear <-hrtick_set
1157 bash-4003 [00] 123.638718: sub_preempt_count <-schedule 1157 bash-4003 [00] 123.638718: sub_preempt_count <-schedule
1158 bash-4003 [00] 123.638718: sub_preempt_count <-preempt_schedule 1158 bash-4003 [00] 123.638718: sub_preempt_count <-preempt_schedule
1159 bash-4003 [00] 123.638719: wait_for_completion <-__stop_machine_run 1159 bash-4003 [00] 123.638719: wait_for_completion <-__stop_machine_run
1160 bash-4003 [00] 123.638719: wait_for_common <-wait_for_completion 1160 bash-4003 [00] 123.638719: wait_for_common <-wait_for_completion
1161 bash-4003 [00] 123.638720: _spin_lock_irq <-wait_for_common 1161 bash-4003 [00] 123.638720: _spin_lock_irq <-wait_for_common
1162 bash-4003 [00] 123.638720: add_preempt_count <-_spin_lock_irq 1162 bash-4003 [00] 123.638720: add_preempt_count <-_spin_lock_irq
1163 [...] 1163 [...]
1164 1164
1165 1165
1166 Note: function tracer uses ring buffers to store the above 1166 Note: function tracer uses ring buffers to store the above
1167 entries. The newest data may overwrite the oldest data. 1167 entries. The newest data may overwrite the oldest data.
1168 Sometimes using echo to stop the trace is not sufficient because 1168 Sometimes using echo to stop the trace is not sufficient because
1169 the tracing could have overwritten the data that you wanted to 1169 the tracing could have overwritten the data that you wanted to
1170 record. For this reason, it is sometimes better to disable 1170 record. For this reason, it is sometimes better to disable
1171 tracing directly from a program. This allows you to stop the 1171 tracing directly from a program. This allows you to stop the
1172 tracing at the point that you hit the part that you are 1172 tracing at the point that you hit the part that you are
1173 interested in. To disable the tracing directly from a C program, 1173 interested in. To disable the tracing directly from a C program,
1174 something like following code snippet can be used: 1174 something like following code snippet can be used:
1175 1175
1176 int trace_fd; 1176 int trace_fd;
1177 [...] 1177 [...]
1178 int main(int argc, char *argv[]) { 1178 int main(int argc, char *argv[]) {
1179 [...] 1179 [...]
1180 trace_fd = open(tracing_file("tracing_enabled"), O_WRONLY); 1180 trace_fd = open(tracing_file("tracing_enabled"), O_WRONLY);
1181 [...] 1181 [...]
1182 if (condition_hit()) { 1182 if (condition_hit()) {
1183 write(trace_fd, "0", 1); 1183 write(trace_fd, "0", 1);
1184 } 1184 }
1185 [...] 1185 [...]
1186 } 1186 }
1187 1187
1188 1188
1189 Single thread tracing 1189 Single thread tracing
1190 --------------------- 1190 ---------------------
1191 1191
1192 By writing into set_ftrace_pid you can trace a 1192 By writing into set_ftrace_pid you can trace a
1193 single thread. For example: 1193 single thread. For example:
1194 1194
1195 # cat set_ftrace_pid 1195 # cat set_ftrace_pid
1196 no pid 1196 no pid
1197 # echo 3111 > set_ftrace_pid 1197 # echo 3111 > set_ftrace_pid
1198 # cat set_ftrace_pid 1198 # cat set_ftrace_pid
1199 3111 1199 3111
1200 # echo function > current_tracer 1200 # echo function > current_tracer
1201 # cat trace | head 1201 # cat trace | head
1202 # tracer: function 1202 # tracer: function
1203 # 1203 #
1204 # TASK-PID CPU# TIMESTAMP FUNCTION 1204 # TASK-PID CPU# TIMESTAMP FUNCTION
1205 # | | | | | 1205 # | | | | |
1206 yum-updatesd-3111 [003] 1637.254676: finish_task_switch <-thread_return 1206 yum-updatesd-3111 [003] 1637.254676: finish_task_switch <-thread_return
1207 yum-updatesd-3111 [003] 1637.254681: hrtimer_cancel <-schedule_hrtimeout_range 1207 yum-updatesd-3111 [003] 1637.254681: hrtimer_cancel <-schedule_hrtimeout_range
1208 yum-updatesd-3111 [003] 1637.254682: hrtimer_try_to_cancel <-hrtimer_cancel 1208 yum-updatesd-3111 [003] 1637.254682: hrtimer_try_to_cancel <-hrtimer_cancel
1209 yum-updatesd-3111 [003] 1637.254683: lock_hrtimer_base <-hrtimer_try_to_cancel 1209 yum-updatesd-3111 [003] 1637.254683: lock_hrtimer_base <-hrtimer_try_to_cancel
1210 yum-updatesd-3111 [003] 1637.254685: fget_light <-do_sys_poll 1210 yum-updatesd-3111 [003] 1637.254685: fget_light <-do_sys_poll
1211 yum-updatesd-3111 [003] 1637.254686: pipe_poll <-do_sys_poll 1211 yum-updatesd-3111 [003] 1637.254686: pipe_poll <-do_sys_poll
1212 # echo -1 > set_ftrace_pid 1212 # echo -1 > set_ftrace_pid
1213 # cat trace |head 1213 # cat trace |head
1214 # tracer: function 1214 # tracer: function
1215 # 1215 #
1216 # TASK-PID CPU# TIMESTAMP FUNCTION 1216 # TASK-PID CPU# TIMESTAMP FUNCTION
1217 # | | | | | 1217 # | | | | |
1218 ##### CPU 3 buffer started #### 1218 ##### CPU 3 buffer started ####
1219 yum-updatesd-3111 [003] 1701.957688: free_poll_entry <-poll_freewait 1219 yum-updatesd-3111 [003] 1701.957688: free_poll_entry <-poll_freewait
1220 yum-updatesd-3111 [003] 1701.957689: remove_wait_queue <-free_poll_entry 1220 yum-updatesd-3111 [003] 1701.957689: remove_wait_queue <-free_poll_entry
1221 yum-updatesd-3111 [003] 1701.957691: fput <-free_poll_entry 1221 yum-updatesd-3111 [003] 1701.957691: fput <-free_poll_entry
1222 yum-updatesd-3111 [003] 1701.957692: audit_syscall_exit <-sysret_audit 1222 yum-updatesd-3111 [003] 1701.957692: audit_syscall_exit <-sysret_audit
1223 yum-updatesd-3111 [003] 1701.957693: path_put <-audit_syscall_exit 1223 yum-updatesd-3111 [003] 1701.957693: path_put <-audit_syscall_exit
1224 1224
1225 If you want to trace a function when executing, you could use 1225 If you want to trace a function when executing, you could use
1226 something like this simple program: 1226 something like this simple program:
1227 1227
1228 #include <stdio.h> 1228 #include <stdio.h>
1229 #include <stdlib.h> 1229 #include <stdlib.h>
1230 #include <sys/types.h> 1230 #include <sys/types.h>
1231 #include <sys/stat.h> 1231 #include <sys/stat.h>
1232 #include <fcntl.h> 1232 #include <fcntl.h>
1233 #include <unistd.h> 1233 #include <unistd.h>
1234 1234
1235 #define _STR(x) #x 1235 #define _STR(x) #x
1236 #define STR(x) _STR(x) 1236 #define STR(x) _STR(x)
1237 #define MAX_PATH 256 1237 #define MAX_PATH 256
1238 1238
1239 const char *find_debugfs(void) 1239 const char *find_debugfs(void)
1240 { 1240 {
1241 static char debugfs[MAX_PATH+1]; 1241 static char debugfs[MAX_PATH+1];
1242 static int debugfs_found; 1242 static int debugfs_found;
1243 char type[100]; 1243 char type[100];
1244 FILE *fp; 1244 FILE *fp;
1245 1245
1246 if (debugfs_found) 1246 if (debugfs_found)
1247 return debugfs; 1247 return debugfs;
1248 1248
1249 if ((fp = fopen("/proc/mounts","r")) == NULL) { 1249 if ((fp = fopen("/proc/mounts","r")) == NULL) {
1250 perror("/proc/mounts"); 1250 perror("/proc/mounts");
1251 return NULL; 1251 return NULL;
1252 } 1252 }
1253 1253
1254 while (fscanf(fp, "%*s %" 1254 while (fscanf(fp, "%*s %"
1255 STR(MAX_PATH) 1255 STR(MAX_PATH)
1256 "s %99s %*s %*d %*d\n", 1256 "s %99s %*s %*d %*d\n",
1257 debugfs, type) == 2) { 1257 debugfs, type) == 2) {
1258 if (strcmp(type, "debugfs") == 0) 1258 if (strcmp(type, "debugfs") == 0)
1259 break; 1259 break;
1260 } 1260 }
1261 fclose(fp); 1261 fclose(fp);
1262 1262
1263 if (strcmp(type, "debugfs") != 0) { 1263 if (strcmp(type, "debugfs") != 0) {
1264 fprintf(stderr, "debugfs not mounted"); 1264 fprintf(stderr, "debugfs not mounted");
1265 return NULL; 1265 return NULL;
1266 } 1266 }
1267 1267
1268 debugfs_found = 1; 1268 debugfs_found = 1;
1269 1269
1270 return debugfs; 1270 return debugfs;
1271 } 1271 }
1272 1272
1273 const char *tracing_file(const char *file_name) 1273 const char *tracing_file(const char *file_name)
1274 { 1274 {
1275 static char trace_file[MAX_PATH+1]; 1275 static char trace_file[MAX_PATH+1];
1276 snprintf(trace_file, MAX_PATH, "%s/%s", find_debugfs(), file_name); 1276 snprintf(trace_file, MAX_PATH, "%s/%s", find_debugfs(), file_name);
1277 return trace_file; 1277 return trace_file;
1278 } 1278 }
1279 1279
1280 int main (int argc, char **argv) 1280 int main (int argc, char **argv)
1281 { 1281 {
1282 if (argc < 1) 1282 if (argc < 1)
1283 exit(-1); 1283 exit(-1);
1284 1284
1285 if (fork() > 0) { 1285 if (fork() > 0) {
1286 int fd, ffd; 1286 int fd, ffd;
1287 char line[64]; 1287 char line[64];
1288 int s; 1288 int s;
1289 1289
1290 ffd = open(tracing_file("current_tracer"), O_WRONLY); 1290 ffd = open(tracing_file("current_tracer"), O_WRONLY);
1291 if (ffd < 0) 1291 if (ffd < 0)
1292 exit(-1); 1292 exit(-1);
1293 write(ffd, "nop", 3); 1293 write(ffd, "nop", 3);
1294 1294
1295 fd = open(tracing_file("set_ftrace_pid"), O_WRONLY); 1295 fd = open(tracing_file("set_ftrace_pid"), O_WRONLY);
1296 s = sprintf(line, "%d\n", getpid()); 1296 s = sprintf(line, "%d\n", getpid());
1297 write(fd, line, s); 1297 write(fd, line, s);
1298 1298
1299 write(ffd, "function", 8); 1299 write(ffd, "function", 8);
1300 1300
1301 close(fd); 1301 close(fd);
1302 close(ffd); 1302 close(ffd);
1303 1303
1304 execvp(argv[1], argv+1); 1304 execvp(argv[1], argv+1);
1305 } 1305 }
1306 1306
1307 return 0; 1307 return 0;
1308 } 1308 }
1309 1309
1310 1310
1311 hw-branch-tracer (x86 only) 1311 hw-branch-tracer (x86 only)
1312 --------------------------- 1312 ---------------------------
1313 1313
1314 This tracer uses the x86 last branch tracing hardware feature to 1314 This tracer uses the x86 last branch tracing hardware feature to
1315 collect a branch trace on all cpus with relatively low overhead. 1315 collect a branch trace on all cpus with relatively low overhead.
1316 1316
1317 The tracer uses a fixed-size circular buffer per cpu and only 1317 The tracer uses a fixed-size circular buffer per cpu and only
1318 traces ring 0 branches. The trace file dumps that buffer in the 1318 traces ring 0 branches. The trace file dumps that buffer in the
1319 following format: 1319 following format:
1320 1320
1321 # tracer: hw-branch-tracer 1321 # tracer: hw-branch-tracer
1322 # 1322 #
1323 # CPU# TO <- FROM 1323 # CPU# TO <- FROM
1324 0 scheduler_tick+0xb5/0x1bf <- task_tick_idle+0x5/0x6 1324 0 scheduler_tick+0xb5/0x1bf <- task_tick_idle+0x5/0x6
1325 2 run_posix_cpu_timers+0x2b/0x72a <- run_posix_cpu_timers+0x25/0x72a 1325 2 run_posix_cpu_timers+0x2b/0x72a <- run_posix_cpu_timers+0x25/0x72a
1326 0 scheduler_tick+0x139/0x1bf <- scheduler_tick+0xed/0x1bf 1326 0 scheduler_tick+0x139/0x1bf <- scheduler_tick+0xed/0x1bf
1327 0 scheduler_tick+0x17c/0x1bf <- scheduler_tick+0x148/0x1bf 1327 0 scheduler_tick+0x17c/0x1bf <- scheduler_tick+0x148/0x1bf
1328 2 run_posix_cpu_timers+0x9e/0x72a <- run_posix_cpu_timers+0x5e/0x72a 1328 2 run_posix_cpu_timers+0x9e/0x72a <- run_posix_cpu_timers+0x5e/0x72a
1329 0 scheduler_tick+0x1b6/0x1bf <- scheduler_tick+0x1aa/0x1bf 1329 0 scheduler_tick+0x1b6/0x1bf <- scheduler_tick+0x1aa/0x1bf
1330 1330
1331 1331
1332 The tracer may be used to dump the trace for the oops'ing cpu on 1332 The tracer may be used to dump the trace for the oops'ing cpu on
1333 a kernel oops into the system log. To enable this, 1333 a kernel oops into the system log. To enable this,
1334 ftrace_dump_on_oops must be set. To set ftrace_dump_on_oops, one 1334 ftrace_dump_on_oops must be set. To set ftrace_dump_on_oops, one
1335 can either use the sysctl function or set it via the proc system 1335 can either use the sysctl function or set it via the proc system
1336 interface. 1336 interface.
1337 1337
1338 sysctl kernel.ftrace_dump_on_oops=1 1338 sysctl kernel.ftrace_dump_on_oops=1
1339 1339
1340 or 1340 or
1341 1341
1342 echo 1 > /proc/sys/kernel/ftrace_dump_on_oops 1342 echo 1 > /proc/sys/kernel/ftrace_dump_on_oops
1343 1343
1344 1344
1345 Here's an example of such a dump after a null pointer 1345 Here's an example of such a dump after a null pointer
1346 dereference in a kernel module: 1346 dereference in a kernel module:
1347 1347
1348 [57848.105921] BUG: unable to handle kernel NULL pointer dereference at 0000000000000000 1348 [57848.105921] BUG: unable to handle kernel NULL pointer dereference at 0000000000000000
1349 [57848.106019] IP: [<ffffffffa0000006>] open+0x6/0x14 [oops] 1349 [57848.106019] IP: [<ffffffffa0000006>] open+0x6/0x14 [oops]
1350 [57848.106019] PGD 2354e9067 PUD 2375e7067 PMD 0 1350 [57848.106019] PGD 2354e9067 PUD 2375e7067 PMD 0
1351 [57848.106019] Oops: 0002 [#1] SMP 1351 [57848.106019] Oops: 0002 [#1] SMP
1352 [57848.106019] last sysfs file: /sys/devices/pci0000:00/0000:00:1e.0/0000:20:05.0/local_cpus 1352 [57848.106019] last sysfs file: /sys/devices/pci0000:00/0000:00:1e.0/0000:20:05.0/local_cpus
1353 [57848.106019] Dumping ftrace buffer: 1353 [57848.106019] Dumping ftrace buffer:
1354 [57848.106019] --------------------------------- 1354 [57848.106019] ---------------------------------
1355 [...] 1355 [...]
1356 [57848.106019] 0 chrdev_open+0xe6/0x165 <- cdev_put+0x23/0x24 1356 [57848.106019] 0 chrdev_open+0xe6/0x165 <- cdev_put+0x23/0x24
1357 [57848.106019] 0 chrdev_open+0x117/0x165 <- chrdev_open+0xfa/0x165 1357 [57848.106019] 0 chrdev_open+0x117/0x165 <- chrdev_open+0xfa/0x165
1358 [57848.106019] 0 chrdev_open+0x120/0x165 <- chrdev_open+0x11c/0x165 1358 [57848.106019] 0 chrdev_open+0x120/0x165 <- chrdev_open+0x11c/0x165
1359 [57848.106019] 0 chrdev_open+0x134/0x165 <- chrdev_open+0x12b/0x165 1359 [57848.106019] 0 chrdev_open+0x134/0x165 <- chrdev_open+0x12b/0x165
1360 [57848.106019] 0 open+0x0/0x14 [oops] <- chrdev_open+0x144/0x165 1360 [57848.106019] 0 open+0x0/0x14 [oops] <- chrdev_open+0x144/0x165
1361 [57848.106019] 0 page_fault+0x0/0x30 <- open+0x6/0x14 [oops] 1361 [57848.106019] 0 page_fault+0x0/0x30 <- open+0x6/0x14 [oops]
1362 [57848.106019] 0 error_entry+0x0/0x5b <- page_fault+0x4/0x30 1362 [57848.106019] 0 error_entry+0x0/0x5b <- page_fault+0x4/0x30
1363 [57848.106019] 0 error_kernelspace+0x0/0x31 <- error_entry+0x59/0x5b 1363 [57848.106019] 0 error_kernelspace+0x0/0x31 <- error_entry+0x59/0x5b
1364 [57848.106019] 0 error_sti+0x0/0x1 <- error_kernelspace+0x2d/0x31 1364 [57848.106019] 0 error_sti+0x0/0x1 <- error_kernelspace+0x2d/0x31
1365 [57848.106019] 0 page_fault+0x9/0x30 <- error_sti+0x0/0x1 1365 [57848.106019] 0 page_fault+0x9/0x30 <- error_sti+0x0/0x1
1366 [57848.106019] 0 do_page_fault+0x0/0x881 <- page_fault+0x1a/0x30 1366 [57848.106019] 0 do_page_fault+0x0/0x881 <- page_fault+0x1a/0x30
1367 [...] 1367 [...]
1368 [57848.106019] 0 do_page_fault+0x66b/0x881 <- is_prefetch+0x1ee/0x1f2 1368 [57848.106019] 0 do_page_fault+0x66b/0x881 <- is_prefetch+0x1ee/0x1f2
1369 [57848.106019] 0 do_page_fault+0x6e0/0x881 <- do_page_fault+0x67a/0x881 1369 [57848.106019] 0 do_page_fault+0x6e0/0x881 <- do_page_fault+0x67a/0x881
1370 [57848.106019] 0 oops_begin+0x0/0x96 <- do_page_fault+0x6e0/0x881 1370 [57848.106019] 0 oops_begin+0x0/0x96 <- do_page_fault+0x6e0/0x881
1371 [57848.106019] 0 trace_hw_branch_oops+0x0/0x2d <- oops_begin+0x9/0x96 1371 [57848.106019] 0 trace_hw_branch_oops+0x0/0x2d <- oops_begin+0x9/0x96
1372 [...] 1372 [...]
1373 [57848.106019] 0 ds_suspend_bts+0x2a/0xe3 <- ds_suspend_bts+0x1a/0xe3 1373 [57848.106019] 0 ds_suspend_bts+0x2a/0xe3 <- ds_suspend_bts+0x1a/0xe3
1374 [57848.106019] --------------------------------- 1374 [57848.106019] ---------------------------------
1375 [57848.106019] CPU 0 1375 [57848.106019] CPU 0
1376 [57848.106019] Modules linked in: oops 1376 [57848.106019] Modules linked in: oops
1377 [57848.106019] Pid: 5542, comm: cat Tainted: G W 2.6.28 #23 1377 [57848.106019] Pid: 5542, comm: cat Tainted: G W 2.6.28 #23
1378 [57848.106019] RIP: 0010:[<ffffffffa0000006>] [<ffffffffa0000006>] open+0x6/0x14 [oops] 1378 [57848.106019] RIP: 0010:[<ffffffffa0000006>] [<ffffffffa0000006>] open+0x6/0x14 [oops]
1379 [57848.106019] RSP: 0018:ffff880235457d48 EFLAGS: 00010246 1379 [57848.106019] RSP: 0018:ffff880235457d48 EFLAGS: 00010246
1380 [...] 1380 [...]
1381 1381
1382 1382
1383 function graph tracer 1383 function graph tracer
1384 --------------------------- 1384 ---------------------------
1385 1385
1386 This tracer is similar to the function tracer except that it 1386 This tracer is similar to the function tracer except that it
1387 probes a function on its entry and its exit. This is done by 1387 probes a function on its entry and its exit. This is done by
1388 using a dynamically allocated stack of return addresses in each 1388 using a dynamically allocated stack of return addresses in each
1389 task_struct. On function entry the tracer overwrites the return 1389 task_struct. On function entry the tracer overwrites the return
1390 address of each function traced to set a custom probe. Thus the 1390 address of each function traced to set a custom probe. Thus the
1391 original return address is stored on the stack of return address 1391 original return address is stored on the stack of return address
1392 in the task_struct. 1392 in the task_struct.
1393 1393
1394 Probing on both ends of a function leads to special features 1394 Probing on both ends of a function leads to special features
1395 such as: 1395 such as:
1396 1396
1397 - measure of a function's time execution 1397 - measure of a function's time execution
1398 - having a reliable call stack to draw function calls graph 1398 - having a reliable call stack to draw function calls graph
1399 1399
1400 This tracer is useful in several situations: 1400 This tracer is useful in several situations:
1401 1401
1402 - you want to find the reason of a strange kernel behavior and 1402 - you want to find the reason of a strange kernel behavior and
1403 need to see what happens in detail on any areas (or specific 1403 need to see what happens in detail on any areas (or specific
1404 ones). 1404 ones).
1405 1405
1406 - you are experiencing weird latencies but it's difficult to 1406 - you are experiencing weird latencies but it's difficult to
1407 find its origin. 1407 find its origin.
1408 1408
1409 - you want to find quickly which path is taken by a specific 1409 - you want to find quickly which path is taken by a specific
1410 function 1410 function
1411 1411
1412 - you just want to peek inside a working kernel and want to see 1412 - you just want to peek inside a working kernel and want to see
1413 what happens there. 1413 what happens there.
1414 1414
1415 # tracer: function_graph 1415 # tracer: function_graph
1416 # 1416 #
1417 # CPU DURATION FUNCTION CALLS 1417 # CPU DURATION FUNCTION CALLS
1418 # | | | | | | | 1418 # | | | | | | |
1419 1419
1420 0) | sys_open() { 1420 0) | sys_open() {
1421 0) | do_sys_open() { 1421 0) | do_sys_open() {
1422 0) | getname() { 1422 0) | getname() {
1423 0) | kmem_cache_alloc() { 1423 0) | kmem_cache_alloc() {
1424 0) 1.382 us | __might_sleep(); 1424 0) 1.382 us | __might_sleep();
1425 0) 2.478 us | } 1425 0) 2.478 us | }
1426 0) | strncpy_from_user() { 1426 0) | strncpy_from_user() {
1427 0) | might_fault() { 1427 0) | might_fault() {
1428 0) 1.389 us | __might_sleep(); 1428 0) 1.389 us | __might_sleep();
1429 0) 2.553 us | } 1429 0) 2.553 us | }
1430 0) 3.807 us | } 1430 0) 3.807 us | }
1431 0) 7.876 us | } 1431 0) 7.876 us | }
1432 0) | alloc_fd() { 1432 0) | alloc_fd() {
1433 0) 0.668 us | _spin_lock(); 1433 0) 0.668 us | _spin_lock();
1434 0) 0.570 us | expand_files(); 1434 0) 0.570 us | expand_files();
1435 0) 0.586 us | _spin_unlock(); 1435 0) 0.586 us | _spin_unlock();
1436 1436
1437 1437
1438 There are several columns that can be dynamically 1438 There are several columns that can be dynamically
1439 enabled/disabled. You can use every combination of options you 1439 enabled/disabled. You can use every combination of options you
1440 want, depending on your needs. 1440 want, depending on your needs.
1441 1441
1442 - The cpu number on which the function executed is default 1442 - The cpu number on which the function executed is default
1443 enabled. It is sometimes better to only trace one cpu (see 1443 enabled. It is sometimes better to only trace one cpu (see
1444 tracing_cpu_mask file) or you might sometimes see unordered 1444 tracing_cpu_mask file) or you might sometimes see unordered
1445 function calls while cpu tracing switch. 1445 function calls while cpu tracing switch.
1446 1446
1447 hide: echo nofuncgraph-cpu > trace_options 1447 hide: echo nofuncgraph-cpu > trace_options
1448 show: echo funcgraph-cpu > trace_options 1448 show: echo funcgraph-cpu > trace_options
1449 1449
1450 - The duration (function's time of execution) is displayed on 1450 - The duration (function's time of execution) is displayed on
1451 the closing bracket line of a function or on the same line 1451 the closing bracket line of a function or on the same line
1452 than the current function in case of a leaf one. It is default 1452 than the current function in case of a leaf one. It is default
1453 enabled. 1453 enabled.
1454 1454
1455 hide: echo nofuncgraph-duration > trace_options 1455 hide: echo nofuncgraph-duration > trace_options
1456 show: echo funcgraph-duration > trace_options 1456 show: echo funcgraph-duration > trace_options
1457 1457
1458 - The overhead field precedes the duration field in case of 1458 - The overhead field precedes the duration field in case of
1459 reached duration thresholds. 1459 reached duration thresholds.
1460 1460
1461 hide: echo nofuncgraph-overhead > trace_options 1461 hide: echo nofuncgraph-overhead > trace_options
1462 show: echo funcgraph-overhead > trace_options 1462 show: echo funcgraph-overhead > trace_options
1463 depends on: funcgraph-duration 1463 depends on: funcgraph-duration
1464 1464
1465 ie: 1465 ie:
1466 1466
1467 0) | up_write() { 1467 0) | up_write() {
1468 0) 0.646 us | _spin_lock_irqsave(); 1468 0) 0.646 us | _spin_lock_irqsave();
1469 0) 0.684 us | _spin_unlock_irqrestore(); 1469 0) 0.684 us | _spin_unlock_irqrestore();
1470 0) 3.123 us | } 1470 0) 3.123 us | }
1471 0) 0.548 us | fput(); 1471 0) 0.548 us | fput();
1472 0) + 58.628 us | } 1472 0) + 58.628 us | }
1473 1473
1474 [...] 1474 [...]
1475 1475
1476 0) | putname() { 1476 0) | putname() {
1477 0) | kmem_cache_free() { 1477 0) | kmem_cache_free() {
1478 0) 0.518 us | __phys_addr(); 1478 0) 0.518 us | __phys_addr();
1479 0) 1.757 us | } 1479 0) 1.757 us | }
1480 0) 2.861 us | } 1480 0) 2.861 us | }
1481 0) ! 115.305 us | } 1481 0) ! 115.305 us | }
1482 0) ! 116.402 us | } 1482 0) ! 116.402 us | }
1483 1483
1484 + means that the function exceeded 10 usecs. 1484 + means that the function exceeded 10 usecs.
1485 ! means that the function exceeded 100 usecs. 1485 ! means that the function exceeded 100 usecs.
1486 1486
1487 1487
1488 - The task/pid field displays the thread cmdline and pid which 1488 - The task/pid field displays the thread cmdline and pid which
1489 executed the function. It is default disabled. 1489 executed the function. It is default disabled.
1490 1490
1491 hide: echo nofuncgraph-proc > trace_options 1491 hide: echo nofuncgraph-proc > trace_options
1492 show: echo funcgraph-proc > trace_options 1492 show: echo funcgraph-proc > trace_options
1493 1493
1494 ie: 1494 ie:
1495 1495
1496 # tracer: function_graph 1496 # tracer: function_graph
1497 # 1497 #
1498 # CPU TASK/PID DURATION FUNCTION CALLS 1498 # CPU TASK/PID DURATION FUNCTION CALLS
1499 # | | | | | | | | | 1499 # | | | | | | | | |
1500 0) sh-4802 | | d_free() { 1500 0) sh-4802 | | d_free() {
1501 0) sh-4802 | | call_rcu() { 1501 0) sh-4802 | | call_rcu() {
1502 0) sh-4802 | | __call_rcu() { 1502 0) sh-4802 | | __call_rcu() {
1503 0) sh-4802 | 0.616 us | rcu_process_gp_end(); 1503 0) sh-4802 | 0.616 us | rcu_process_gp_end();
1504 0) sh-4802 | 0.586 us | check_for_new_grace_period(); 1504 0) sh-4802 | 0.586 us | check_for_new_grace_period();
1505 0) sh-4802 | 2.899 us | } 1505 0) sh-4802 | 2.899 us | }
1506 0) sh-4802 | 4.040 us | } 1506 0) sh-4802 | 4.040 us | }
1507 0) sh-4802 | 5.151 us | } 1507 0) sh-4802 | 5.151 us | }
1508 0) sh-4802 | + 49.370 us | } 1508 0) sh-4802 | + 49.370 us | }
1509 1509
1510 1510
1511 - The absolute time field is an absolute timestamp given by the 1511 - The absolute time field is an absolute timestamp given by the
1512 system clock since it started. A snapshot of this time is 1512 system clock since it started. A snapshot of this time is
1513 given on each entry/exit of functions 1513 given on each entry/exit of functions
1514 1514
1515 hide: echo nofuncgraph-abstime > trace_options 1515 hide: echo nofuncgraph-abstime > trace_options
1516 show: echo funcgraph-abstime > trace_options 1516 show: echo funcgraph-abstime > trace_options
1517 1517
1518 ie: 1518 ie:
1519 1519
1520 # 1520 #
1521 # TIME CPU DURATION FUNCTION CALLS 1521 # TIME CPU DURATION FUNCTION CALLS
1522 # | | | | | | | | 1522 # | | | | | | | |
1523 360.774522 | 1) 0.541 us | } 1523 360.774522 | 1) 0.541 us | }
1524 360.774522 | 1) 4.663 us | } 1524 360.774522 | 1) 4.663 us | }
1525 360.774523 | 1) 0.541 us | __wake_up_bit(); 1525 360.774523 | 1) 0.541 us | __wake_up_bit();
1526 360.774524 | 1) 6.796 us | } 1526 360.774524 | 1) 6.796 us | }
1527 360.774524 | 1) 7.952 us | } 1527 360.774524 | 1) 7.952 us | }
1528 360.774525 | 1) 9.063 us | } 1528 360.774525 | 1) 9.063 us | }
1529 360.774525 | 1) 0.615 us | journal_mark_dirty(); 1529 360.774525 | 1) 0.615 us | journal_mark_dirty();
1530 360.774527 | 1) 0.578 us | __brelse(); 1530 360.774527 | 1) 0.578 us | __brelse();
1531 360.774528 | 1) | reiserfs_prepare_for_journal() { 1531 360.774528 | 1) | reiserfs_prepare_for_journal() {
1532 360.774528 | 1) | unlock_buffer() { 1532 360.774528 | 1) | unlock_buffer() {
1533 360.774529 | 1) | wake_up_bit() { 1533 360.774529 | 1) | wake_up_bit() {
1534 360.774529 | 1) | bit_waitqueue() { 1534 360.774529 | 1) | bit_waitqueue() {
1535 360.774530 | 1) 0.594 us | __phys_addr(); 1535 360.774530 | 1) 0.594 us | __phys_addr();
1536 1536
1537 1537
1538 You can put some comments on specific functions by using 1538 You can put some comments on specific functions by using
1539 trace_printk() For example, if you want to put a comment inside 1539 trace_printk() For example, if you want to put a comment inside
1540 the __might_sleep() function, you just have to include 1540 the __might_sleep() function, you just have to include
1541 <linux/ftrace.h> and call trace_printk() inside __might_sleep() 1541 <linux/ftrace.h> and call trace_printk() inside __might_sleep()
1542 1542
1543 trace_printk("I'm a comment!\n") 1543 trace_printk("I'm a comment!\n")
1544 1544
1545 will produce: 1545 will produce:
1546 1546
1547 1) | __might_sleep() { 1547 1) | __might_sleep() {
1548 1) | /* I'm a comment! */ 1548 1) | /* I'm a comment! */
1549 1) 1.449 us | } 1549 1) 1.449 us | }
1550 1550
1551 1551
1552 You might find other useful features for this tracer in the 1552 You might find other useful features for this tracer in the
1553 following "dynamic ftrace" section such as tracing only specific 1553 following "dynamic ftrace" section such as tracing only specific
1554 functions or tasks. 1554 functions or tasks.
1555 1555
1556 dynamic ftrace 1556 dynamic ftrace
1557 -------------- 1557 --------------
1558 1558
1559 If CONFIG_DYNAMIC_FTRACE is set, the system will run with 1559 If CONFIG_DYNAMIC_FTRACE is set, the system will run with
1560 virtually no overhead when function tracing is disabled. The way 1560 virtually no overhead when function tracing is disabled. The way
1561 this works is the mcount function call (placed at the start of 1561 this works is the mcount function call (placed at the start of
1562 every kernel function, produced by the -pg switch in gcc), 1562 every kernel function, produced by the -pg switch in gcc),
1563 starts of pointing to a simple return. (Enabling FTRACE will 1563 starts of pointing to a simple return. (Enabling FTRACE will
1564 include the -pg switch in the compiling of the kernel.) 1564 include the -pg switch in the compiling of the kernel.)
1565 1565
1566 At compile time every C file object is run through the 1566 At compile time every C file object is run through the
1567 recordmcount.pl script (located in the scripts directory). This 1567 recordmcount.pl script (located in the scripts directory). This
1568 script will process the C object using objdump to find all the 1568 script will process the C object using objdump to find all the
1569 locations in the .text section that call mcount. (Note, only the 1569 locations in the .text section that call mcount. (Note, only the
1570 .text section is processed, since processing other sections like 1570 .text section is processed, since processing other sections like
1571 .init.text may cause races due to those sections being freed). 1571 .init.text may cause races due to those sections being freed).
1572 1572
1573 A new section called "__mcount_loc" is created that holds 1573 A new section called "__mcount_loc" is created that holds
1574 references to all the mcount call sites in the .text section. 1574 references to all the mcount call sites in the .text section.
1575 This section is compiled back into the original object. The 1575 This section is compiled back into the original object. The
1576 final linker will add all these references into a single table. 1576 final linker will add all these references into a single table.
1577 1577
1578 On boot up, before SMP is initialized, the dynamic ftrace code 1578 On boot up, before SMP is initialized, the dynamic ftrace code
1579 scans this table and updates all the locations into nops. It 1579 scans this table and updates all the locations into nops. It
1580 also records the locations, which are added to the 1580 also records the locations, which are added to the
1581 available_filter_functions list. Modules are processed as they 1581 available_filter_functions list. Modules are processed as they
1582 are loaded and before they are executed. When a module is 1582 are loaded and before they are executed. When a module is
1583 unloaded, it also removes its functions from the ftrace function 1583 unloaded, it also removes its functions from the ftrace function
1584 list. This is automatic in the module unload code, and the 1584 list. This is automatic in the module unload code, and the
1585 module author does not need to worry about it. 1585 module author does not need to worry about it.
1586 1586
1587 When tracing is enabled, kstop_machine is called to prevent 1587 When tracing is enabled, kstop_machine is called to prevent
1588 races with the CPUS executing code being modified (which can 1588 races with the CPUS executing code being modified (which can
1589 cause the CPU to do undesireable things), and the nops are 1589 cause the CPU to do undesireable things), and the nops are
1590 patched back to calls. But this time, they do not call mcount 1590 patched back to calls. But this time, they do not call mcount
1591 (which is just a function stub). They now call into the ftrace 1591 (which is just a function stub). They now call into the ftrace
1592 infrastructure. 1592 infrastructure.
1593 1593
1594 One special side-effect to the recording of the functions being 1594 One special side-effect to the recording of the functions being
1595 traced is that we can now selectively choose which functions we 1595 traced is that we can now selectively choose which functions we
1596 wish to trace and which ones we want the mcount calls to remain 1596 wish to trace and which ones we want the mcount calls to remain
1597 as nops. 1597 as nops.
1598 1598
1599 Two files are used, one for enabling and one for disabling the 1599 Two files are used, one for enabling and one for disabling the
1600 tracing of specified functions. They are: 1600 tracing of specified functions. They are:
1601 1601
1602 set_ftrace_filter 1602 set_ftrace_filter
1603 1603
1604 and 1604 and
1605 1605
1606 set_ftrace_notrace 1606 set_ftrace_notrace
1607 1607
1608 A list of available functions that you can add to these files is 1608 A list of available functions that you can add to these files is
1609 listed in: 1609 listed in:
1610 1610
1611 available_filter_functions 1611 available_filter_functions
1612 1612
1613 # cat available_filter_functions 1613 # cat available_filter_functions
1614 put_prev_task_idle 1614 put_prev_task_idle
1615 kmem_cache_create 1615 kmem_cache_create
1616 pick_next_task_rt 1616 pick_next_task_rt
1617 get_online_cpus 1617 get_online_cpus
1618 pick_next_task_fair 1618 pick_next_task_fair
1619 mutex_lock 1619 mutex_lock
1620 [...] 1620 [...]
1621 1621
1622 If I am only interested in sys_nanosleep and hrtimer_interrupt: 1622 If I am only interested in sys_nanosleep and hrtimer_interrupt:
1623 1623
1624 # echo sys_nanosleep hrtimer_interrupt \ 1624 # echo sys_nanosleep hrtimer_interrupt \
1625 > set_ftrace_filter 1625 > set_ftrace_filter
1626 # echo ftrace > current_tracer 1626 # echo ftrace > current_tracer
1627 # echo 1 > tracing_enabled 1627 # echo 1 > tracing_enabled
1628 # usleep 1 1628 # usleep 1
1629 # echo 0 > tracing_enabled 1629 # echo 0 > tracing_enabled
1630 # cat trace 1630 # cat trace
1631 # tracer: ftrace 1631 # tracer: ftrace
1632 # 1632 #
1633 # TASK-PID CPU# TIMESTAMP FUNCTION 1633 # TASK-PID CPU# TIMESTAMP FUNCTION
1634 # | | | | | 1634 # | | | | |
1635 usleep-4134 [00] 1317.070017: hrtimer_interrupt <-smp_apic_timer_interrupt 1635 usleep-4134 [00] 1317.070017: hrtimer_interrupt <-smp_apic_timer_interrupt
1636 usleep-4134 [00] 1317.070111: sys_nanosleep <-syscall_call 1636 usleep-4134 [00] 1317.070111: sys_nanosleep <-syscall_call
1637 <idle>-0 [00] 1317.070115: hrtimer_interrupt <-smp_apic_timer_interrupt 1637 <idle>-0 [00] 1317.070115: hrtimer_interrupt <-smp_apic_timer_interrupt
1638 1638
1639 To see which functions are being traced, you can cat the file: 1639 To see which functions are being traced, you can cat the file:
1640 1640
1641 # cat set_ftrace_filter 1641 # cat set_ftrace_filter
1642 hrtimer_interrupt 1642 hrtimer_interrupt
1643 sys_nanosleep 1643 sys_nanosleep
1644 1644
1645 1645
1646 Perhaps this is not enough. The filters also allow simple wild 1646 Perhaps this is not enough. The filters also allow simple wild
1647 cards. Only the following are currently available 1647 cards. Only the following are currently available
1648 1648
1649 <match>* - will match functions that begin with <match> 1649 <match>* - will match functions that begin with <match>
1650 *<match> - will match functions that end with <match> 1650 *<match> - will match functions that end with <match>
1651 *<match>* - will match functions that have <match> in it 1651 *<match>* - will match functions that have <match> in it
1652 1652
1653 These are the only wild cards which are supported. 1653 These are the only wild cards which are supported.
1654 1654
1655 <match>*<match> will not work. 1655 <match>*<match> will not work.
1656 1656
1657 Note: It is better to use quotes to enclose the wild cards, 1657 Note: It is better to use quotes to enclose the wild cards,
1658 otherwise the shell may expand the parameters into names 1658 otherwise the shell may expand the parameters into names
1659 of files in the local directory. 1659 of files in the local directory.
1660 1660
1661 # echo 'hrtimer_*' > set_ftrace_filter 1661 # echo 'hrtimer_*' > set_ftrace_filter
1662 1662
1663 Produces: 1663 Produces:
1664 1664
1665 # tracer: ftrace 1665 # tracer: ftrace
1666 # 1666 #
1667 # TASK-PID CPU# TIMESTAMP FUNCTION 1667 # TASK-PID CPU# TIMESTAMP FUNCTION
1668 # | | | | | 1668 # | | | | |
1669 bash-4003 [00] 1480.611794: hrtimer_init <-copy_process 1669 bash-4003 [00] 1480.611794: hrtimer_init <-copy_process
1670 bash-4003 [00] 1480.611941: hrtimer_start <-hrtick_set 1670 bash-4003 [00] 1480.611941: hrtimer_start <-hrtick_set
1671 bash-4003 [00] 1480.611956: hrtimer_cancel <-hrtick_clear 1671 bash-4003 [00] 1480.611956: hrtimer_cancel <-hrtick_clear
1672 bash-4003 [00] 1480.611956: hrtimer_try_to_cancel <-hrtimer_cancel 1672 bash-4003 [00] 1480.611956: hrtimer_try_to_cancel <-hrtimer_cancel
1673 <idle>-0 [00] 1480.612019: hrtimer_get_next_event <-get_next_timer_interrupt 1673 <idle>-0 [00] 1480.612019: hrtimer_get_next_event <-get_next_timer_interrupt
1674 <idle>-0 [00] 1480.612025: hrtimer_get_next_event <-get_next_timer_interrupt 1674 <idle>-0 [00] 1480.612025: hrtimer_get_next_event <-get_next_timer_interrupt
1675 <idle>-0 [00] 1480.612032: hrtimer_get_next_event <-get_next_timer_interrupt 1675 <idle>-0 [00] 1480.612032: hrtimer_get_next_event <-get_next_timer_interrupt
1676 <idle>-0 [00] 1480.612037: hrtimer_get_next_event <-get_next_timer_interrupt 1676 <idle>-0 [00] 1480.612037: hrtimer_get_next_event <-get_next_timer_interrupt
1677 <idle>-0 [00] 1480.612382: hrtimer_get_next_event <-get_next_timer_interrupt 1677 <idle>-0 [00] 1480.612382: hrtimer_get_next_event <-get_next_timer_interrupt
1678 1678
1679 1679
1680 Notice that we lost the sys_nanosleep. 1680 Notice that we lost the sys_nanosleep.
1681 1681
1682 # cat set_ftrace_filter 1682 # cat set_ftrace_filter
1683 hrtimer_run_queues 1683 hrtimer_run_queues
1684 hrtimer_run_pending 1684 hrtimer_run_pending
1685 hrtimer_init 1685 hrtimer_init
1686 hrtimer_cancel 1686 hrtimer_cancel
1687 hrtimer_try_to_cancel 1687 hrtimer_try_to_cancel
1688 hrtimer_forward 1688 hrtimer_forward
1689 hrtimer_start 1689 hrtimer_start
1690 hrtimer_reprogram 1690 hrtimer_reprogram
1691 hrtimer_force_reprogram 1691 hrtimer_force_reprogram
1692 hrtimer_get_next_event 1692 hrtimer_get_next_event
1693 hrtimer_interrupt 1693 hrtimer_interrupt
1694 hrtimer_nanosleep 1694 hrtimer_nanosleep
1695 hrtimer_wakeup 1695 hrtimer_wakeup
1696 hrtimer_get_remaining 1696 hrtimer_get_remaining
1697 hrtimer_get_res 1697 hrtimer_get_res
1698 hrtimer_init_sleeper 1698 hrtimer_init_sleeper
1699 1699
1700 1700
1701 This is because the '>' and '>>' act just like they do in bash. 1701 This is because the '>' and '>>' act just like they do in bash.
1702 To rewrite the filters, use '>' 1702 To rewrite the filters, use '>'
1703 To append to the filters, use '>>' 1703 To append to the filters, use '>>'
1704 1704
1705 To clear out a filter so that all functions will be recorded 1705 To clear out a filter so that all functions will be recorded
1706 again: 1706 again:
1707 1707
1708 # echo > set_ftrace_filter 1708 # echo > set_ftrace_filter
1709 # cat set_ftrace_filter 1709 # cat set_ftrace_filter
1710 # 1710 #
1711 1711
1712 Again, now we want to append. 1712 Again, now we want to append.
1713 1713
1714 # echo sys_nanosleep > set_ftrace_filter 1714 # echo sys_nanosleep > set_ftrace_filter
1715 # cat set_ftrace_filter 1715 # cat set_ftrace_filter
1716 sys_nanosleep 1716 sys_nanosleep
1717 # echo 'hrtimer_*' >> set_ftrace_filter 1717 # echo 'hrtimer_*' >> set_ftrace_filter
1718 # cat set_ftrace_filter 1718 # cat set_ftrace_filter
1719 hrtimer_run_queues 1719 hrtimer_run_queues
1720 hrtimer_run_pending 1720 hrtimer_run_pending
1721 hrtimer_init 1721 hrtimer_init
1722 hrtimer_cancel 1722 hrtimer_cancel
1723 hrtimer_try_to_cancel 1723 hrtimer_try_to_cancel
1724 hrtimer_forward 1724 hrtimer_forward
1725 hrtimer_start 1725 hrtimer_start
1726 hrtimer_reprogram 1726 hrtimer_reprogram
1727 hrtimer_force_reprogram 1727 hrtimer_force_reprogram
1728 hrtimer_get_next_event 1728 hrtimer_get_next_event
1729 hrtimer_interrupt 1729 hrtimer_interrupt
1730 sys_nanosleep 1730 sys_nanosleep
1731 hrtimer_nanosleep 1731 hrtimer_nanosleep
1732 hrtimer_wakeup 1732 hrtimer_wakeup
1733 hrtimer_get_remaining 1733 hrtimer_get_remaining
1734 hrtimer_get_res 1734 hrtimer_get_res
1735 hrtimer_init_sleeper 1735 hrtimer_init_sleeper
1736 1736
1737 1737
1738 The set_ftrace_notrace prevents those functions from being 1738 The set_ftrace_notrace prevents those functions from being
1739 traced. 1739 traced.
1740 1740
1741 # echo '*preempt*' '*lock*' > set_ftrace_notrace 1741 # echo '*preempt*' '*lock*' > set_ftrace_notrace
1742 1742
1743 Produces: 1743 Produces:
1744 1744
1745 # tracer: ftrace 1745 # tracer: ftrace
1746 # 1746 #
1747 # TASK-PID CPU# TIMESTAMP FUNCTION 1747 # TASK-PID CPU# TIMESTAMP FUNCTION
1748 # | | | | | 1748 # | | | | |
1749 bash-4043 [01] 115.281644: finish_task_switch <-schedule 1749 bash-4043 [01] 115.281644: finish_task_switch <-schedule
1750 bash-4043 [01] 115.281645: hrtick_set <-schedule 1750 bash-4043 [01] 115.281645: hrtick_set <-schedule
1751 bash-4043 [01] 115.281645: hrtick_clear <-hrtick_set 1751 bash-4043 [01] 115.281645: hrtick_clear <-hrtick_set
1752 bash-4043 [01] 115.281646: wait_for_completion <-__stop_machine_run 1752 bash-4043 [01] 115.281646: wait_for_completion <-__stop_machine_run
1753 bash-4043 [01] 115.281647: wait_for_common <-wait_for_completion 1753 bash-4043 [01] 115.281647: wait_for_common <-wait_for_completion
1754 bash-4043 [01] 115.281647: kthread_stop <-stop_machine_run 1754 bash-4043 [01] 115.281647: kthread_stop <-stop_machine_run
1755 bash-4043 [01] 115.281648: init_waitqueue_head <-kthread_stop 1755 bash-4043 [01] 115.281648: init_waitqueue_head <-kthread_stop
1756 bash-4043 [01] 115.281648: wake_up_process <-kthread_stop 1756 bash-4043 [01] 115.281648: wake_up_process <-kthread_stop
1757 bash-4043 [01] 115.281649: try_to_wake_up <-wake_up_process 1757 bash-4043 [01] 115.281649: try_to_wake_up <-wake_up_process
1758 1758
1759 We can see that there's no more lock or preempt tracing. 1759 We can see that there's no more lock or preempt tracing.
1760 1760
1761 1761
1762 Dynamic ftrace with the function graph tracer 1762 Dynamic ftrace with the function graph tracer
1763 --------------------------------------------- 1763 ---------------------------------------------
1764 1764
1765 Although what has been explained above concerns both the 1765 Although what has been explained above concerns both the
1766 function tracer and the function-graph-tracer, there are some 1766 function tracer and the function-graph-tracer, there are some
1767 special features only available in the function-graph tracer. 1767 special features only available in the function-graph tracer.
1768 1768
1769 If you want to trace only one function and all of its children, 1769 If you want to trace only one function and all of its children,
1770 you just have to echo its name into set_graph_function: 1770 you just have to echo its name into set_graph_function:
1771 1771
1772 echo __do_fault > set_graph_function 1772 echo __do_fault > set_graph_function
1773 1773
1774 will produce the following "expanded" trace of the __do_fault() 1774 will produce the following "expanded" trace of the __do_fault()
1775 function: 1775 function:
1776 1776
1777 0) | __do_fault() { 1777 0) | __do_fault() {
1778 0) | filemap_fault() { 1778 0) | filemap_fault() {
1779 0) | find_lock_page() { 1779 0) | find_lock_page() {
1780 0) 0.804 us | find_get_page(); 1780 0) 0.804 us | find_get_page();
1781 0) | __might_sleep() { 1781 0) | __might_sleep() {
1782 0) 1.329 us | } 1782 0) 1.329 us | }
1783 0) 3.904 us | } 1783 0) 3.904 us | }
1784 0) 4.979 us | } 1784 0) 4.979 us | }
1785 0) 0.653 us | _spin_lock(); 1785 0) 0.653 us | _spin_lock();
1786 0) 0.578 us | page_add_file_rmap(); 1786 0) 0.578 us | page_add_file_rmap();
1787 0) 0.525 us | native_set_pte_at(); 1787 0) 0.525 us | native_set_pte_at();
1788 0) 0.585 us | _spin_unlock(); 1788 0) 0.585 us | _spin_unlock();
1789 0) | unlock_page() { 1789 0) | unlock_page() {
1790 0) 0.541 us | page_waitqueue(); 1790 0) 0.541 us | page_waitqueue();
1791 0) 0.639 us | __wake_up_bit(); 1791 0) 0.639 us | __wake_up_bit();
1792 0) 2.786 us | } 1792 0) 2.786 us | }
1793 0) + 14.237 us | } 1793 0) + 14.237 us | }
1794 0) | __do_fault() { 1794 0) | __do_fault() {
1795 0) | filemap_fault() { 1795 0) | filemap_fault() {
1796 0) | find_lock_page() { 1796 0) | find_lock_page() {
1797 0) 0.698 us | find_get_page(); 1797 0) 0.698 us | find_get_page();
1798 0) | __might_sleep() { 1798 0) | __might_sleep() {
1799 0) 1.412 us | } 1799 0) 1.412 us | }
1800 0) 3.950 us | } 1800 0) 3.950 us | }
1801 0) 5.098 us | } 1801 0) 5.098 us | }
1802 0) 0.631 us | _spin_lock(); 1802 0) 0.631 us | _spin_lock();
1803 0) 0.571 us | page_add_file_rmap(); 1803 0) 0.571 us | page_add_file_rmap();
1804 0) 0.526 us | native_set_pte_at(); 1804 0) 0.526 us | native_set_pte_at();
1805 0) 0.586 us | _spin_unlock(); 1805 0) 0.586 us | _spin_unlock();
1806 0) | unlock_page() { 1806 0) | unlock_page() {
1807 0) 0.533 us | page_waitqueue(); 1807 0) 0.533 us | page_waitqueue();
1808 0) 0.638 us | __wake_up_bit(); 1808 0) 0.638 us | __wake_up_bit();
1809 0) 2.793 us | } 1809 0) 2.793 us | }
1810 0) + 14.012 us | } 1810 0) + 14.012 us | }
1811 1811
1812 You can also expand several functions at once: 1812 You can also expand several functions at once:
1813 1813
1814 echo sys_open > set_graph_function 1814 echo sys_open > set_graph_function
1815 echo sys_close >> set_graph_function 1815 echo sys_close >> set_graph_function
1816 1816
1817 Now if you want to go back to trace all functions you can clear 1817 Now if you want to go back to trace all functions you can clear
1818 this special filter via: 1818 this special filter via:
1819 1819
1820 echo > set_graph_function 1820 echo > set_graph_function
1821 1821
1822 1822
1823 trace_pipe 1823 trace_pipe
1824 ---------- 1824 ----------
1825 1825
1826 The trace_pipe outputs the same content as the trace file, but 1826 The trace_pipe outputs the same content as the trace file, but
1827 the effect on the tracing is different. Every read from 1827 the effect on the tracing is different. Every read from
1828 trace_pipe is consumed. This means that subsequent reads will be 1828 trace_pipe is consumed. This means that subsequent reads will be
1829 different. The trace is live. 1829 different. The trace is live.
1830 1830
1831 # echo function > current_tracer 1831 # echo function > current_tracer
1832 # cat trace_pipe > /tmp/trace.out & 1832 # cat trace_pipe > /tmp/trace.out &
1833 [1] 4153 1833 [1] 4153
1834 # echo 1 > tracing_enabled 1834 # echo 1 > tracing_enabled
1835 # usleep 1 1835 # usleep 1
1836 # echo 0 > tracing_enabled 1836 # echo 0 > tracing_enabled
1837 # cat trace 1837 # cat trace
1838 # tracer: function 1838 # tracer: function
1839 # 1839 #
1840 # TASK-PID CPU# TIMESTAMP FUNCTION 1840 # TASK-PID CPU# TIMESTAMP FUNCTION
1841 # | | | | | 1841 # | | | | |
1842 1842
1843 # 1843 #
1844 # cat /tmp/trace.out 1844 # cat /tmp/trace.out
1845 bash-4043 [00] 41.267106: finish_task_switch <-schedule 1845 bash-4043 [00] 41.267106: finish_task_switch <-schedule
1846 bash-4043 [00] 41.267106: hrtick_set <-schedule 1846 bash-4043 [00] 41.267106: hrtick_set <-schedule
1847 bash-4043 [00] 41.267107: hrtick_clear <-hrtick_set 1847 bash-4043 [00] 41.267107: hrtick_clear <-hrtick_set
1848 bash-4043 [00] 41.267108: wait_for_completion <-__stop_machine_run 1848 bash-4043 [00] 41.267108: wait_for_completion <-__stop_machine_run
1849 bash-4043 [00] 41.267108: wait_for_common <-wait_for_completion 1849 bash-4043 [00] 41.267108: wait_for_common <-wait_for_completion
1850 bash-4043 [00] 41.267109: kthread_stop <-stop_machine_run 1850 bash-4043 [00] 41.267109: kthread_stop <-stop_machine_run
1851 bash-4043 [00] 41.267109: init_waitqueue_head <-kthread_stop 1851 bash-4043 [00] 41.267109: init_waitqueue_head <-kthread_stop
1852 bash-4043 [00] 41.267110: wake_up_process <-kthread_stop 1852 bash-4043 [00] 41.267110: wake_up_process <-kthread_stop
1853 bash-4043 [00] 41.267110: try_to_wake_up <-wake_up_process 1853 bash-4043 [00] 41.267110: try_to_wake_up <-wake_up_process
1854 bash-4043 [00] 41.267111: select_task_rq_rt <-try_to_wake_up 1854 bash-4043 [00] 41.267111: select_task_rq_rt <-try_to_wake_up
1855 1855
1856 1856
1857 Note, reading the trace_pipe file will block until more input is 1857 Note, reading the trace_pipe file will block until more input is
1858 added. By changing the tracer, trace_pipe will issue an EOF. We 1858 added. By changing the tracer, trace_pipe will issue an EOF. We
1859 needed to set the function tracer _before_ we "cat" the 1859 needed to set the function tracer _before_ we "cat" the
1860 trace_pipe file. 1860 trace_pipe file.
1861 1861
1862 1862
1863 trace entries 1863 trace entries
1864 ------------- 1864 -------------
1865 1865
1866 Having too much or not enough data can be troublesome in 1866 Having too much or not enough data can be troublesome in
1867 diagnosing an issue in the kernel. The file buffer_size_kb is 1867 diagnosing an issue in the kernel. The file buffer_size_kb is
1868 used to modify the size of the internal trace buffers. The 1868 used to modify the size of the internal trace buffers. The
1869 number listed is the number of entries that can be recorded per 1869 number listed is the number of entries that can be recorded per
1870 CPU. To know the full size, multiply the number of possible CPUS 1870 CPU. To know the full size, multiply the number of possible CPUS
1871 with the number of entries. 1871 with the number of entries.
1872 1872
1873 # cat buffer_size_kb 1873 # cat buffer_size_kb
1874 1408 (units kilobytes) 1874 1408 (units kilobytes)
1875 1875
1876 Note, to modify this, you must have tracing completely disabled. 1876 Note, to modify this, you must have tracing completely disabled.
1877 To do that, echo "nop" into the current_tracer. If the 1877 To do that, echo "nop" into the current_tracer. If the
1878 current_tracer is not set to "nop", an EINVAL error will be 1878 current_tracer is not set to "nop", an EINVAL error will be
1879 returned. 1879 returned.
1880 1880
1881 # echo nop > current_tracer 1881 # echo nop > current_tracer
1882 # echo 10000 > buffer_size_kb 1882 # echo 10000 > buffer_size_kb
1883 # cat buffer_size_kb 1883 # cat buffer_size_kb
1884 10000 (units kilobytes) 1884 10000 (units kilobytes)
1885 1885
1886 The number of pages which will be allocated is limited to a 1886 The number of pages which will be allocated is limited to a
1887 percentage of available memory. Allocating too much will produce 1887 percentage of available memory. Allocating too much will produce
1888 an error. 1888 an error.
1889 1889
1890 # echo 1000000000000 > buffer_size_kb 1890 # echo 1000000000000 > buffer_size_kb
1891 -bash: echo: write error: Cannot allocate memory 1891 -bash: echo: write error: Cannot allocate memory
1892 # cat buffer_size_kb 1892 # cat buffer_size_kb
1893 85 1893 85
1894 1894
1895 ----------- 1895 -----------
1896 1896
1897 More details can be found in the source code, in the 1897 More details can be found in the source code, in the
1898 kernel/trace/*.c files. 1898 kernel/trace/*.c files.
1899 1899
1 # 1 #
2 # arch/arm/Makefile 2 # arch/arm/Makefile
3 # 3 #
4 # This file is included by the global makefile so that you can add your own 4 # This file is included by the global makefile so that you can add your own
5 # architecture-specific flags and dependencies. 5 # architecture-specific flags and dependencies.
6 # 6 #
7 # This file is subject to the terms and conditions of the GNU General Public 7 # This file is subject to the terms and conditions of the GNU General Public
8 # License. See the file "COPYING" in the main directory of this archive 8 # License. See the file "COPYING" in the main directory of this archive
9 # for more details. 9 # for more details.
10 # 10 #
11 # Copyright (C) 1995-2001 by Russell King 11 # Copyright (C) 1995-2001 by Russell King
12 12
13 LDFLAGS_vmlinux :=-p --no-undefined -X 13 LDFLAGS_vmlinux :=-p --no-undefined -X
14 ifeq ($(CONFIG_CPU_ENDIAN_BE8),y) 14 ifeq ($(CONFIG_CPU_ENDIAN_BE8),y)
15 LDFLAGS_vmlinux += --be8 15 LDFLAGS_vmlinux += --be8
16 endif 16 endif
17 CPPFLAGS_vmlinux.lds = -DTEXT_OFFSET=$(TEXT_OFFSET) 17 CPPFLAGS_vmlinux.lds = -DTEXT_OFFSET=$(TEXT_OFFSET)
18 OBJCOPYFLAGS :=-O binary -R .note -R .note.gnu.build-id -R .comment -S 18 OBJCOPYFLAGS :=-O binary -R .note -R .note.gnu.build-id -R .comment -S
19 GZFLAGS :=-9 19 GZFLAGS :=-9
20 #KBUILD_CFLAGS +=-pipe 20 #KBUILD_CFLAGS +=-pipe
21 # Explicitly specifiy 32-bit ARM ISA since toolchain default can be -mthumb: 21 # Explicitly specifiy 32-bit ARM ISA since toolchain default can be -mthumb:
22 KBUILD_CFLAGS +=$(call cc-option,-marm,) 22 KBUILD_CFLAGS +=$(call cc-option,-marm,)
23 23
24 # Do not use arch/arm/defconfig - it's always outdated. 24 # Do not use arch/arm/defconfig - it's always outdated.
25 # Select a platform tht is kept up-to-date 25 # Select a platform tht is kept up-to-date
26 KBUILD_DEFCONFIG := versatile_defconfig 26 KBUILD_DEFCONFIG := versatile_defconfig
27 27
28 # defines filename extension depending memory manement type. 28 # defines filename extension depending memory management type.
29 ifeq ($(CONFIG_MMU),) 29 ifeq ($(CONFIG_MMU),)
30 MMUEXT := -nommu 30 MMUEXT := -nommu
31 endif 31 endif
32 32
33 ifeq ($(CONFIG_FRAME_POINTER),y) 33 ifeq ($(CONFIG_FRAME_POINTER),y)
34 KBUILD_CFLAGS +=-fno-omit-frame-pointer -mapcs -mno-sched-prolog 34 KBUILD_CFLAGS +=-fno-omit-frame-pointer -mapcs -mno-sched-prolog
35 endif 35 endif
36 36
37 ifeq ($(CONFIG_CPU_BIG_ENDIAN),y) 37 ifeq ($(CONFIG_CPU_BIG_ENDIAN),y)
38 KBUILD_CPPFLAGS += -mbig-endian 38 KBUILD_CPPFLAGS += -mbig-endian
39 AS += -EB 39 AS += -EB
40 LD += -EB 40 LD += -EB
41 else 41 else
42 KBUILD_CPPFLAGS += -mlittle-endian 42 KBUILD_CPPFLAGS += -mlittle-endian
43 AS += -EL 43 AS += -EL
44 LD += -EL 44 LD += -EL
45 endif 45 endif
46 46
47 comma = , 47 comma = ,
48 48
49 # This selects which instruction set is used. 49 # This selects which instruction set is used.
50 # Note that GCC does not numerically define an architecture version 50 # Note that GCC does not numerically define an architecture version
51 # macro, but instead defines a whole series of macros which makes 51 # macro, but instead defines a whole series of macros which makes
52 # testing for a specific architecture or later rather impossible. 52 # testing for a specific architecture or later rather impossible.
53 arch-$(CONFIG_CPU_32v7) :=-D__LINUX_ARM_ARCH__=7 $(call cc-option,-march=armv7-a,-march=armv5t -Wa$(comma)-march=armv7-a) 53 arch-$(CONFIG_CPU_32v7) :=-D__LINUX_ARM_ARCH__=7 $(call cc-option,-march=armv7-a,-march=armv5t -Wa$(comma)-march=armv7-a)
54 arch-$(CONFIG_CPU_32v6) :=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6,-march=armv5t -Wa$(comma)-march=armv6) 54 arch-$(CONFIG_CPU_32v6) :=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6,-march=armv5t -Wa$(comma)-march=armv6)
55 # Only override the compiler option if ARMv6. The ARMv6K extensions are 55 # Only override the compiler option if ARMv6. The ARMv6K extensions are
56 # always available in ARMv7 56 # always available in ARMv7
57 ifeq ($(CONFIG_CPU_32v6),y) 57 ifeq ($(CONFIG_CPU_32v6),y)
58 arch-$(CONFIG_CPU_32v6K) :=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6k,-march=armv5t -Wa$(comma)-march=armv6k) 58 arch-$(CONFIG_CPU_32v6K) :=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6k,-march=armv5t -Wa$(comma)-march=armv6k)
59 endif 59 endif
60 arch-$(CONFIG_CPU_32v5) :=-D__LINUX_ARM_ARCH__=5 $(call cc-option,-march=armv5te,-march=armv4t) 60 arch-$(CONFIG_CPU_32v5) :=-D__LINUX_ARM_ARCH__=5 $(call cc-option,-march=armv5te,-march=armv4t)
61 arch-$(CONFIG_CPU_32v4T) :=-D__LINUX_ARM_ARCH__=4 -march=armv4t 61 arch-$(CONFIG_CPU_32v4T) :=-D__LINUX_ARM_ARCH__=4 -march=armv4t
62 arch-$(CONFIG_CPU_32v4) :=-D__LINUX_ARM_ARCH__=4 -march=armv4 62 arch-$(CONFIG_CPU_32v4) :=-D__LINUX_ARM_ARCH__=4 -march=armv4
63 arch-$(CONFIG_CPU_32v3) :=-D__LINUX_ARM_ARCH__=3 -march=armv3 63 arch-$(CONFIG_CPU_32v3) :=-D__LINUX_ARM_ARCH__=3 -march=armv3
64 64
65 # This selects how we optimise for the processor. 65 # This selects how we optimise for the processor.
66 tune-$(CONFIG_CPU_ARM610) :=-mtune=arm610 66 tune-$(CONFIG_CPU_ARM610) :=-mtune=arm610
67 tune-$(CONFIG_CPU_ARM710) :=-mtune=arm710 67 tune-$(CONFIG_CPU_ARM710) :=-mtune=arm710
68 tune-$(CONFIG_CPU_ARM7TDMI) :=-mtune=arm7tdmi 68 tune-$(CONFIG_CPU_ARM7TDMI) :=-mtune=arm7tdmi
69 tune-$(CONFIG_CPU_ARM720T) :=-mtune=arm7tdmi 69 tune-$(CONFIG_CPU_ARM720T) :=-mtune=arm7tdmi
70 tune-$(CONFIG_CPU_ARM740T) :=-mtune=arm7tdmi 70 tune-$(CONFIG_CPU_ARM740T) :=-mtune=arm7tdmi
71 tune-$(CONFIG_CPU_ARM9TDMI) :=-mtune=arm9tdmi 71 tune-$(CONFIG_CPU_ARM9TDMI) :=-mtune=arm9tdmi
72 tune-$(CONFIG_CPU_ARM940T) :=-mtune=arm9tdmi 72 tune-$(CONFIG_CPU_ARM940T) :=-mtune=arm9tdmi
73 tune-$(CONFIG_CPU_ARM946E) :=$(call cc-option,-mtune=arm9e,-mtune=arm9tdmi) 73 tune-$(CONFIG_CPU_ARM946E) :=$(call cc-option,-mtune=arm9e,-mtune=arm9tdmi)
74 tune-$(CONFIG_CPU_ARM920T) :=-mtune=arm9tdmi 74 tune-$(CONFIG_CPU_ARM920T) :=-mtune=arm9tdmi
75 tune-$(CONFIG_CPU_ARM922T) :=-mtune=arm9tdmi 75 tune-$(CONFIG_CPU_ARM922T) :=-mtune=arm9tdmi
76 tune-$(CONFIG_CPU_ARM925T) :=-mtune=arm9tdmi 76 tune-$(CONFIG_CPU_ARM925T) :=-mtune=arm9tdmi
77 tune-$(CONFIG_CPU_ARM926T) :=-mtune=arm9tdmi 77 tune-$(CONFIG_CPU_ARM926T) :=-mtune=arm9tdmi
78 tune-$(CONFIG_CPU_FA526) :=-mtune=arm9tdmi 78 tune-$(CONFIG_CPU_FA526) :=-mtune=arm9tdmi
79 tune-$(CONFIG_CPU_SA110) :=-mtune=strongarm110 79 tune-$(CONFIG_CPU_SA110) :=-mtune=strongarm110
80 tune-$(CONFIG_CPU_SA1100) :=-mtune=strongarm1100 80 tune-$(CONFIG_CPU_SA1100) :=-mtune=strongarm1100
81 tune-$(CONFIG_CPU_XSCALE) :=$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale 81 tune-$(CONFIG_CPU_XSCALE) :=$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale
82 tune-$(CONFIG_CPU_XSC3) :=$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale 82 tune-$(CONFIG_CPU_XSC3) :=$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale
83 tune-$(CONFIG_CPU_FEROCEON) :=$(call cc-option,-mtune=marvell-f,-mtune=xscale) 83 tune-$(CONFIG_CPU_FEROCEON) :=$(call cc-option,-mtune=marvell-f,-mtune=xscale)
84 tune-$(CONFIG_CPU_V6) :=$(call cc-option,-mtune=arm1136j-s,-mtune=strongarm) 84 tune-$(CONFIG_CPU_V6) :=$(call cc-option,-mtune=arm1136j-s,-mtune=strongarm)
85 85
86 ifeq ($(CONFIG_AEABI),y) 86 ifeq ($(CONFIG_AEABI),y)
87 CFLAGS_ABI :=-mabi=aapcs-linux -mno-thumb-interwork 87 CFLAGS_ABI :=-mabi=aapcs-linux -mno-thumb-interwork
88 else 88 else
89 CFLAGS_ABI :=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) $(call cc-option,-mno-thumb-interwork,) 89 CFLAGS_ABI :=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) $(call cc-option,-mno-thumb-interwork,)
90 endif 90 endif
91 91
92 ifeq ($(CONFIG_ARM_UNWIND),y) 92 ifeq ($(CONFIG_ARM_UNWIND),y)
93 CFLAGS_ABI +=-funwind-tables 93 CFLAGS_ABI +=-funwind-tables
94 endif 94 endif
95 95
96 ifeq ($(CONFIG_THUMB2_KERNEL),y) 96 ifeq ($(CONFIG_THUMB2_KERNEL),y)
97 AFLAGS_AUTOIT :=$(call as-option,-Wa$(comma)-mimplicit-it=thumb,-Wa$(comma)-mauto-it) 97 AFLAGS_AUTOIT :=$(call as-option,-Wa$(comma)-mimplicit-it=thumb,-Wa$(comma)-mauto-it)
98 AFLAGS_NOWARN :=$(call as-option,-Wa$(comma)-mno-warn-deprecated,-Wa$(comma)-W) 98 AFLAGS_NOWARN :=$(call as-option,-Wa$(comma)-mno-warn-deprecated,-Wa$(comma)-W)
99 CFLAGS_THUMB2 :=-mthumb $(AFLAGS_AUTOIT) $(AFLAGS_NOWARN) 99 CFLAGS_THUMB2 :=-mthumb $(AFLAGS_AUTOIT) $(AFLAGS_NOWARN)
100 AFLAGS_THUMB2 :=$(CFLAGS_THUMB2) -Wa$(comma)-mthumb 100 AFLAGS_THUMB2 :=$(CFLAGS_THUMB2) -Wa$(comma)-mthumb
101 endif 101 endif
102 102
103 # Need -Uarm for gcc < 3.x 103 # Need -Uarm for gcc < 3.x
104 KBUILD_CFLAGS +=$(CFLAGS_ABI) $(CFLAGS_THUMB2) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -msoft-float -Uarm 104 KBUILD_CFLAGS +=$(CFLAGS_ABI) $(CFLAGS_THUMB2) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -msoft-float -Uarm
105 KBUILD_AFLAGS +=$(CFLAGS_ABI) $(AFLAGS_THUMB2) $(arch-y) $(tune-y) -include asm/unified.h -msoft-float 105 KBUILD_AFLAGS +=$(CFLAGS_ABI) $(AFLAGS_THUMB2) $(arch-y) $(tune-y) -include asm/unified.h -msoft-float
106 106
107 CHECKFLAGS += -D__arm__ 107 CHECKFLAGS += -D__arm__
108 108
109 #Default value 109 #Default value
110 head-y := arch/arm/kernel/head$(MMUEXT).o arch/arm/kernel/init_task.o 110 head-y := arch/arm/kernel/head$(MMUEXT).o arch/arm/kernel/init_task.o
111 textofs-y := 0x00008000 111 textofs-y := 0x00008000
112 textofs-$(CONFIG_ARCH_CLPS711X) := 0x00028000 112 textofs-$(CONFIG_ARCH_CLPS711X) := 0x00028000
113 # SA1111 DMA bug: we don't want the kernel to live in precious DMA-able memory 113 # SA1111 DMA bug: we don't want the kernel to live in precious DMA-able memory
114 ifeq ($(CONFIG_ARCH_SA1100),y) 114 ifeq ($(CONFIG_ARCH_SA1100),y)
115 textofs-$(CONFIG_SA1111) := 0x00208000 115 textofs-$(CONFIG_SA1111) := 0x00208000
116 endif 116 endif
117 117
118 # Machine directory name. This list is sorted alphanumerically 118 # Machine directory name. This list is sorted alphanumerically
119 # by CONFIG_* macro name. 119 # by CONFIG_* macro name.
120 machine-$(CONFIG_ARCH_AAEC2000) := aaec2000 120 machine-$(CONFIG_ARCH_AAEC2000) := aaec2000
121 machine-$(CONFIG_ARCH_AT91) := at91 121 machine-$(CONFIG_ARCH_AT91) := at91
122 machine-$(CONFIG_ARCH_BCMRING) := bcmring 122 machine-$(CONFIG_ARCH_BCMRING) := bcmring
123 machine-$(CONFIG_ARCH_CLPS711X) := clps711x 123 machine-$(CONFIG_ARCH_CLPS711X) := clps711x
124 machine-$(CONFIG_ARCH_DAVINCI) := davinci 124 machine-$(CONFIG_ARCH_DAVINCI) := davinci
125 machine-$(CONFIG_ARCH_EBSA110) := ebsa110 125 machine-$(CONFIG_ARCH_EBSA110) := ebsa110
126 machine-$(CONFIG_ARCH_EP93XX) := ep93xx 126 machine-$(CONFIG_ARCH_EP93XX) := ep93xx
127 machine-$(CONFIG_ARCH_GEMINI) := gemini 127 machine-$(CONFIG_ARCH_GEMINI) := gemini
128 machine-$(CONFIG_ARCH_H720X) := h720x 128 machine-$(CONFIG_ARCH_H720X) := h720x
129 machine-$(CONFIG_ARCH_INTEGRATOR) := integrator 129 machine-$(CONFIG_ARCH_INTEGRATOR) := integrator
130 machine-$(CONFIG_ARCH_IOP13XX) := iop13xx 130 machine-$(CONFIG_ARCH_IOP13XX) := iop13xx
131 machine-$(CONFIG_ARCH_IOP32X) := iop32x 131 machine-$(CONFIG_ARCH_IOP32X) := iop32x
132 machine-$(CONFIG_ARCH_IOP33X) := iop33x 132 machine-$(CONFIG_ARCH_IOP33X) := iop33x
133 machine-$(CONFIG_ARCH_IXP2000) := ixp2000 133 machine-$(CONFIG_ARCH_IXP2000) := ixp2000
134 machine-$(CONFIG_ARCH_IXP23XX) := ixp23xx 134 machine-$(CONFIG_ARCH_IXP23XX) := ixp23xx
135 machine-$(CONFIG_ARCH_IXP4XX) := ixp4xx 135 machine-$(CONFIG_ARCH_IXP4XX) := ixp4xx
136 machine-$(CONFIG_ARCH_KIRKWOOD) := kirkwood 136 machine-$(CONFIG_ARCH_KIRKWOOD) := kirkwood
137 machine-$(CONFIG_ARCH_KS8695) := ks8695 137 machine-$(CONFIG_ARCH_KS8695) := ks8695
138 machine-$(CONFIG_ARCH_L7200) := l7200 138 machine-$(CONFIG_ARCH_L7200) := l7200
139 machine-$(CONFIG_ARCH_LH7A40X) := lh7a40x 139 machine-$(CONFIG_ARCH_LH7A40X) := lh7a40x
140 machine-$(CONFIG_ARCH_LOKI) := loki 140 machine-$(CONFIG_ARCH_LOKI) := loki
141 machine-$(CONFIG_ARCH_MMP) := mmp 141 machine-$(CONFIG_ARCH_MMP) := mmp
142 machine-$(CONFIG_ARCH_MSM) := msm 142 machine-$(CONFIG_ARCH_MSM) := msm
143 machine-$(CONFIG_ARCH_MV78XX0) := mv78xx0 143 machine-$(CONFIG_ARCH_MV78XX0) := mv78xx0
144 machine-$(CONFIG_ARCH_MX1) := mx1 144 machine-$(CONFIG_ARCH_MX1) := mx1
145 machine-$(CONFIG_ARCH_MX2) := mx2 145 machine-$(CONFIG_ARCH_MX2) := mx2
146 machine-$(CONFIG_ARCH_MX25) := mx25 146 machine-$(CONFIG_ARCH_MX25) := mx25
147 machine-$(CONFIG_ARCH_MX3) := mx3 147 machine-$(CONFIG_ARCH_MX3) := mx3
148 machine-$(CONFIG_ARCH_NETX) := netx 148 machine-$(CONFIG_ARCH_NETX) := netx
149 machine-$(CONFIG_ARCH_NOMADIK) := nomadik 149 machine-$(CONFIG_ARCH_NOMADIK) := nomadik
150 machine-$(CONFIG_ARCH_NS9XXX) := ns9xxx 150 machine-$(CONFIG_ARCH_NS9XXX) := ns9xxx
151 machine-$(CONFIG_ARCH_OMAP1) := omap1 151 machine-$(CONFIG_ARCH_OMAP1) := omap1
152 machine-$(CONFIG_ARCH_OMAP2) := omap2 152 machine-$(CONFIG_ARCH_OMAP2) := omap2
153 machine-$(CONFIG_ARCH_OMAP3) := omap2 153 machine-$(CONFIG_ARCH_OMAP3) := omap2
154 machine-$(CONFIG_ARCH_OMAP4) := omap2 154 machine-$(CONFIG_ARCH_OMAP4) := omap2
155 machine-$(CONFIG_ARCH_ORION5X) := orion5x 155 machine-$(CONFIG_ARCH_ORION5X) := orion5x
156 machine-$(CONFIG_ARCH_PNX4008) := pnx4008 156 machine-$(CONFIG_ARCH_PNX4008) := pnx4008
157 machine-$(CONFIG_ARCH_PXA) := pxa 157 machine-$(CONFIG_ARCH_PXA) := pxa
158 machine-$(CONFIG_ARCH_REALVIEW) := realview 158 machine-$(CONFIG_ARCH_REALVIEW) := realview
159 machine-$(CONFIG_ARCH_RPC) := rpc 159 machine-$(CONFIG_ARCH_RPC) := rpc
160 machine-$(CONFIG_ARCH_S3C2410) := s3c2410 s3c2400 s3c2412 s3c2440 s3c2442 s3c2443 160 machine-$(CONFIG_ARCH_S3C2410) := s3c2410 s3c2400 s3c2412 s3c2440 s3c2442 s3c2443
161 machine-$(CONFIG_ARCH_S3C24A0) := s3c24a0 161 machine-$(CONFIG_ARCH_S3C24A0) := s3c24a0
162 machine-$(CONFIG_ARCH_S3C64XX) := s3c6400 s3c6410 162 machine-$(CONFIG_ARCH_S3C64XX) := s3c6400 s3c6410
163 machine-$(CONFIG_ARCH_S5PC1XX) := s5pc100 163 machine-$(CONFIG_ARCH_S5PC1XX) := s5pc100
164 machine-$(CONFIG_ARCH_SA1100) := sa1100 164 machine-$(CONFIG_ARCH_SA1100) := sa1100
165 machine-$(CONFIG_ARCH_SHARK) := shark 165 machine-$(CONFIG_ARCH_SHARK) := shark
166 machine-$(CONFIG_ARCH_STMP378X) := stmp378x 166 machine-$(CONFIG_ARCH_STMP378X) := stmp378x
167 machine-$(CONFIG_ARCH_STMP37XX) := stmp37xx 167 machine-$(CONFIG_ARCH_STMP37XX) := stmp37xx
168 machine-$(CONFIG_ARCH_U300) := u300 168 machine-$(CONFIG_ARCH_U300) := u300
169 machine-$(CONFIG_ARCH_VERSATILE) := versatile 169 machine-$(CONFIG_ARCH_VERSATILE) := versatile
170 machine-$(CONFIG_ARCH_W90X900) := w90x900 170 machine-$(CONFIG_ARCH_W90X900) := w90x900
171 machine-$(CONFIG_FOOTBRIDGE) := footbridge 171 machine-$(CONFIG_FOOTBRIDGE) := footbridge
172 machine-$(CONFIG_ARCH_MXC91231) := mxc91231 172 machine-$(CONFIG_ARCH_MXC91231) := mxc91231
173 173
174 # Platform directory name. This list is sorted alphanumerically 174 # Platform directory name. This list is sorted alphanumerically
175 # by CONFIG_* macro name. 175 # by CONFIG_* macro name.
176 plat-$(CONFIG_ARCH_MXC) := mxc 176 plat-$(CONFIG_ARCH_MXC) := mxc
177 plat-$(CONFIG_ARCH_OMAP) := omap 177 plat-$(CONFIG_ARCH_OMAP) := omap
178 plat-$(CONFIG_PLAT_IOP) := iop 178 plat-$(CONFIG_PLAT_IOP) := iop
179 plat-$(CONFIG_PLAT_ORION) := orion 179 plat-$(CONFIG_PLAT_ORION) := orion
180 plat-$(CONFIG_PLAT_PXA) := pxa 180 plat-$(CONFIG_PLAT_PXA) := pxa
181 plat-$(CONFIG_PLAT_S3C24XX) := s3c24xx s3c 181 plat-$(CONFIG_PLAT_S3C24XX) := s3c24xx s3c
182 plat-$(CONFIG_PLAT_S3C64XX) := s3c64xx s3c 182 plat-$(CONFIG_PLAT_S3C64XX) := s3c64xx s3c
183 plat-$(CONFIG_PLAT_S5PC1XX) := s5pc1xx s3c 183 plat-$(CONFIG_PLAT_S5PC1XX) := s5pc1xx s3c
184 plat-$(CONFIG_ARCH_STMP3XXX) := stmp3xxx 184 plat-$(CONFIG_ARCH_STMP3XXX) := stmp3xxx
185 185
186 ifeq ($(CONFIG_ARCH_EBSA110),y) 186 ifeq ($(CONFIG_ARCH_EBSA110),y)
187 # This is what happens if you forget the IOCS16 line. 187 # This is what happens if you forget the IOCS16 line.
188 # PCMCIA cards stop working. 188 # PCMCIA cards stop working.
189 CFLAGS_3c589_cs.o :=-DISA_SIXTEEN_BIT_PERIPHERAL 189 CFLAGS_3c589_cs.o :=-DISA_SIXTEEN_BIT_PERIPHERAL
190 export CFLAGS_3c589_cs.o 190 export CFLAGS_3c589_cs.o
191 endif 191 endif
192 192
193 # The byte offset of the kernel image in RAM from the start of RAM. 193 # The byte offset of the kernel image in RAM from the start of RAM.
194 TEXT_OFFSET := $(textofs-y) 194 TEXT_OFFSET := $(textofs-y)
195 195
196 # The first directory contains additional information for the boot setup code 196 # The first directory contains additional information for the boot setup code
197 ifneq ($(machine-y),) 197 ifneq ($(machine-y),)
198 MACHINE := arch/arm/mach-$(word 1,$(machine-y))/ 198 MACHINE := arch/arm/mach-$(word 1,$(machine-y))/
199 else 199 else
200 MACHINE := 200 MACHINE :=
201 endif 201 endif
202 202
203 machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y)) 203 machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y))
204 platdirs := $(patsubst %,arch/arm/plat-%/,$(plat-y)) 204 platdirs := $(patsubst %,arch/arm/plat-%/,$(plat-y))
205 205
206 ifeq ($(KBUILD_SRC),) 206 ifeq ($(KBUILD_SRC),)
207 KBUILD_CPPFLAGS += $(patsubst %,-I%include,$(machdirs) $(platdirs)) 207 KBUILD_CPPFLAGS += $(patsubst %,-I%include,$(machdirs) $(platdirs))
208 else 208 else
209 KBUILD_CPPFLAGS += $(patsubst %,-I$(srctree)/%include,$(machdirs) $(platdirs)) 209 KBUILD_CPPFLAGS += $(patsubst %,-I$(srctree)/%include,$(machdirs) $(platdirs))
210 endif 210 endif
211 211
212 export TEXT_OFFSET GZFLAGS MMUEXT 212 export TEXT_OFFSET GZFLAGS MMUEXT
213 213
214 # Do we have FASTFPE? 214 # Do we have FASTFPE?
215 FASTFPE :=arch/arm/fastfpe 215 FASTFPE :=arch/arm/fastfpe
216 ifeq ($(FASTFPE),$(wildcard $(FASTFPE))) 216 ifeq ($(FASTFPE),$(wildcard $(FASTFPE)))
217 FASTFPE_OBJ :=$(FASTFPE)/ 217 FASTFPE_OBJ :=$(FASTFPE)/
218 endif 218 endif
219 219
220 # If we have a machine-specific directory, then include it in the build. 220 # If we have a machine-specific directory, then include it in the build.
221 core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/ 221 core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/
222 core-y += $(machdirs) $(platdirs) 222 core-y += $(machdirs) $(platdirs)
223 core-$(CONFIG_FPE_NWFPE) += arch/arm/nwfpe/ 223 core-$(CONFIG_FPE_NWFPE) += arch/arm/nwfpe/
224 core-$(CONFIG_FPE_FASTFPE) += $(FASTFPE_OBJ) 224 core-$(CONFIG_FPE_FASTFPE) += $(FASTFPE_OBJ)
225 core-$(CONFIG_VFP) += arch/arm/vfp/ 225 core-$(CONFIG_VFP) += arch/arm/vfp/
226 226
227 drivers-$(CONFIG_OPROFILE) += arch/arm/oprofile/ 227 drivers-$(CONFIG_OPROFILE) += arch/arm/oprofile/
228 228
229 libs-y := arch/arm/lib/ $(libs-y) 229 libs-y := arch/arm/lib/ $(libs-y)
230 230
231 # Default target when executing plain make 231 # Default target when executing plain make
232 ifeq ($(CONFIG_XIP_KERNEL),y) 232 ifeq ($(CONFIG_XIP_KERNEL),y)
233 KBUILD_IMAGE := xipImage 233 KBUILD_IMAGE := xipImage
234 else 234 else
235 KBUILD_IMAGE := zImage 235 KBUILD_IMAGE := zImage
236 endif 236 endif
237 237
238 all: $(KBUILD_IMAGE) 238 all: $(KBUILD_IMAGE)
239 239
240 boot := arch/arm/boot 240 boot := arch/arm/boot
241 241
242 # Update machine arch and proc symlinks if something which affects 242 # Update machine arch and proc symlinks if something which affects
243 # them changed. We use .arch to indicate when they were updated 243 # them changed. We use .arch to indicate when they were updated
244 # last, otherwise make uses the target directory mtime. 244 # last, otherwise make uses the target directory mtime.
245 245
246 archprepare: maketools 246 archprepare: maketools
247 247
248 PHONY += maketools FORCE 248 PHONY += maketools FORCE
249 maketools: include/linux/version.h FORCE 249 maketools: include/linux/version.h FORCE
250 $(Q)$(MAKE) $(build)=arch/arm/tools include/asm-arm/mach-types.h 250 $(Q)$(MAKE) $(build)=arch/arm/tools include/asm-arm/mach-types.h
251 251
252 # Convert bzImage to zImage 252 # Convert bzImage to zImage
253 bzImage: zImage 253 bzImage: zImage
254 254
255 zImage Image xipImage bootpImage uImage: vmlinux 255 zImage Image xipImage bootpImage uImage: vmlinux
256 $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@ 256 $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@
257 257
258 zinstall install: vmlinux 258 zinstall install: vmlinux
259 $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $@ 259 $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $@
260 260
261 CLEAN_FILES += include/asm-arm/mach-types.h \ 261 CLEAN_FILES += include/asm-arm/mach-types.h \
262 include/asm-arm/arch include/asm-arm/.arch 262 include/asm-arm/arch include/asm-arm/.arch
263 263
264 # We use MRPROPER_FILES and CLEAN_FILES now 264 # We use MRPROPER_FILES and CLEAN_FILES now
265 archclean: 265 archclean:
266 $(Q)$(MAKE) $(clean)=$(boot) 266 $(Q)$(MAKE) $(clean)=$(boot)
267 267
268 # My testing targets (bypasses dependencies) 268 # My testing targets (bypasses dependencies)
269 bp:; $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/bootpImage 269 bp:; $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/bootpImage
270 i zi:; $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $@ 270 i zi:; $(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $@
271 271
272 272
273 define archhelp 273 define archhelp
274 echo '* zImage - Compressed kernel image (arch/$(ARCH)/boot/zImage)' 274 echo '* zImage - Compressed kernel image (arch/$(ARCH)/boot/zImage)'
275 echo ' Image - Uncompressed kernel image (arch/$(ARCH)/boot/Image)' 275 echo ' Image - Uncompressed kernel image (arch/$(ARCH)/boot/Image)'
276 echo '* xipImage - XIP kernel image, if configured (arch/$(ARCH)/boot/xipImage)' 276 echo '* xipImage - XIP kernel image, if configured (arch/$(ARCH)/boot/xipImage)'
277 echo ' uImage - U-Boot wrapped zImage' 277 echo ' uImage - U-Boot wrapped zImage'
278 echo ' bootpImage - Combined zImage and initial RAM disk' 278 echo ' bootpImage - Combined zImage and initial RAM disk'
279 echo ' (supply initrd image via make variable INITRD=<path>)' 279 echo ' (supply initrd image via make variable INITRD=<path>)'
280 echo ' install - Install uncompressed kernel' 280 echo ' install - Install uncompressed kernel'
281 echo ' zinstall - Install compressed kernel' 281 echo ' zinstall - Install compressed kernel'
282 echo ' Install using (your) ~/bin/installkernel or' 282 echo ' Install using (your) ~/bin/installkernel or'
283 echo ' (distribution) /sbin/installkernel or' 283 echo ' (distribution) /sbin/installkernel or'
284 echo ' install to $$(INSTALL_PATH) and run lilo' 284 echo ' install to $$(INSTALL_PATH) and run lilo'
285 endef 285 endef
286 286
arch/frv/lib/cache.S
1 /* cache.S: cache managment routines 1 /* cache.S: cache management routines
2 * 2 *
3 * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. 3 * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com) 4 * Written by David Howells (dhowells@redhat.com)
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License 7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version. 9 * 2 of the License, or (at your option) any later version.
10 */ 10 */
11 11
12 #include <asm/spr-regs.h> 12 #include <asm/spr-regs.h>
13 #include <asm/cache.h> 13 #include <asm/cache.h>
14 14
15 .text 15 .text
16 .p2align 4 16 .p2align 4
17 17
18 ############################################################################### 18 ###############################################################################
19 # 19 #
20 # Write back a range of dcache 20 # Write back a range of dcache
21 # - void frv_dcache_writeback(unsigned long start [GR8], unsigned long size [GR9]) 21 # - void frv_dcache_writeback(unsigned long start [GR8], unsigned long size [GR9])
22 # 22 #
23 ############################################################################### 23 ###############################################################################
24 .globl frv_dcache_writeback 24 .globl frv_dcache_writeback
25 .type frv_dcache_writeback,@function 25 .type frv_dcache_writeback,@function
26 frv_dcache_writeback: 26 frv_dcache_writeback:
27 andi gr8,~(L1_CACHE_BYTES-1),gr8 27 andi gr8,~(L1_CACHE_BYTES-1),gr8
28 28
29 2: dcf @(gr8,gr0) 29 2: dcf @(gr8,gr0)
30 addi gr8,#L1_CACHE_BYTES,gr8 30 addi gr8,#L1_CACHE_BYTES,gr8
31 cmp gr9,gr8,icc0 31 cmp gr9,gr8,icc0
32 bhi icc0,#2,2b 32 bhi icc0,#2,2b
33 33
34 membar 34 membar
35 bralr 35 bralr
36 .size frv_dcache_writeback, .-frv_dcache_writeback 36 .size frv_dcache_writeback, .-frv_dcache_writeback
37 37
38 ############################################################################## 38 ##############################################################################
39 # 39 #
40 # Invalidate a range of dcache and icache 40 # Invalidate a range of dcache and icache
41 # - void frv_cache_invalidate(unsigned long start [GR8], unsigned long end [GR9]); 41 # - void frv_cache_invalidate(unsigned long start [GR8], unsigned long end [GR9]);
42 # 42 #
43 ############################################################################### 43 ###############################################################################
44 .globl frv_cache_invalidate 44 .globl frv_cache_invalidate
45 .type frv_cache_invalidate,@function 45 .type frv_cache_invalidate,@function
46 frv_cache_invalidate: 46 frv_cache_invalidate:
47 andi gr8,~(L1_CACHE_BYTES-1),gr8 47 andi gr8,~(L1_CACHE_BYTES-1),gr8
48 48
49 2: dci @(gr8,gr0) 49 2: dci @(gr8,gr0)
50 ici @(gr8,gr0) 50 ici @(gr8,gr0)
51 addi gr8,#L1_CACHE_BYTES,gr8 51 addi gr8,#L1_CACHE_BYTES,gr8
52 cmp gr9,gr8,icc0 52 cmp gr9,gr8,icc0
53 bhi icc0,#2,2b 53 bhi icc0,#2,2b
54 54
55 membar 55 membar
56 bralr 56 bralr
57 .size frv_cache_invalidate, .-frv_cache_invalidate 57 .size frv_cache_invalidate, .-frv_cache_invalidate
58 58
59 ############################################################################## 59 ##############################################################################
60 # 60 #
61 # Invalidate a range of icache 61 # Invalidate a range of icache
62 # - void frv_icache_invalidate(unsigned long start [GR8], unsigned long end [GR9]); 62 # - void frv_icache_invalidate(unsigned long start [GR8], unsigned long end [GR9]);
63 # 63 #
64 ############################################################################### 64 ###############################################################################
65 .globl frv_icache_invalidate 65 .globl frv_icache_invalidate
66 .type frv_icache_invalidate,@function 66 .type frv_icache_invalidate,@function
67 frv_icache_invalidate: 67 frv_icache_invalidate:
68 andi gr8,~(L1_CACHE_BYTES-1),gr8 68 andi gr8,~(L1_CACHE_BYTES-1),gr8
69 69
70 2: ici @(gr8,gr0) 70 2: ici @(gr8,gr0)
71 addi gr8,#L1_CACHE_BYTES,gr8 71 addi gr8,#L1_CACHE_BYTES,gr8
72 cmp gr9,gr8,icc0 72 cmp gr9,gr8,icc0
73 bhi icc0,#2,2b 73 bhi icc0,#2,2b
74 74
75 membar 75 membar
76 bralr 76 bralr
77 .size frv_icache_invalidate, .-frv_icache_invalidate 77 .size frv_icache_invalidate, .-frv_icache_invalidate
78 78
79 ############################################################################### 79 ###############################################################################
80 # 80 #
81 # Write back and invalidate a range of dcache and icache 81 # Write back and invalidate a range of dcache and icache
82 # - void frv_cache_wback_inv(unsigned long start [GR8], unsigned long end [GR9]) 82 # - void frv_cache_wback_inv(unsigned long start [GR8], unsigned long end [GR9])
83 # 83 #
84 ############################################################################### 84 ###############################################################################
85 .globl frv_cache_wback_inv 85 .globl frv_cache_wback_inv
86 .type frv_cache_wback_inv,@function 86 .type frv_cache_wback_inv,@function
87 frv_cache_wback_inv: 87 frv_cache_wback_inv:
88 andi gr8,~(L1_CACHE_BYTES-1),gr8 88 andi gr8,~(L1_CACHE_BYTES-1),gr8
89 89
90 2: dcf @(gr8,gr0) 90 2: dcf @(gr8,gr0)
91 ici @(gr8,gr0) 91 ici @(gr8,gr0)
92 addi gr8,#L1_CACHE_BYTES,gr8 92 addi gr8,#L1_CACHE_BYTES,gr8
93 cmp gr9,gr8,icc0 93 cmp gr9,gr8,icc0
94 bhi icc0,#2,2b 94 bhi icc0,#2,2b
95 95
96 membar 96 membar
97 bralr 97 bralr
98 .size frv_cache_wback_inv, .-frv_cache_wback_inv 98 .size frv_cache_wback_inv, .-frv_cache_wback_inv
99 99
arch/mn10300/include/asm/cacheflush.h
1 /* MN10300 Cache flushing 1 /* MN10300 Cache flushing
2 * 2 *
3 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. 3 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com) 4 * Written by David Howells (dhowells@redhat.com)
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public Licence 7 * modify it under the terms of the GNU General Public Licence
8 * as published by the Free Software Foundation; either version 8 * as published by the Free Software Foundation; either version
9 * 2 of the Licence, or (at your option) any later version. 9 * 2 of the Licence, or (at your option) any later version.
10 */ 10 */
11 #ifndef _ASM_CACHEFLUSH_H 11 #ifndef _ASM_CACHEFLUSH_H
12 #define _ASM_CACHEFLUSH_H 12 #define _ASM_CACHEFLUSH_H
13 13
14 #ifndef __ASSEMBLY__ 14 #ifndef __ASSEMBLY__
15 15
16 /* Keep includes the same across arches. */ 16 /* Keep includes the same across arches. */
17 #include <linux/mm.h> 17 #include <linux/mm.h>
18 18
19 /* 19 /*
20 * virtually-indexed cache managment (our cache is physically indexed) 20 * virtually-indexed cache management (our cache is physically indexed)
21 */ 21 */
22 #define flush_cache_all() do {} while (0) 22 #define flush_cache_all() do {} while (0)
23 #define flush_cache_mm(mm) do {} while (0) 23 #define flush_cache_mm(mm) do {} while (0)
24 #define flush_cache_dup_mm(mm) do {} while (0) 24 #define flush_cache_dup_mm(mm) do {} while (0)
25 #define flush_cache_range(mm, start, end) do {} while (0) 25 #define flush_cache_range(mm, start, end) do {} while (0)
26 #define flush_cache_page(vma, vmaddr, pfn) do {} while (0) 26 #define flush_cache_page(vma, vmaddr, pfn) do {} while (0)
27 #define flush_cache_vmap(start, end) do {} while (0) 27 #define flush_cache_vmap(start, end) do {} while (0)
28 #define flush_cache_vunmap(start, end) do {} while (0) 28 #define flush_cache_vunmap(start, end) do {} while (0)
29 #define flush_dcache_page(page) do {} while (0) 29 #define flush_dcache_page(page) do {} while (0)
30 #define flush_dcache_mmap_lock(mapping) do {} while (0) 30 #define flush_dcache_mmap_lock(mapping) do {} while (0)
31 #define flush_dcache_mmap_unlock(mapping) do {} while (0) 31 #define flush_dcache_mmap_unlock(mapping) do {} while (0)
32 32
33 /* 33 /*
34 * physically-indexed cache managment 34 * physically-indexed cache management
35 */ 35 */
36 #ifndef CONFIG_MN10300_CACHE_DISABLED 36 #ifndef CONFIG_MN10300_CACHE_DISABLED
37 37
38 extern void flush_icache_range(unsigned long start, unsigned long end); 38 extern void flush_icache_range(unsigned long start, unsigned long end);
39 extern void flush_icache_page(struct vm_area_struct *vma, struct page *pg); 39 extern void flush_icache_page(struct vm_area_struct *vma, struct page *pg);
40 40
41 #else 41 #else
42 42
43 #define flush_icache_range(start, end) do {} while (0) 43 #define flush_icache_range(start, end) do {} while (0)
44 #define flush_icache_page(vma, pg) do {} while (0) 44 #define flush_icache_page(vma, pg) do {} while (0)
45 45
46 #endif 46 #endif
47 47
48 #define flush_icache_user_range(vma, pg, adr, len) \ 48 #define flush_icache_user_range(vma, pg, adr, len) \
49 flush_icache_range(adr, adr + len) 49 flush_icache_range(adr, adr + len)
50 50
51 #define copy_to_user_page(vma, page, vaddr, dst, src, len) \ 51 #define copy_to_user_page(vma, page, vaddr, dst, src, len) \
52 do { \ 52 do { \
53 memcpy(dst, src, len); \ 53 memcpy(dst, src, len); \
54 flush_icache_page(vma, page); \ 54 flush_icache_page(vma, page); \
55 } while (0) 55 } while (0)
56 56
57 #define copy_from_user_page(vma, page, vaddr, dst, src, len) \ 57 #define copy_from_user_page(vma, page, vaddr, dst, src, len) \
58 memcpy(dst, src, len) 58 memcpy(dst, src, len)
59 59
60 /* 60 /*
61 * primitive routines 61 * primitive routines
62 */ 62 */
63 #ifndef CONFIG_MN10300_CACHE_DISABLED 63 #ifndef CONFIG_MN10300_CACHE_DISABLED
64 extern void mn10300_icache_inv(void); 64 extern void mn10300_icache_inv(void);
65 extern void mn10300_dcache_inv(void); 65 extern void mn10300_dcache_inv(void);
66 extern void mn10300_dcache_inv_page(unsigned start); 66 extern void mn10300_dcache_inv_page(unsigned start);
67 extern void mn10300_dcache_inv_range(unsigned start, unsigned end); 67 extern void mn10300_dcache_inv_range(unsigned start, unsigned end);
68 extern void mn10300_dcache_inv_range2(unsigned start, unsigned size); 68 extern void mn10300_dcache_inv_range2(unsigned start, unsigned size);
69 #ifdef CONFIG_MN10300_CACHE_WBACK 69 #ifdef CONFIG_MN10300_CACHE_WBACK
70 extern void mn10300_dcache_flush(void); 70 extern void mn10300_dcache_flush(void);
71 extern void mn10300_dcache_flush_page(unsigned start); 71 extern void mn10300_dcache_flush_page(unsigned start);
72 extern void mn10300_dcache_flush_range(unsigned start, unsigned end); 72 extern void mn10300_dcache_flush_range(unsigned start, unsigned end);
73 extern void mn10300_dcache_flush_range2(unsigned start, unsigned size); 73 extern void mn10300_dcache_flush_range2(unsigned start, unsigned size);
74 extern void mn10300_dcache_flush_inv(void); 74 extern void mn10300_dcache_flush_inv(void);
75 extern void mn10300_dcache_flush_inv_page(unsigned start); 75 extern void mn10300_dcache_flush_inv_page(unsigned start);
76 extern void mn10300_dcache_flush_inv_range(unsigned start, unsigned end); 76 extern void mn10300_dcache_flush_inv_range(unsigned start, unsigned end);
77 extern void mn10300_dcache_flush_inv_range2(unsigned start, unsigned size); 77 extern void mn10300_dcache_flush_inv_range2(unsigned start, unsigned size);
78 #else 78 #else
79 #define mn10300_dcache_flush() do {} while (0) 79 #define mn10300_dcache_flush() do {} while (0)
80 #define mn10300_dcache_flush_page(start) do {} while (0) 80 #define mn10300_dcache_flush_page(start) do {} while (0)
81 #define mn10300_dcache_flush_range(start, end) do {} while (0) 81 #define mn10300_dcache_flush_range(start, end) do {} while (0)
82 #define mn10300_dcache_flush_range2(start, size) do {} while (0) 82 #define mn10300_dcache_flush_range2(start, size) do {} while (0)
83 #define mn10300_dcache_flush_inv() mn10300_dcache_inv() 83 #define mn10300_dcache_flush_inv() mn10300_dcache_inv()
84 #define mn10300_dcache_flush_inv_page(start) \ 84 #define mn10300_dcache_flush_inv_page(start) \
85 mn10300_dcache_inv_page((start)) 85 mn10300_dcache_inv_page((start))
86 #define mn10300_dcache_flush_inv_range(start, end) \ 86 #define mn10300_dcache_flush_inv_range(start, end) \
87 mn10300_dcache_inv_range((start), (end)) 87 mn10300_dcache_inv_range((start), (end))
88 #define mn10300_dcache_flush_inv_range2(start, size) \ 88 #define mn10300_dcache_flush_inv_range2(start, size) \
89 mn10300_dcache_inv_range2((start), (size)) 89 mn10300_dcache_inv_range2((start), (size))
90 #endif /* CONFIG_MN10300_CACHE_WBACK */ 90 #endif /* CONFIG_MN10300_CACHE_WBACK */
91 #else 91 #else
92 #define mn10300_icache_inv() do {} while (0) 92 #define mn10300_icache_inv() do {} while (0)
93 #define mn10300_dcache_inv() do {} while (0) 93 #define mn10300_dcache_inv() do {} while (0)
94 #define mn10300_dcache_inv_page(start) do {} while (0) 94 #define mn10300_dcache_inv_page(start) do {} while (0)
95 #define mn10300_dcache_inv_range(start, end) do {} while (0) 95 #define mn10300_dcache_inv_range(start, end) do {} while (0)
96 #define mn10300_dcache_inv_range2(start, size) do {} while (0) 96 #define mn10300_dcache_inv_range2(start, size) do {} while (0)
97 #define mn10300_dcache_flush() do {} while (0) 97 #define mn10300_dcache_flush() do {} while (0)
98 #define mn10300_dcache_flush_inv_page(start) do {} while (0) 98 #define mn10300_dcache_flush_inv_page(start) do {} while (0)
99 #define mn10300_dcache_flush_inv() do {} while (0) 99 #define mn10300_dcache_flush_inv() do {} while (0)
100 #define mn10300_dcache_flush_inv_range(start, end) do {} while (0) 100 #define mn10300_dcache_flush_inv_range(start, end) do {} while (0)
101 #define mn10300_dcache_flush_inv_range2(start, size) do {} while (0) 101 #define mn10300_dcache_flush_inv_range2(start, size) do {} while (0)
102 #define mn10300_dcache_flush_page(start) do {} while (0) 102 #define mn10300_dcache_flush_page(start) do {} while (0)
103 #define mn10300_dcache_flush_range(start, end) do {} while (0) 103 #define mn10300_dcache_flush_range(start, end) do {} while (0)
104 #define mn10300_dcache_flush_range2(start, size) do {} while (0) 104 #define mn10300_dcache_flush_range2(start, size) do {} while (0)
105 #endif /* CONFIG_MN10300_CACHE_DISABLED */ 105 #endif /* CONFIG_MN10300_CACHE_DISABLED */
106 106
107 /* 107 /*
108 * internal debugging function 108 * internal debugging function
109 */ 109 */
110 #ifdef CONFIG_DEBUG_PAGEALLOC 110 #ifdef CONFIG_DEBUG_PAGEALLOC
111 extern void kernel_map_pages(struct page *page, int numpages, int enable); 111 extern void kernel_map_pages(struct page *page, int numpages, int enable);
112 #endif 112 #endif
113 113
114 #endif /* __ASSEMBLY__ */ 114 #endif /* __ASSEMBLY__ */
115 115
116 #endif /* _ASM_CACHEFLUSH_H */ 116 #endif /* _ASM_CACHEFLUSH_H */
117 117
drivers/media/dvb/siano/smscoreapi.c
1 /* 1 /*
2 * Siano core API module 2 * Siano core API module
3 * 3 *
4 * This file contains implementation for the interface to sms core component 4 * This file contains implementation for the interface to sms core component
5 * 5 *
6 * author: Uri Shkolnik 6 * author: Uri Shkolnik
7 * 7 *
8 * Copyright (c), 2005-2008 Siano Mobile Silicon, Inc. 8 * Copyright (c), 2005-2008 Siano Mobile Silicon, Inc.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as 11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation; 12 * published by the Free Software Foundation;
13 * 13 *
14 * Software distributed under the License is distributed on an "AS IS" 14 * Software distributed under the License is distributed on an "AS IS"
15 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. 15 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
16 * 16 *
17 * See the GNU General Public License for more details. 17 * See the GNU General Public License for more details.
18 * 18 *
19 * You should have received a copy of the GNU General Public License 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 20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */ 22 */
23 23
24 #include <linux/kernel.h> 24 #include <linux/kernel.h>
25 #include <linux/init.h> 25 #include <linux/init.h>
26 #include <linux/module.h> 26 #include <linux/module.h>
27 #include <linux/moduleparam.h> 27 #include <linux/moduleparam.h>
28 #include <linux/dma-mapping.h> 28 #include <linux/dma-mapping.h>
29 #include <linux/delay.h> 29 #include <linux/delay.h>
30 #include <linux/io.h> 30 #include <linux/io.h>
31 31
32 #include <linux/firmware.h> 32 #include <linux/firmware.h>
33 #include <linux/wait.h> 33 #include <linux/wait.h>
34 #include <asm/byteorder.h> 34 #include <asm/byteorder.h>
35 35
36 #include "smscoreapi.h" 36 #include "smscoreapi.h"
37 #include "sms-cards.h" 37 #include "sms-cards.h"
38 #include "smsir.h" 38 #include "smsir.h"
39 #include "smsendian.h" 39 #include "smsendian.h"
40 40
41 static int sms_dbg; 41 static int sms_dbg;
42 module_param_named(debug, sms_dbg, int, 0644); 42 module_param_named(debug, sms_dbg, int, 0644);
43 MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))"); 43 MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))");
44 44
45 struct smscore_device_notifyee_t { 45 struct smscore_device_notifyee_t {
46 struct list_head entry; 46 struct list_head entry;
47 hotplug_t hotplug; 47 hotplug_t hotplug;
48 }; 48 };
49 49
50 struct smscore_idlist_t { 50 struct smscore_idlist_t {
51 struct list_head entry; 51 struct list_head entry;
52 int id; 52 int id;
53 int data_type; 53 int data_type;
54 }; 54 };
55 55
56 struct smscore_client_t { 56 struct smscore_client_t {
57 struct list_head entry; 57 struct list_head entry;
58 struct smscore_device_t *coredev; 58 struct smscore_device_t *coredev;
59 void *context; 59 void *context;
60 struct list_head idlist; 60 struct list_head idlist;
61 onresponse_t onresponse_handler; 61 onresponse_t onresponse_handler;
62 onremove_t onremove_handler; 62 onremove_t onremove_handler;
63 }; 63 };
64 64
65 void smscore_set_board_id(struct smscore_device_t *core, int id) 65 void smscore_set_board_id(struct smscore_device_t *core, int id)
66 { 66 {
67 core->board_id = id; 67 core->board_id = id;
68 } 68 }
69 69
70 int smscore_led_state(struct smscore_device_t *core, int led) 70 int smscore_led_state(struct smscore_device_t *core, int led)
71 { 71 {
72 if (led >= 0) 72 if (led >= 0)
73 core->led_state = led; 73 core->led_state = led;
74 return core->led_state; 74 return core->led_state;
75 } 75 }
76 EXPORT_SYMBOL_GPL(smscore_set_board_id); 76 EXPORT_SYMBOL_GPL(smscore_set_board_id);
77 77
78 int smscore_get_board_id(struct smscore_device_t *core) 78 int smscore_get_board_id(struct smscore_device_t *core)
79 { 79 {
80 return core->board_id; 80 return core->board_id;
81 } 81 }
82 EXPORT_SYMBOL_GPL(smscore_get_board_id); 82 EXPORT_SYMBOL_GPL(smscore_get_board_id);
83 83
84 struct smscore_registry_entry_t { 84 struct smscore_registry_entry_t {
85 struct list_head entry; 85 struct list_head entry;
86 char devpath[32]; 86 char devpath[32];
87 int mode; 87 int mode;
88 enum sms_device_type_st type; 88 enum sms_device_type_st type;
89 }; 89 };
90 90
91 static struct list_head g_smscore_notifyees; 91 static struct list_head g_smscore_notifyees;
92 static struct list_head g_smscore_devices; 92 static struct list_head g_smscore_devices;
93 static struct mutex g_smscore_deviceslock; 93 static struct mutex g_smscore_deviceslock;
94 94
95 static struct list_head g_smscore_registry; 95 static struct list_head g_smscore_registry;
96 static struct mutex g_smscore_registrylock; 96 static struct mutex g_smscore_registrylock;
97 97
98 static int default_mode = 4; 98 static int default_mode = 4;
99 99
100 module_param(default_mode, int, 0644); 100 module_param(default_mode, int, 0644);
101 MODULE_PARM_DESC(default_mode, "default firmware id (device mode)"); 101 MODULE_PARM_DESC(default_mode, "default firmware id (device mode)");
102 102
103 static struct smscore_registry_entry_t *smscore_find_registry(char *devpath) 103 static struct smscore_registry_entry_t *smscore_find_registry(char *devpath)
104 { 104 {
105 struct smscore_registry_entry_t *entry; 105 struct smscore_registry_entry_t *entry;
106 struct list_head *next; 106 struct list_head *next;
107 107
108 kmutex_lock(&g_smscore_registrylock); 108 kmutex_lock(&g_smscore_registrylock);
109 for (next = g_smscore_registry.next; 109 for (next = g_smscore_registry.next;
110 next != &g_smscore_registry; 110 next != &g_smscore_registry;
111 next = next->next) { 111 next = next->next) {
112 entry = (struct smscore_registry_entry_t *) next; 112 entry = (struct smscore_registry_entry_t *) next;
113 if (!strcmp(entry->devpath, devpath)) { 113 if (!strcmp(entry->devpath, devpath)) {
114 kmutex_unlock(&g_smscore_registrylock); 114 kmutex_unlock(&g_smscore_registrylock);
115 return entry; 115 return entry;
116 } 116 }
117 } 117 }
118 entry = (struct smscore_registry_entry_t *) 118 entry = (struct smscore_registry_entry_t *)
119 kmalloc(sizeof(struct smscore_registry_entry_t), 119 kmalloc(sizeof(struct smscore_registry_entry_t),
120 GFP_KERNEL); 120 GFP_KERNEL);
121 if (entry) { 121 if (entry) {
122 entry->mode = default_mode; 122 entry->mode = default_mode;
123 strcpy(entry->devpath, devpath); 123 strcpy(entry->devpath, devpath);
124 list_add(&entry->entry, &g_smscore_registry); 124 list_add(&entry->entry, &g_smscore_registry);
125 } else 125 } else
126 sms_err("failed to create smscore_registry."); 126 sms_err("failed to create smscore_registry.");
127 kmutex_unlock(&g_smscore_registrylock); 127 kmutex_unlock(&g_smscore_registrylock);
128 return entry; 128 return entry;
129 } 129 }
130 130
131 int smscore_registry_getmode(char *devpath) 131 int smscore_registry_getmode(char *devpath)
132 { 132 {
133 struct smscore_registry_entry_t *entry; 133 struct smscore_registry_entry_t *entry;
134 134
135 entry = smscore_find_registry(devpath); 135 entry = smscore_find_registry(devpath);
136 if (entry) 136 if (entry)
137 return entry->mode; 137 return entry->mode;
138 else 138 else
139 sms_err("No registry found."); 139 sms_err("No registry found.");
140 140
141 return default_mode; 141 return default_mode;
142 } 142 }
143 EXPORT_SYMBOL_GPL(smscore_registry_getmode); 143 EXPORT_SYMBOL_GPL(smscore_registry_getmode);
144 144
145 static enum sms_device_type_st smscore_registry_gettype(char *devpath) 145 static enum sms_device_type_st smscore_registry_gettype(char *devpath)
146 { 146 {
147 struct smscore_registry_entry_t *entry; 147 struct smscore_registry_entry_t *entry;
148 148
149 entry = smscore_find_registry(devpath); 149 entry = smscore_find_registry(devpath);
150 if (entry) 150 if (entry)
151 return entry->type; 151 return entry->type;
152 else 152 else
153 sms_err("No registry found."); 153 sms_err("No registry found.");
154 154
155 return -1; 155 return -1;
156 } 156 }
157 157
158 void smscore_registry_setmode(char *devpath, int mode) 158 void smscore_registry_setmode(char *devpath, int mode)
159 { 159 {
160 struct smscore_registry_entry_t *entry; 160 struct smscore_registry_entry_t *entry;
161 161
162 entry = smscore_find_registry(devpath); 162 entry = smscore_find_registry(devpath);
163 if (entry) 163 if (entry)
164 entry->mode = mode; 164 entry->mode = mode;
165 else 165 else
166 sms_err("No registry found."); 166 sms_err("No registry found.");
167 } 167 }
168 168
169 static void smscore_registry_settype(char *devpath, 169 static void smscore_registry_settype(char *devpath,
170 enum sms_device_type_st type) 170 enum sms_device_type_st type)
171 { 171 {
172 struct smscore_registry_entry_t *entry; 172 struct smscore_registry_entry_t *entry;
173 173
174 entry = smscore_find_registry(devpath); 174 entry = smscore_find_registry(devpath);
175 if (entry) 175 if (entry)
176 entry->type = type; 176 entry->type = type;
177 else 177 else
178 sms_err("No registry found."); 178 sms_err("No registry found.");
179 } 179 }
180 180
181 181
182 static void list_add_locked(struct list_head *new, struct list_head *head, 182 static void list_add_locked(struct list_head *new, struct list_head *head,
183 spinlock_t *lock) 183 spinlock_t *lock)
184 { 184 {
185 unsigned long flags; 185 unsigned long flags;
186 186
187 spin_lock_irqsave(lock, flags); 187 spin_lock_irqsave(lock, flags);
188 188
189 list_add(new, head); 189 list_add(new, head);
190 190
191 spin_unlock_irqrestore(lock, flags); 191 spin_unlock_irqrestore(lock, flags);
192 } 192 }
193 193
194 /** 194 /**
195 * register a client callback that called when device plugged in/unplugged 195 * register a client callback that called when device plugged in/unplugged
196 * NOTE: if devices exist callback is called immediately for each device 196 * NOTE: if devices exist callback is called immediately for each device
197 * 197 *
198 * @param hotplug callback 198 * @param hotplug callback
199 * 199 *
200 * @return 0 on success, <0 on error. 200 * @return 0 on success, <0 on error.
201 */ 201 */
202 int smscore_register_hotplug(hotplug_t hotplug) 202 int smscore_register_hotplug(hotplug_t hotplug)
203 { 203 {
204 struct smscore_device_notifyee_t *notifyee; 204 struct smscore_device_notifyee_t *notifyee;
205 struct list_head *next, *first; 205 struct list_head *next, *first;
206 int rc = 0; 206 int rc = 0;
207 207
208 kmutex_lock(&g_smscore_deviceslock); 208 kmutex_lock(&g_smscore_deviceslock);
209 209
210 notifyee = kmalloc(sizeof(struct smscore_device_notifyee_t), 210 notifyee = kmalloc(sizeof(struct smscore_device_notifyee_t),
211 GFP_KERNEL); 211 GFP_KERNEL);
212 if (notifyee) { 212 if (notifyee) {
213 /* now notify callback about existing devices */ 213 /* now notify callback about existing devices */
214 first = &g_smscore_devices; 214 first = &g_smscore_devices;
215 for (next = first->next; 215 for (next = first->next;
216 next != first && !rc; 216 next != first && !rc;
217 next = next->next) { 217 next = next->next) {
218 struct smscore_device_t *coredev = 218 struct smscore_device_t *coredev =
219 (struct smscore_device_t *) next; 219 (struct smscore_device_t *) next;
220 rc = hotplug(coredev, coredev->device, 1); 220 rc = hotplug(coredev, coredev->device, 1);
221 } 221 }
222 222
223 if (rc >= 0) { 223 if (rc >= 0) {
224 notifyee->hotplug = hotplug; 224 notifyee->hotplug = hotplug;
225 list_add(&notifyee->entry, &g_smscore_notifyees); 225 list_add(&notifyee->entry, &g_smscore_notifyees);
226 } else 226 } else
227 kfree(notifyee); 227 kfree(notifyee);
228 } else 228 } else
229 rc = -ENOMEM; 229 rc = -ENOMEM;
230 230
231 kmutex_unlock(&g_smscore_deviceslock); 231 kmutex_unlock(&g_smscore_deviceslock);
232 232
233 return rc; 233 return rc;
234 } 234 }
235 EXPORT_SYMBOL_GPL(smscore_register_hotplug); 235 EXPORT_SYMBOL_GPL(smscore_register_hotplug);
236 236
237 /** 237 /**
238 * unregister a client callback that called when device plugged in/unplugged 238 * unregister a client callback that called when device plugged in/unplugged
239 * 239 *
240 * @param hotplug callback 240 * @param hotplug callback
241 * 241 *
242 */ 242 */
243 void smscore_unregister_hotplug(hotplug_t hotplug) 243 void smscore_unregister_hotplug(hotplug_t hotplug)
244 { 244 {
245 struct list_head *next, *first; 245 struct list_head *next, *first;
246 246
247 kmutex_lock(&g_smscore_deviceslock); 247 kmutex_lock(&g_smscore_deviceslock);
248 248
249 first = &g_smscore_notifyees; 249 first = &g_smscore_notifyees;
250 250
251 for (next = first->next; next != first;) { 251 for (next = first->next; next != first;) {
252 struct smscore_device_notifyee_t *notifyee = 252 struct smscore_device_notifyee_t *notifyee =
253 (struct smscore_device_notifyee_t *) next; 253 (struct smscore_device_notifyee_t *) next;
254 next = next->next; 254 next = next->next;
255 255
256 if (notifyee->hotplug == hotplug) { 256 if (notifyee->hotplug == hotplug) {
257 list_del(&notifyee->entry); 257 list_del(&notifyee->entry);
258 kfree(notifyee); 258 kfree(notifyee);
259 } 259 }
260 } 260 }
261 261
262 kmutex_unlock(&g_smscore_deviceslock); 262 kmutex_unlock(&g_smscore_deviceslock);
263 } 263 }
264 EXPORT_SYMBOL_GPL(smscore_unregister_hotplug); 264 EXPORT_SYMBOL_GPL(smscore_unregister_hotplug);
265 265
266 static void smscore_notify_clients(struct smscore_device_t *coredev) 266 static void smscore_notify_clients(struct smscore_device_t *coredev)
267 { 267 {
268 struct smscore_client_t *client; 268 struct smscore_client_t *client;
269 269
270 /* the client must call smscore_unregister_client from remove handler */ 270 /* the client must call smscore_unregister_client from remove handler */
271 while (!list_empty(&coredev->clients)) { 271 while (!list_empty(&coredev->clients)) {
272 client = (struct smscore_client_t *) coredev->clients.next; 272 client = (struct smscore_client_t *) coredev->clients.next;
273 client->onremove_handler(client->context); 273 client->onremove_handler(client->context);
274 } 274 }
275 } 275 }
276 276
277 static int smscore_notify_callbacks(struct smscore_device_t *coredev, 277 static int smscore_notify_callbacks(struct smscore_device_t *coredev,
278 struct device *device, int arrival) 278 struct device *device, int arrival)
279 { 279 {
280 struct list_head *next, *first; 280 struct list_head *next, *first;
281 int rc = 0; 281 int rc = 0;
282 282
283 /* note: must be called under g_deviceslock */ 283 /* note: must be called under g_deviceslock */
284 284
285 first = &g_smscore_notifyees; 285 first = &g_smscore_notifyees;
286 286
287 for (next = first->next; next != first; next = next->next) { 287 for (next = first->next; next != first; next = next->next) {
288 rc = ((struct smscore_device_notifyee_t *) next)-> 288 rc = ((struct smscore_device_notifyee_t *) next)->
289 hotplug(coredev, device, arrival); 289 hotplug(coredev, device, arrival);
290 if (rc < 0) 290 if (rc < 0)
291 break; 291 break;
292 } 292 }
293 293
294 return rc; 294 return rc;
295 } 295 }
296 296
297 static struct 297 static struct
298 smscore_buffer_t *smscore_createbuffer(u8 *buffer, void *common_buffer, 298 smscore_buffer_t *smscore_createbuffer(u8 *buffer, void *common_buffer,
299 dma_addr_t common_buffer_phys) 299 dma_addr_t common_buffer_phys)
300 { 300 {
301 struct smscore_buffer_t *cb = 301 struct smscore_buffer_t *cb =
302 kmalloc(sizeof(struct smscore_buffer_t), GFP_KERNEL); 302 kmalloc(sizeof(struct smscore_buffer_t), GFP_KERNEL);
303 if (!cb) { 303 if (!cb) {
304 sms_info("kmalloc(...) failed"); 304 sms_info("kmalloc(...) failed");
305 return NULL; 305 return NULL;
306 } 306 }
307 307
308 cb->p = buffer; 308 cb->p = buffer;
309 cb->offset_in_common = buffer - (u8 *) common_buffer; 309 cb->offset_in_common = buffer - (u8 *) common_buffer;
310 cb->phys = common_buffer_phys + cb->offset_in_common; 310 cb->phys = common_buffer_phys + cb->offset_in_common;
311 311
312 return cb; 312 return cb;
313 } 313 }
314 314
315 /** 315 /**
316 * creates coredev object for a device, prepares buffers, 316 * creates coredev object for a device, prepares buffers,
317 * creates buffer mappings, notifies registered hotplugs about new device. 317 * creates buffer mappings, notifies registered hotplugs about new device.
318 * 318 *
319 * @param params device pointer to struct with device specific parameters 319 * @param params device pointer to struct with device specific parameters
320 * and handlers 320 * and handlers
321 * @param coredev pointer to a value that receives created coredev object 321 * @param coredev pointer to a value that receives created coredev object
322 * 322 *
323 * @return 0 on success, <0 on error. 323 * @return 0 on success, <0 on error.
324 */ 324 */
325 int smscore_register_device(struct smsdevice_params_t *params, 325 int smscore_register_device(struct smsdevice_params_t *params,
326 struct smscore_device_t **coredev) 326 struct smscore_device_t **coredev)
327 { 327 {
328 struct smscore_device_t *dev; 328 struct smscore_device_t *dev;
329 u8 *buffer; 329 u8 *buffer;
330 330
331 dev = kzalloc(sizeof(struct smscore_device_t), GFP_KERNEL); 331 dev = kzalloc(sizeof(struct smscore_device_t), GFP_KERNEL);
332 if (!dev) { 332 if (!dev) {
333 sms_info("kzalloc(...) failed"); 333 sms_info("kzalloc(...) failed");
334 return -ENOMEM; 334 return -ENOMEM;
335 } 335 }
336 336
337 /* init list entry so it could be safe in smscore_unregister_device */ 337 /* init list entry so it could be safe in smscore_unregister_device */
338 INIT_LIST_HEAD(&dev->entry); 338 INIT_LIST_HEAD(&dev->entry);
339 339
340 /* init queues */ 340 /* init queues */
341 INIT_LIST_HEAD(&dev->clients); 341 INIT_LIST_HEAD(&dev->clients);
342 INIT_LIST_HEAD(&dev->buffers); 342 INIT_LIST_HEAD(&dev->buffers);
343 343
344 /* init locks */ 344 /* init locks */
345 spin_lock_init(&dev->clientslock); 345 spin_lock_init(&dev->clientslock);
346 spin_lock_init(&dev->bufferslock); 346 spin_lock_init(&dev->bufferslock);
347 347
348 /* init completion events */ 348 /* init completion events */
349 init_completion(&dev->version_ex_done); 349 init_completion(&dev->version_ex_done);
350 init_completion(&dev->data_download_done); 350 init_completion(&dev->data_download_done);
351 init_completion(&dev->trigger_done); 351 init_completion(&dev->trigger_done);
352 init_completion(&dev->init_device_done); 352 init_completion(&dev->init_device_done);
353 init_completion(&dev->reload_start_done); 353 init_completion(&dev->reload_start_done);
354 init_completion(&dev->resume_done); 354 init_completion(&dev->resume_done);
355 init_completion(&dev->gpio_configuration_done); 355 init_completion(&dev->gpio_configuration_done);
356 init_completion(&dev->gpio_set_level_done); 356 init_completion(&dev->gpio_set_level_done);
357 init_completion(&dev->gpio_get_level_done); 357 init_completion(&dev->gpio_get_level_done);
358 init_completion(&dev->ir_init_done); 358 init_completion(&dev->ir_init_done);
359 359
360 /* Buffer management */ 360 /* Buffer management */
361 init_waitqueue_head(&dev->buffer_mng_waitq); 361 init_waitqueue_head(&dev->buffer_mng_waitq);
362 362
363 /* alloc common buffer */ 363 /* alloc common buffer */
364 dev->common_buffer_size = params->buffer_size * params->num_buffers; 364 dev->common_buffer_size = params->buffer_size * params->num_buffers;
365 dev->common_buffer = dma_alloc_coherent(NULL, dev->common_buffer_size, 365 dev->common_buffer = dma_alloc_coherent(NULL, dev->common_buffer_size,
366 &dev->common_buffer_phys, 366 &dev->common_buffer_phys,
367 GFP_KERNEL | GFP_DMA); 367 GFP_KERNEL | GFP_DMA);
368 if (!dev->common_buffer) { 368 if (!dev->common_buffer) {
369 smscore_unregister_device(dev); 369 smscore_unregister_device(dev);
370 return -ENOMEM; 370 return -ENOMEM;
371 } 371 }
372 372
373 /* prepare dma buffers */ 373 /* prepare dma buffers */
374 for (buffer = dev->common_buffer; 374 for (buffer = dev->common_buffer;
375 dev->num_buffers < params->num_buffers; 375 dev->num_buffers < params->num_buffers;
376 dev->num_buffers++, buffer += params->buffer_size) { 376 dev->num_buffers++, buffer += params->buffer_size) {
377 struct smscore_buffer_t *cb = 377 struct smscore_buffer_t *cb =
378 smscore_createbuffer(buffer, dev->common_buffer, 378 smscore_createbuffer(buffer, dev->common_buffer,
379 dev->common_buffer_phys); 379 dev->common_buffer_phys);
380 if (!cb) { 380 if (!cb) {
381 smscore_unregister_device(dev); 381 smscore_unregister_device(dev);
382 return -ENOMEM; 382 return -ENOMEM;
383 } 383 }
384 384
385 smscore_putbuffer(dev, cb); 385 smscore_putbuffer(dev, cb);
386 } 386 }
387 387
388 sms_info("allocated %d buffers", dev->num_buffers); 388 sms_info("allocated %d buffers", dev->num_buffers);
389 389
390 dev->mode = DEVICE_MODE_NONE; 390 dev->mode = DEVICE_MODE_NONE;
391 dev->context = params->context; 391 dev->context = params->context;
392 dev->device = params->device; 392 dev->device = params->device;
393 dev->setmode_handler = params->setmode_handler; 393 dev->setmode_handler = params->setmode_handler;
394 dev->detectmode_handler = params->detectmode_handler; 394 dev->detectmode_handler = params->detectmode_handler;
395 dev->sendrequest_handler = params->sendrequest_handler; 395 dev->sendrequest_handler = params->sendrequest_handler;
396 dev->preload_handler = params->preload_handler; 396 dev->preload_handler = params->preload_handler;
397 dev->postload_handler = params->postload_handler; 397 dev->postload_handler = params->postload_handler;
398 398
399 dev->device_flags = params->flags; 399 dev->device_flags = params->flags;
400 strcpy(dev->devpath, params->devpath); 400 strcpy(dev->devpath, params->devpath);
401 401
402 smscore_registry_settype(dev->devpath, params->device_type); 402 smscore_registry_settype(dev->devpath, params->device_type);
403 403
404 /* add device to devices list */ 404 /* add device to devices list */
405 kmutex_lock(&g_smscore_deviceslock); 405 kmutex_lock(&g_smscore_deviceslock);
406 list_add(&dev->entry, &g_smscore_devices); 406 list_add(&dev->entry, &g_smscore_devices);
407 kmutex_unlock(&g_smscore_deviceslock); 407 kmutex_unlock(&g_smscore_deviceslock);
408 408
409 *coredev = dev; 409 *coredev = dev;
410 410
411 sms_info("device %p created", dev); 411 sms_info("device %p created", dev);
412 412
413 return 0; 413 return 0;
414 } 414 }
415 EXPORT_SYMBOL_GPL(smscore_register_device); 415 EXPORT_SYMBOL_GPL(smscore_register_device);
416 416
417 417
418 static int smscore_sendrequest_and_wait(struct smscore_device_t *coredev, 418 static int smscore_sendrequest_and_wait(struct smscore_device_t *coredev,
419 void *buffer, size_t size, struct completion *completion) { 419 void *buffer, size_t size, struct completion *completion) {
420 int rc = coredev->sendrequest_handler(coredev->context, buffer, size); 420 int rc = coredev->sendrequest_handler(coredev->context, buffer, size);
421 if (rc < 0) { 421 if (rc < 0) {
422 sms_info("sendrequest returned error %d", rc); 422 sms_info("sendrequest returned error %d", rc);
423 return rc; 423 return rc;
424 } 424 }
425 425
426 return wait_for_completion_timeout(completion, 426 return wait_for_completion_timeout(completion,
427 msecs_to_jiffies(SMS_PROTOCOL_MAX_RAOUNDTRIP_MS)) ? 427 msecs_to_jiffies(SMS_PROTOCOL_MAX_RAOUNDTRIP_MS)) ?
428 0 : -ETIME; 428 0 : -ETIME;
429 } 429 }
430 430
431 /** 431 /**
432 * Starts & enables IR operations 432 * Starts & enables IR operations
433 * 433 *
434 * @return 0 on success, < 0 on error. 434 * @return 0 on success, < 0 on error.
435 */ 435 */
436 static int smscore_init_ir(struct smscore_device_t *coredev) 436 static int smscore_init_ir(struct smscore_device_t *coredev)
437 { 437 {
438 int ir_io; 438 int ir_io;
439 int rc; 439 int rc;
440 void *buffer; 440 void *buffer;
441 441
442 coredev->ir.input_dev = NULL; 442 coredev->ir.input_dev = NULL;
443 ir_io = sms_get_board(smscore_get_board_id(coredev))->board_cfg.ir; 443 ir_io = sms_get_board(smscore_get_board_id(coredev))->board_cfg.ir;
444 if (ir_io) {/* only if IR port exist we use IR sub-module */ 444 if (ir_io) {/* only if IR port exist we use IR sub-module */
445 sms_info("IR loading"); 445 sms_info("IR loading");
446 rc = sms_ir_init(coredev); 446 rc = sms_ir_init(coredev);
447 447
448 if (rc != 0) 448 if (rc != 0)
449 sms_err("Error initialization DTV IR sub-module"); 449 sms_err("Error initialization DTV IR sub-module");
450 else { 450 else {
451 buffer = kmalloc(sizeof(struct SmsMsgData_ST2) + 451 buffer = kmalloc(sizeof(struct SmsMsgData_ST2) +
452 SMS_DMA_ALIGNMENT, 452 SMS_DMA_ALIGNMENT,
453 GFP_KERNEL | GFP_DMA); 453 GFP_KERNEL | GFP_DMA);
454 if (buffer) { 454 if (buffer) {
455 struct SmsMsgData_ST2 *msg = 455 struct SmsMsgData_ST2 *msg =
456 (struct SmsMsgData_ST2 *) 456 (struct SmsMsgData_ST2 *)
457 SMS_ALIGN_ADDRESS(buffer); 457 SMS_ALIGN_ADDRESS(buffer);
458 458
459 SMS_INIT_MSG(&msg->xMsgHeader, 459 SMS_INIT_MSG(&msg->xMsgHeader,
460 MSG_SMS_START_IR_REQ, 460 MSG_SMS_START_IR_REQ,
461 sizeof(struct SmsMsgData_ST2)); 461 sizeof(struct SmsMsgData_ST2));
462 msg->msgData[0] = coredev->ir.controller; 462 msg->msgData[0] = coredev->ir.controller;
463 msg->msgData[1] = coredev->ir.timeout; 463 msg->msgData[1] = coredev->ir.timeout;
464 464
465 smsendian_handle_tx_message( 465 smsendian_handle_tx_message(
466 (struct SmsMsgHdr_ST2 *)msg); 466 (struct SmsMsgHdr_ST2 *)msg);
467 rc = smscore_sendrequest_and_wait(coredev, msg, 467 rc = smscore_sendrequest_and_wait(coredev, msg,
468 msg->xMsgHeader. msgLength, 468 msg->xMsgHeader. msgLength,
469 &coredev->ir_init_done); 469 &coredev->ir_init_done);
470 470
471 kfree(buffer); 471 kfree(buffer);
472 } else 472 } else
473 sms_err 473 sms_err
474 ("Sending IR initialization message failed"); 474 ("Sending IR initialization message failed");
475 } 475 }
476 } else 476 } else
477 sms_info("IR port has not been detected"); 477 sms_info("IR port has not been detected");
478 478
479 return 0; 479 return 0;
480 } 480 }
481 481
482 /** 482 /**
483 * sets initial device mode and notifies client hotplugs that device is ready 483 * sets initial device mode and notifies client hotplugs that device is ready
484 * 484 *
485 * @param coredev pointer to a coredev object returned by 485 * @param coredev pointer to a coredev object returned by
486 * smscore_register_device 486 * smscore_register_device
487 * 487 *
488 * @return 0 on success, <0 on error. 488 * @return 0 on success, <0 on error.
489 */ 489 */
490 int smscore_start_device(struct smscore_device_t *coredev) 490 int smscore_start_device(struct smscore_device_t *coredev)
491 { 491 {
492 int rc = smscore_set_device_mode( 492 int rc = smscore_set_device_mode(
493 coredev, smscore_registry_getmode(coredev->devpath)); 493 coredev, smscore_registry_getmode(coredev->devpath));
494 if (rc < 0) { 494 if (rc < 0) {
495 sms_info("set device mode faile , rc %d", rc); 495 sms_info("set device mode faile , rc %d", rc);
496 return rc; 496 return rc;
497 } 497 }
498 498
499 kmutex_lock(&g_smscore_deviceslock); 499 kmutex_lock(&g_smscore_deviceslock);
500 500
501 rc = smscore_notify_callbacks(coredev, coredev->device, 1); 501 rc = smscore_notify_callbacks(coredev, coredev->device, 1);
502 smscore_init_ir(coredev); 502 smscore_init_ir(coredev);
503 503
504 sms_info("device %p started, rc %d", coredev, rc); 504 sms_info("device %p started, rc %d", coredev, rc);
505 505
506 kmutex_unlock(&g_smscore_deviceslock); 506 kmutex_unlock(&g_smscore_deviceslock);
507 507
508 return rc; 508 return rc;
509 } 509 }
510 EXPORT_SYMBOL_GPL(smscore_start_device); 510 EXPORT_SYMBOL_GPL(smscore_start_device);
511 511
512 512
513 static int smscore_load_firmware_family2(struct smscore_device_t *coredev, 513 static int smscore_load_firmware_family2(struct smscore_device_t *coredev,
514 void *buffer, size_t size) 514 void *buffer, size_t size)
515 { 515 {
516 struct SmsFirmware_ST *firmware = (struct SmsFirmware_ST *) buffer; 516 struct SmsFirmware_ST *firmware = (struct SmsFirmware_ST *) buffer;
517 struct SmsMsgHdr_ST *msg; 517 struct SmsMsgHdr_ST *msg;
518 u32 mem_address; 518 u32 mem_address;
519 u8 *payload = firmware->Payload; 519 u8 *payload = firmware->Payload;
520 int rc = 0; 520 int rc = 0;
521 firmware->StartAddress = le32_to_cpu(firmware->StartAddress); 521 firmware->StartAddress = le32_to_cpu(firmware->StartAddress);
522 firmware->Length = le32_to_cpu(firmware->Length); 522 firmware->Length = le32_to_cpu(firmware->Length);
523 523
524 mem_address = firmware->StartAddress; 524 mem_address = firmware->StartAddress;
525 525
526 sms_info("loading FW to addr 0x%x size %d", 526 sms_info("loading FW to addr 0x%x size %d",
527 mem_address, firmware->Length); 527 mem_address, firmware->Length);
528 if (coredev->preload_handler) { 528 if (coredev->preload_handler) {
529 rc = coredev->preload_handler(coredev->context); 529 rc = coredev->preload_handler(coredev->context);
530 if (rc < 0) 530 if (rc < 0)
531 return rc; 531 return rc;
532 } 532 }
533 533
534 /* PAGE_SIZE buffer shall be enough and dma aligned */ 534 /* PAGE_SIZE buffer shall be enough and dma aligned */
535 msg = kmalloc(PAGE_SIZE, GFP_KERNEL | GFP_DMA); 535 msg = kmalloc(PAGE_SIZE, GFP_KERNEL | GFP_DMA);
536 if (!msg) 536 if (!msg)
537 return -ENOMEM; 537 return -ENOMEM;
538 538
539 if (coredev->mode != DEVICE_MODE_NONE) { 539 if (coredev->mode != DEVICE_MODE_NONE) {
540 sms_debug("sending reload command."); 540 sms_debug("sending reload command.");
541 SMS_INIT_MSG(msg, MSG_SW_RELOAD_START_REQ, 541 SMS_INIT_MSG(msg, MSG_SW_RELOAD_START_REQ,
542 sizeof(struct SmsMsgHdr_ST)); 542 sizeof(struct SmsMsgHdr_ST));
543 rc = smscore_sendrequest_and_wait(coredev, msg, 543 rc = smscore_sendrequest_and_wait(coredev, msg,
544 msg->msgLength, 544 msg->msgLength,
545 &coredev->reload_start_done); 545 &coredev->reload_start_done);
546 mem_address = *(u32 *) &payload[20]; 546 mem_address = *(u32 *) &payload[20];
547 } 547 }
548 548
549 while (size && rc >= 0) { 549 while (size && rc >= 0) {
550 struct SmsDataDownload_ST *DataMsg = 550 struct SmsDataDownload_ST *DataMsg =
551 (struct SmsDataDownload_ST *) msg; 551 (struct SmsDataDownload_ST *) msg;
552 int payload_size = min((int) size, SMS_MAX_PAYLOAD_SIZE); 552 int payload_size = min((int) size, SMS_MAX_PAYLOAD_SIZE);
553 553
554 SMS_INIT_MSG(msg, MSG_SMS_DATA_DOWNLOAD_REQ, 554 SMS_INIT_MSG(msg, MSG_SMS_DATA_DOWNLOAD_REQ,
555 (u16)(sizeof(struct SmsMsgHdr_ST) + 555 (u16)(sizeof(struct SmsMsgHdr_ST) +
556 sizeof(u32) + payload_size)); 556 sizeof(u32) + payload_size));
557 557
558 DataMsg->MemAddr = mem_address; 558 DataMsg->MemAddr = mem_address;
559 memcpy(DataMsg->Payload, payload, payload_size); 559 memcpy(DataMsg->Payload, payload, payload_size);
560 560
561 if ((coredev->device_flags & SMS_ROM_NO_RESPONSE) && 561 if ((coredev->device_flags & SMS_ROM_NO_RESPONSE) &&
562 (coredev->mode == DEVICE_MODE_NONE)) 562 (coredev->mode == DEVICE_MODE_NONE))
563 rc = coredev->sendrequest_handler( 563 rc = coredev->sendrequest_handler(
564 coredev->context, DataMsg, 564 coredev->context, DataMsg,
565 DataMsg->xMsgHeader.msgLength); 565 DataMsg->xMsgHeader.msgLength);
566 else 566 else
567 rc = smscore_sendrequest_and_wait( 567 rc = smscore_sendrequest_and_wait(
568 coredev, DataMsg, 568 coredev, DataMsg,
569 DataMsg->xMsgHeader.msgLength, 569 DataMsg->xMsgHeader.msgLength,
570 &coredev->data_download_done); 570 &coredev->data_download_done);
571 571
572 payload += payload_size; 572 payload += payload_size;
573 size -= payload_size; 573 size -= payload_size;
574 mem_address += payload_size; 574 mem_address += payload_size;
575 } 575 }
576 576
577 if (rc >= 0) { 577 if (rc >= 0) {
578 if (coredev->mode == DEVICE_MODE_NONE) { 578 if (coredev->mode == DEVICE_MODE_NONE) {
579 struct SmsMsgData_ST *TriggerMsg = 579 struct SmsMsgData_ST *TriggerMsg =
580 (struct SmsMsgData_ST *) msg; 580 (struct SmsMsgData_ST *) msg;
581 581
582 SMS_INIT_MSG(msg, MSG_SMS_SWDOWNLOAD_TRIGGER_REQ, 582 SMS_INIT_MSG(msg, MSG_SMS_SWDOWNLOAD_TRIGGER_REQ,
583 sizeof(struct SmsMsgHdr_ST) + 583 sizeof(struct SmsMsgHdr_ST) +
584 sizeof(u32) * 5); 584 sizeof(u32) * 5);
585 585
586 TriggerMsg->msgData[0] = firmware->StartAddress; 586 TriggerMsg->msgData[0] = firmware->StartAddress;
587 /* Entry point */ 587 /* Entry point */
588 TriggerMsg->msgData[1] = 5; /* Priority */ 588 TriggerMsg->msgData[1] = 5; /* Priority */
589 TriggerMsg->msgData[2] = 0x200; /* Stack size */ 589 TriggerMsg->msgData[2] = 0x200; /* Stack size */
590 TriggerMsg->msgData[3] = 0; /* Parameter */ 590 TriggerMsg->msgData[3] = 0; /* Parameter */
591 TriggerMsg->msgData[4] = 4; /* Task ID */ 591 TriggerMsg->msgData[4] = 4; /* Task ID */
592 592
593 if (coredev->device_flags & SMS_ROM_NO_RESPONSE) { 593 if (coredev->device_flags & SMS_ROM_NO_RESPONSE) {
594 rc = coredev->sendrequest_handler( 594 rc = coredev->sendrequest_handler(
595 coredev->context, TriggerMsg, 595 coredev->context, TriggerMsg,
596 TriggerMsg->xMsgHeader.msgLength); 596 TriggerMsg->xMsgHeader.msgLength);
597 msleep(100); 597 msleep(100);
598 } else 598 } else
599 rc = smscore_sendrequest_and_wait( 599 rc = smscore_sendrequest_and_wait(
600 coredev, TriggerMsg, 600 coredev, TriggerMsg,
601 TriggerMsg->xMsgHeader.msgLength, 601 TriggerMsg->xMsgHeader.msgLength,
602 &coredev->trigger_done); 602 &coredev->trigger_done);
603 } else { 603 } else {
604 SMS_INIT_MSG(msg, MSG_SW_RELOAD_EXEC_REQ, 604 SMS_INIT_MSG(msg, MSG_SW_RELOAD_EXEC_REQ,
605 sizeof(struct SmsMsgHdr_ST)); 605 sizeof(struct SmsMsgHdr_ST));
606 606
607 rc = coredev->sendrequest_handler(coredev->context, 607 rc = coredev->sendrequest_handler(coredev->context,
608 msg, msg->msgLength); 608 msg, msg->msgLength);
609 } 609 }
610 msleep(500); 610 msleep(500);
611 } 611 }
612 612
613 sms_debug("rc=%d, postload=%p ", rc, 613 sms_debug("rc=%d, postload=%p ", rc,
614 coredev->postload_handler); 614 coredev->postload_handler);
615 615
616 kfree(msg); 616 kfree(msg);
617 617
618 return ((rc >= 0) && coredev->postload_handler) ? 618 return ((rc >= 0) && coredev->postload_handler) ?
619 coredev->postload_handler(coredev->context) : 619 coredev->postload_handler(coredev->context) :
620 rc; 620 rc;
621 } 621 }
622 622
623 /** 623 /**
624 * loads specified firmware into a buffer and calls device loadfirmware_handler 624 * loads specified firmware into a buffer and calls device loadfirmware_handler
625 * 625 *
626 * @param coredev pointer to a coredev object returned by 626 * @param coredev pointer to a coredev object returned by
627 * smscore_register_device 627 * smscore_register_device
628 * @param filename null-terminated string specifies firmware file name 628 * @param filename null-terminated string specifies firmware file name
629 * @param loadfirmware_handler device handler that loads firmware 629 * @param loadfirmware_handler device handler that loads firmware
630 * 630 *
631 * @return 0 on success, <0 on error. 631 * @return 0 on success, <0 on error.
632 */ 632 */
633 static int smscore_load_firmware_from_file(struct smscore_device_t *coredev, 633 static int smscore_load_firmware_from_file(struct smscore_device_t *coredev,
634 char *filename, 634 char *filename,
635 loadfirmware_t loadfirmware_handler) 635 loadfirmware_t loadfirmware_handler)
636 { 636 {
637 int rc = -ENOENT; 637 int rc = -ENOENT;
638 const struct firmware *fw; 638 const struct firmware *fw;
639 u8 *fw_buffer; 639 u8 *fw_buffer;
640 640
641 if (loadfirmware_handler == NULL && !(coredev->device_flags & 641 if (loadfirmware_handler == NULL && !(coredev->device_flags &
642 SMS_DEVICE_FAMILY2)) 642 SMS_DEVICE_FAMILY2))
643 return -EINVAL; 643 return -EINVAL;
644 644
645 rc = request_firmware(&fw, filename, coredev->device); 645 rc = request_firmware(&fw, filename, coredev->device);
646 if (rc < 0) { 646 if (rc < 0) {
647 sms_info("failed to open \"%s\"", filename); 647 sms_info("failed to open \"%s\"", filename);
648 return rc; 648 return rc;
649 } 649 }
650 sms_info("read FW %s, size=%zd", filename, fw->size); 650 sms_info("read FW %s, size=%zd", filename, fw->size);
651 fw_buffer = kmalloc(ALIGN(fw->size, SMS_ALLOC_ALIGNMENT), 651 fw_buffer = kmalloc(ALIGN(fw->size, SMS_ALLOC_ALIGNMENT),
652 GFP_KERNEL | GFP_DMA); 652 GFP_KERNEL | GFP_DMA);
653 if (fw_buffer) { 653 if (fw_buffer) {
654 memcpy(fw_buffer, fw->data, fw->size); 654 memcpy(fw_buffer, fw->data, fw->size);
655 655
656 rc = (coredev->device_flags & SMS_DEVICE_FAMILY2) ? 656 rc = (coredev->device_flags & SMS_DEVICE_FAMILY2) ?
657 smscore_load_firmware_family2(coredev, 657 smscore_load_firmware_family2(coredev,
658 fw_buffer, 658 fw_buffer,
659 fw->size) : 659 fw->size) :
660 loadfirmware_handler(coredev->context, 660 loadfirmware_handler(coredev->context,
661 fw_buffer, fw->size); 661 fw_buffer, fw->size);
662 662
663 kfree(fw_buffer); 663 kfree(fw_buffer);
664 } else { 664 } else {
665 sms_info("failed to allocate firmware buffer"); 665 sms_info("failed to allocate firmware buffer");
666 rc = -ENOMEM; 666 rc = -ENOMEM;
667 } 667 }
668 668
669 release_firmware(fw); 669 release_firmware(fw);
670 670
671 return rc; 671 return rc;
672 } 672 }
673 673
674 /** 674 /**
675 * notifies all clients registered with the device, notifies hotplugs, 675 * notifies all clients registered with the device, notifies hotplugs,
676 * frees all buffers and coredev object 676 * frees all buffers and coredev object
677 * 677 *
678 * @param coredev pointer to a coredev object returned by 678 * @param coredev pointer to a coredev object returned by
679 * smscore_register_device 679 * smscore_register_device
680 * 680 *
681 * @return 0 on success, <0 on error. 681 * @return 0 on success, <0 on error.
682 */ 682 */
683 void smscore_unregister_device(struct smscore_device_t *coredev) 683 void smscore_unregister_device(struct smscore_device_t *coredev)
684 { 684 {
685 struct smscore_buffer_t *cb; 685 struct smscore_buffer_t *cb;
686 int num_buffers = 0; 686 int num_buffers = 0;
687 int retry = 0; 687 int retry = 0;
688 688
689 kmutex_lock(&g_smscore_deviceslock); 689 kmutex_lock(&g_smscore_deviceslock);
690 690
691 /* Release input device (IR) resources */ 691 /* Release input device (IR) resources */
692 sms_ir_exit(coredev); 692 sms_ir_exit(coredev);
693 693
694 smscore_notify_clients(coredev); 694 smscore_notify_clients(coredev);
695 smscore_notify_callbacks(coredev, NULL, 0); 695 smscore_notify_callbacks(coredev, NULL, 0);
696 696
697 /* at this point all buffers should be back 697 /* at this point all buffers should be back
698 * onresponse must no longer be called */ 698 * onresponse must no longer be called */
699 699
700 while (1) { 700 while (1) {
701 while (!list_empty(&coredev->buffers)) { 701 while (!list_empty(&coredev->buffers)) {
702 cb = (struct smscore_buffer_t *) coredev->buffers.next; 702 cb = (struct smscore_buffer_t *) coredev->buffers.next;
703 list_del(&cb->entry); 703 list_del(&cb->entry);
704 kfree(cb); 704 kfree(cb);
705 num_buffers++; 705 num_buffers++;
706 } 706 }
707 if (num_buffers == coredev->num_buffers) 707 if (num_buffers == coredev->num_buffers)
708 break; 708 break;
709 if (++retry > 10) { 709 if (++retry > 10) {
710 sms_info("exiting although " 710 sms_info("exiting although "
711 "not all buffers released."); 711 "not all buffers released.");
712 break; 712 break;
713 } 713 }
714 714
715 sms_info("waiting for %d buffer(s)", 715 sms_info("waiting for %d buffer(s)",
716 coredev->num_buffers - num_buffers); 716 coredev->num_buffers - num_buffers);
717 msleep(100); 717 msleep(100);
718 } 718 }
719 719
720 sms_info("freed %d buffers", num_buffers); 720 sms_info("freed %d buffers", num_buffers);
721 721
722 if (coredev->common_buffer) 722 if (coredev->common_buffer)
723 dma_free_coherent(NULL, coredev->common_buffer_size, 723 dma_free_coherent(NULL, coredev->common_buffer_size,
724 coredev->common_buffer, coredev->common_buffer_phys); 724 coredev->common_buffer, coredev->common_buffer_phys);
725 725
726 if (coredev->fw_buf != NULL) 726 if (coredev->fw_buf != NULL)
727 kfree(coredev->fw_buf); 727 kfree(coredev->fw_buf);
728 728
729 list_del(&coredev->entry); 729 list_del(&coredev->entry);
730 kfree(coredev); 730 kfree(coredev);
731 731
732 kmutex_unlock(&g_smscore_deviceslock); 732 kmutex_unlock(&g_smscore_deviceslock);
733 733
734 sms_info("device %p destroyed", coredev); 734 sms_info("device %p destroyed", coredev);
735 } 735 }
736 EXPORT_SYMBOL_GPL(smscore_unregister_device); 736 EXPORT_SYMBOL_GPL(smscore_unregister_device);
737 737
738 static int smscore_detect_mode(struct smscore_device_t *coredev) 738 static int smscore_detect_mode(struct smscore_device_t *coredev)
739 { 739 {
740 void *buffer = kmalloc(sizeof(struct SmsMsgHdr_ST) + SMS_DMA_ALIGNMENT, 740 void *buffer = kmalloc(sizeof(struct SmsMsgHdr_ST) + SMS_DMA_ALIGNMENT,
741 GFP_KERNEL | GFP_DMA); 741 GFP_KERNEL | GFP_DMA);
742 struct SmsMsgHdr_ST *msg = 742 struct SmsMsgHdr_ST *msg =
743 (struct SmsMsgHdr_ST *) SMS_ALIGN_ADDRESS(buffer); 743 (struct SmsMsgHdr_ST *) SMS_ALIGN_ADDRESS(buffer);
744 int rc; 744 int rc;
745 745
746 if (!buffer) 746 if (!buffer)
747 return -ENOMEM; 747 return -ENOMEM;
748 748
749 SMS_INIT_MSG(msg, MSG_SMS_GET_VERSION_EX_REQ, 749 SMS_INIT_MSG(msg, MSG_SMS_GET_VERSION_EX_REQ,
750 sizeof(struct SmsMsgHdr_ST)); 750 sizeof(struct SmsMsgHdr_ST));
751 751
752 rc = smscore_sendrequest_and_wait(coredev, msg, msg->msgLength, 752 rc = smscore_sendrequest_and_wait(coredev, msg, msg->msgLength,
753 &coredev->version_ex_done); 753 &coredev->version_ex_done);
754 if (rc == -ETIME) { 754 if (rc == -ETIME) {
755 sms_err("MSG_SMS_GET_VERSION_EX_REQ failed first try"); 755 sms_err("MSG_SMS_GET_VERSION_EX_REQ failed first try");
756 756
757 if (wait_for_completion_timeout(&coredev->resume_done, 757 if (wait_for_completion_timeout(&coredev->resume_done,
758 msecs_to_jiffies(5000))) { 758 msecs_to_jiffies(5000))) {
759 rc = smscore_sendrequest_and_wait( 759 rc = smscore_sendrequest_and_wait(
760 coredev, msg, msg->msgLength, 760 coredev, msg, msg->msgLength,
761 &coredev->version_ex_done); 761 &coredev->version_ex_done);
762 if (rc < 0) 762 if (rc < 0)
763 sms_err("MSG_SMS_GET_VERSION_EX_REQ failed " 763 sms_err("MSG_SMS_GET_VERSION_EX_REQ failed "
764 "second try, rc %d", rc); 764 "second try, rc %d", rc);
765 } else 765 } else
766 rc = -ETIME; 766 rc = -ETIME;
767 } 767 }
768 768
769 kfree(buffer); 769 kfree(buffer);
770 770
771 return rc; 771 return rc;
772 } 772 }
773 773
774 static char *smscore_fw_lkup[][SMS_NUM_OF_DEVICE_TYPES] = { 774 static char *smscore_fw_lkup[][SMS_NUM_OF_DEVICE_TYPES] = {
775 /*Stellar NOVA A0 Nova B0 VEGA*/ 775 /*Stellar NOVA A0 Nova B0 VEGA*/
776 /*DVBT*/ 776 /*DVBT*/
777 {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"}, 777 {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"},
778 /*DVBH*/ 778 /*DVBH*/
779 {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"}, 779 {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"},
780 /*TDMB*/ 780 /*TDMB*/
781 {"none", "tdmb_nova_12mhz.inp", "tdmb_nova_12mhz_b0.inp", "none"}, 781 {"none", "tdmb_nova_12mhz.inp", "tdmb_nova_12mhz_b0.inp", "none"},
782 /*DABIP*/ 782 /*DABIP*/
783 {"none", "none", "none", "none"}, 783 {"none", "none", "none", "none"},
784 /*BDA*/ 784 /*BDA*/
785 {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"}, 785 {"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"},
786 /*ISDBT*/ 786 /*ISDBT*/
787 {"none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none"}, 787 {"none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none"},
788 /*ISDBTBDA*/ 788 /*ISDBTBDA*/
789 {"none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none"}, 789 {"none", "isdbt_nova_12mhz.inp", "isdbt_nova_12mhz_b0.inp", "none"},
790 /*CMMB*/ 790 /*CMMB*/
791 {"none", "none", "none", "cmmb_vega_12mhz.inp"} 791 {"none", "none", "none", "cmmb_vega_12mhz.inp"}
792 }; 792 };
793 793
794 static inline char *sms_get_fw_name(struct smscore_device_t *coredev, 794 static inline char *sms_get_fw_name(struct smscore_device_t *coredev,
795 int mode, enum sms_device_type_st type) 795 int mode, enum sms_device_type_st type)
796 { 796 {
797 char **fw = sms_get_board(smscore_get_board_id(coredev))->fw; 797 char **fw = sms_get_board(smscore_get_board_id(coredev))->fw;
798 return (fw && fw[mode]) ? fw[mode] : smscore_fw_lkup[mode][type]; 798 return (fw && fw[mode]) ? fw[mode] : smscore_fw_lkup[mode][type];
799 } 799 }
800 800
801 /** 801 /**
802 * calls device handler to change mode of operation 802 * calls device handler to change mode of operation
803 * NOTE: stellar/usb may disconnect when changing mode 803 * NOTE: stellar/usb may disconnect when changing mode
804 * 804 *
805 * @param coredev pointer to a coredev object returned by 805 * @param coredev pointer to a coredev object returned by
806 * smscore_register_device 806 * smscore_register_device
807 * @param mode requested mode of operation 807 * @param mode requested mode of operation
808 * 808 *
809 * @return 0 on success, <0 on error. 809 * @return 0 on success, <0 on error.
810 */ 810 */
811 int smscore_set_device_mode(struct smscore_device_t *coredev, int mode) 811 int smscore_set_device_mode(struct smscore_device_t *coredev, int mode)
812 { 812 {
813 void *buffer; 813 void *buffer;
814 int rc = 0; 814 int rc = 0;
815 enum sms_device_type_st type; 815 enum sms_device_type_st type;
816 816
817 sms_debug("set device mode to %d", mode); 817 sms_debug("set device mode to %d", mode);
818 if (coredev->device_flags & SMS_DEVICE_FAMILY2) { 818 if (coredev->device_flags & SMS_DEVICE_FAMILY2) {
819 if (mode < DEVICE_MODE_DVBT || mode >= DEVICE_MODE_RAW_TUNER) { 819 if (mode < DEVICE_MODE_DVBT || mode >= DEVICE_MODE_RAW_TUNER) {
820 sms_err("invalid mode specified %d", mode); 820 sms_err("invalid mode specified %d", mode);
821 return -EINVAL; 821 return -EINVAL;
822 } 822 }
823 823
824 smscore_registry_setmode(coredev->devpath, mode); 824 smscore_registry_setmode(coredev->devpath, mode);
825 825
826 if (!(coredev->device_flags & SMS_DEVICE_NOT_READY)) { 826 if (!(coredev->device_flags & SMS_DEVICE_NOT_READY)) {
827 rc = smscore_detect_mode(coredev); 827 rc = smscore_detect_mode(coredev);
828 if (rc < 0) { 828 if (rc < 0) {
829 sms_err("mode detect failed %d", rc); 829 sms_err("mode detect failed %d", rc);
830 return rc; 830 return rc;
831 } 831 }
832 } 832 }
833 833
834 if (coredev->mode == mode) { 834 if (coredev->mode == mode) {
835 sms_info("device mode %d already set", mode); 835 sms_info("device mode %d already set", mode);
836 return 0; 836 return 0;
837 } 837 }
838 838
839 if (!(coredev->modes_supported & (1 << mode))) { 839 if (!(coredev->modes_supported & (1 << mode))) {
840 char *fw_filename; 840 char *fw_filename;
841 841
842 type = smscore_registry_gettype(coredev->devpath); 842 type = smscore_registry_gettype(coredev->devpath);
843 fw_filename = sms_get_fw_name(coredev, mode, type); 843 fw_filename = sms_get_fw_name(coredev, mode, type);
844 844
845 rc = smscore_load_firmware_from_file(coredev, 845 rc = smscore_load_firmware_from_file(coredev,
846 fw_filename, NULL); 846 fw_filename, NULL);
847 if (rc < 0) { 847 if (rc < 0) {
848 sms_warn("error %d loading firmware: %s, " 848 sms_warn("error %d loading firmware: %s, "
849 "trying again with default firmware", 849 "trying again with default firmware",
850 rc, fw_filename); 850 rc, fw_filename);
851 851
852 /* try again with the default firmware */ 852 /* try again with the default firmware */
853 fw_filename = smscore_fw_lkup[mode][type]; 853 fw_filename = smscore_fw_lkup[mode][type];
854 rc = smscore_load_firmware_from_file(coredev, 854 rc = smscore_load_firmware_from_file(coredev,
855 fw_filename, NULL); 855 fw_filename, NULL);
856 856
857 if (rc < 0) { 857 if (rc < 0) {
858 sms_warn("error %d loading " 858 sms_warn("error %d loading "
859 "firmware: %s", rc, 859 "firmware: %s", rc,
860 fw_filename); 860 fw_filename);
861 return rc; 861 return rc;
862 } 862 }
863 } 863 }
864 sms_log("firmware download success: %s", fw_filename); 864 sms_log("firmware download success: %s", fw_filename);
865 } else 865 } else
866 sms_info("mode %d supported by running " 866 sms_info("mode %d supported by running "
867 "firmware", mode); 867 "firmware", mode);
868 868
869 buffer = kmalloc(sizeof(struct SmsMsgData_ST) + 869 buffer = kmalloc(sizeof(struct SmsMsgData_ST) +
870 SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA); 870 SMS_DMA_ALIGNMENT, GFP_KERNEL | GFP_DMA);
871 if (buffer) { 871 if (buffer) {
872 struct SmsMsgData_ST *msg = 872 struct SmsMsgData_ST *msg =
873 (struct SmsMsgData_ST *) 873 (struct SmsMsgData_ST *)
874 SMS_ALIGN_ADDRESS(buffer); 874 SMS_ALIGN_ADDRESS(buffer);
875 875
876 SMS_INIT_MSG(&msg->xMsgHeader, MSG_SMS_INIT_DEVICE_REQ, 876 SMS_INIT_MSG(&msg->xMsgHeader, MSG_SMS_INIT_DEVICE_REQ,
877 sizeof(struct SmsMsgData_ST)); 877 sizeof(struct SmsMsgData_ST));
878 msg->msgData[0] = mode; 878 msg->msgData[0] = mode;
879 879
880 rc = smscore_sendrequest_and_wait( 880 rc = smscore_sendrequest_and_wait(
881 coredev, msg, msg->xMsgHeader.msgLength, 881 coredev, msg, msg->xMsgHeader.msgLength,
882 &coredev->init_device_done); 882 &coredev->init_device_done);
883 883
884 kfree(buffer); 884 kfree(buffer);
885 } else { 885 } else {
886 sms_err("Could not allocate buffer for " 886 sms_err("Could not allocate buffer for "
887 "init device message."); 887 "init device message.");
888 rc = -ENOMEM; 888 rc = -ENOMEM;
889 } 889 }
890 } else { 890 } else {
891 if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_DVBT_BDA) { 891 if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_DVBT_BDA) {
892 sms_err("invalid mode specified %d", mode); 892 sms_err("invalid mode specified %d", mode);
893 return -EINVAL; 893 return -EINVAL;
894 } 894 }
895 895
896 smscore_registry_setmode(coredev->devpath, mode); 896 smscore_registry_setmode(coredev->devpath, mode);
897 897
898 if (coredev->detectmode_handler) 898 if (coredev->detectmode_handler)
899 coredev->detectmode_handler(coredev->context, 899 coredev->detectmode_handler(coredev->context,
900 &coredev->mode); 900 &coredev->mode);
901 901
902 if (coredev->mode != mode && coredev->setmode_handler) 902 if (coredev->mode != mode && coredev->setmode_handler)
903 rc = coredev->setmode_handler(coredev->context, mode); 903 rc = coredev->setmode_handler(coredev->context, mode);
904 } 904 }
905 905
906 if (rc >= 0) { 906 if (rc >= 0) {
907 coredev->mode = mode; 907 coredev->mode = mode;
908 coredev->device_flags &= ~SMS_DEVICE_NOT_READY; 908 coredev->device_flags &= ~SMS_DEVICE_NOT_READY;
909 } 909 }
910 910
911 if (rc < 0) 911 if (rc < 0)
912 sms_err("return error code %d.", rc); 912 sms_err("return error code %d.", rc);
913 return rc; 913 return rc;
914 } 914 }
915 915
916 /** 916 /**
917 * calls device handler to get current mode of operation 917 * calls device handler to get current mode of operation
918 * 918 *
919 * @param coredev pointer to a coredev object returned by 919 * @param coredev pointer to a coredev object returned by
920 * smscore_register_device 920 * smscore_register_device
921 * 921 *
922 * @return current mode 922 * @return current mode
923 */ 923 */
924 int smscore_get_device_mode(struct smscore_device_t *coredev) 924 int smscore_get_device_mode(struct smscore_device_t *coredev)
925 { 925 {
926 return coredev->mode; 926 return coredev->mode;
927 } 927 }
928 EXPORT_SYMBOL_GPL(smscore_get_device_mode); 928 EXPORT_SYMBOL_GPL(smscore_get_device_mode);
929 929
930 /** 930 /**
931 * find client by response id & type within the clients list. 931 * find client by response id & type within the clients list.
932 * return client handle or NULL. 932 * return client handle or NULL.
933 * 933 *
934 * @param coredev pointer to a coredev object returned by 934 * @param coredev pointer to a coredev object returned by
935 * smscore_register_device 935 * smscore_register_device
936 * @param data_type client data type (SMS_DONT_CARE for all types) 936 * @param data_type client data type (SMS_DONT_CARE for all types)
937 * @param id client id (SMS_DONT_CARE for all id) 937 * @param id client id (SMS_DONT_CARE for all id)
938 * 938 *
939 */ 939 */
940 static struct 940 static struct
941 smscore_client_t *smscore_find_client(struct smscore_device_t *coredev, 941 smscore_client_t *smscore_find_client(struct smscore_device_t *coredev,
942 int data_type, int id) 942 int data_type, int id)
943 { 943 {
944 struct smscore_client_t *client = NULL; 944 struct smscore_client_t *client = NULL;
945 struct list_head *next, *first; 945 struct list_head *next, *first;
946 unsigned long flags; 946 unsigned long flags;
947 struct list_head *firstid, *nextid; 947 struct list_head *firstid, *nextid;
948 948
949 949
950 spin_lock_irqsave(&coredev->clientslock, flags); 950 spin_lock_irqsave(&coredev->clientslock, flags);
951 first = &coredev->clients; 951 first = &coredev->clients;
952 for (next = first->next; 952 for (next = first->next;
953 (next != first) && !client; 953 (next != first) && !client;
954 next = next->next) { 954 next = next->next) {
955 firstid = &((struct smscore_client_t *)next)->idlist; 955 firstid = &((struct smscore_client_t *)next)->idlist;
956 for (nextid = firstid->next; 956 for (nextid = firstid->next;
957 nextid != firstid; 957 nextid != firstid;
958 nextid = nextid->next) { 958 nextid = nextid->next) {
959 if ((((struct smscore_idlist_t *)nextid)->id == id) && 959 if ((((struct smscore_idlist_t *)nextid)->id == id) &&
960 (((struct smscore_idlist_t *)nextid)->data_type == data_type || 960 (((struct smscore_idlist_t *)nextid)->data_type == data_type ||
961 (((struct smscore_idlist_t *)nextid)->data_type == 0))) { 961 (((struct smscore_idlist_t *)nextid)->data_type == 0))) {
962 client = (struct smscore_client_t *) next; 962 client = (struct smscore_client_t *) next;
963 break; 963 break;
964 } 964 }
965 } 965 }
966 } 966 }
967 spin_unlock_irqrestore(&coredev->clientslock, flags); 967 spin_unlock_irqrestore(&coredev->clientslock, flags);
968 return client; 968 return client;
969 } 969 }
970 970
971 /** 971 /**
972 * find client by response id/type, call clients onresponse handler 972 * find client by response id/type, call clients onresponse handler
973 * return buffer to pool on error 973 * return buffer to pool on error
974 * 974 *
975 * @param coredev pointer to a coredev object returned by 975 * @param coredev pointer to a coredev object returned by
976 * smscore_register_device 976 * smscore_register_device
977 * @param cb pointer to response buffer descriptor 977 * @param cb pointer to response buffer descriptor
978 * 978 *
979 */ 979 */
980 void smscore_onresponse(struct smscore_device_t *coredev, 980 void smscore_onresponse(struct smscore_device_t *coredev,
981 struct smscore_buffer_t *cb) { 981 struct smscore_buffer_t *cb) {
982 struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) ((u8 *) cb->p 982 struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) ((u8 *) cb->p
983 + cb->offset); 983 + cb->offset);
984 struct smscore_client_t *client; 984 struct smscore_client_t *client;
985 int rc = -EBUSY; 985 int rc = -EBUSY;
986 static unsigned long last_sample_time; /* = 0; */ 986 static unsigned long last_sample_time; /* = 0; */
987 static int data_total; /* = 0; */ 987 static int data_total; /* = 0; */
988 unsigned long time_now = jiffies_to_msecs(jiffies); 988 unsigned long time_now = jiffies_to_msecs(jiffies);
989 989
990 if (!last_sample_time) 990 if (!last_sample_time)
991 last_sample_time = time_now; 991 last_sample_time = time_now;
992 992
993 if (time_now - last_sample_time > 10000) { 993 if (time_now - last_sample_time > 10000) {
994 sms_debug("\ndata rate %d bytes/secs", 994 sms_debug("\ndata rate %d bytes/secs",
995 (int)((data_total * 1000) / 995 (int)((data_total * 1000) /
996 (time_now - last_sample_time))); 996 (time_now - last_sample_time)));
997 997
998 last_sample_time = time_now; 998 last_sample_time = time_now;
999 data_total = 0; 999 data_total = 0;
1000 } 1000 }
1001 1001
1002 data_total += cb->size; 1002 data_total += cb->size;
1003 /* Do we need to re-route? */ 1003 /* Do we need to re-route? */
1004 if ((phdr->msgType == MSG_SMS_HO_PER_SLICES_IND) || 1004 if ((phdr->msgType == MSG_SMS_HO_PER_SLICES_IND) ||
1005 (phdr->msgType == MSG_SMS_TRANSMISSION_IND)) { 1005 (phdr->msgType == MSG_SMS_TRANSMISSION_IND)) {
1006 if (coredev->mode == DEVICE_MODE_DVBT_BDA) 1006 if (coredev->mode == DEVICE_MODE_DVBT_BDA)
1007 phdr->msgDstId = DVBT_BDA_CONTROL_MSG_ID; 1007 phdr->msgDstId = DVBT_BDA_CONTROL_MSG_ID;
1008 } 1008 }
1009 1009
1010 1010
1011 client = smscore_find_client(coredev, phdr->msgType, phdr->msgDstId); 1011 client = smscore_find_client(coredev, phdr->msgType, phdr->msgDstId);
1012 1012
1013 /* If no client registered for type & id, 1013 /* If no client registered for type & id,
1014 * check for control client where type is not registered */ 1014 * check for control client where type is not registered */
1015 if (client) 1015 if (client)
1016 rc = client->onresponse_handler(client->context, cb); 1016 rc = client->onresponse_handler(client->context, cb);
1017 1017
1018 if (rc < 0) { 1018 if (rc < 0) {
1019 switch (phdr->msgType) { 1019 switch (phdr->msgType) {
1020 case MSG_SMS_GET_VERSION_EX_RES: 1020 case MSG_SMS_GET_VERSION_EX_RES:
1021 { 1021 {
1022 struct SmsVersionRes_ST *ver = 1022 struct SmsVersionRes_ST *ver =
1023 (struct SmsVersionRes_ST *) phdr; 1023 (struct SmsVersionRes_ST *) phdr;
1024 sms_debug("MSG_SMS_GET_VERSION_EX_RES " 1024 sms_debug("MSG_SMS_GET_VERSION_EX_RES "
1025 "id %d prots 0x%x ver %d.%d", 1025 "id %d prots 0x%x ver %d.%d",
1026 ver->FirmwareId, ver->SupportedProtocols, 1026 ver->FirmwareId, ver->SupportedProtocols,
1027 ver->RomVersionMajor, ver->RomVersionMinor); 1027 ver->RomVersionMajor, ver->RomVersionMinor);
1028 1028
1029 coredev->mode = ver->FirmwareId == 255 ? 1029 coredev->mode = ver->FirmwareId == 255 ?
1030 DEVICE_MODE_NONE : ver->FirmwareId; 1030 DEVICE_MODE_NONE : ver->FirmwareId;
1031 coredev->modes_supported = ver->SupportedProtocols; 1031 coredev->modes_supported = ver->SupportedProtocols;
1032 1032
1033 complete(&coredev->version_ex_done); 1033 complete(&coredev->version_ex_done);
1034 break; 1034 break;
1035 } 1035 }
1036 case MSG_SMS_INIT_DEVICE_RES: 1036 case MSG_SMS_INIT_DEVICE_RES:
1037 sms_debug("MSG_SMS_INIT_DEVICE_RES"); 1037 sms_debug("MSG_SMS_INIT_DEVICE_RES");
1038 complete(&coredev->init_device_done); 1038 complete(&coredev->init_device_done);
1039 break; 1039 break;
1040 case MSG_SW_RELOAD_START_RES: 1040 case MSG_SW_RELOAD_START_RES:
1041 sms_debug("MSG_SW_RELOAD_START_RES"); 1041 sms_debug("MSG_SW_RELOAD_START_RES");
1042 complete(&coredev->reload_start_done); 1042 complete(&coredev->reload_start_done);
1043 break; 1043 break;
1044 case MSG_SMS_DATA_DOWNLOAD_RES: 1044 case MSG_SMS_DATA_DOWNLOAD_RES:
1045 complete(&coredev->data_download_done); 1045 complete(&coredev->data_download_done);
1046 break; 1046 break;
1047 case MSG_SW_RELOAD_EXEC_RES: 1047 case MSG_SW_RELOAD_EXEC_RES:
1048 sms_debug("MSG_SW_RELOAD_EXEC_RES"); 1048 sms_debug("MSG_SW_RELOAD_EXEC_RES");
1049 break; 1049 break;
1050 case MSG_SMS_SWDOWNLOAD_TRIGGER_RES: 1050 case MSG_SMS_SWDOWNLOAD_TRIGGER_RES:
1051 sms_debug("MSG_SMS_SWDOWNLOAD_TRIGGER_RES"); 1051 sms_debug("MSG_SMS_SWDOWNLOAD_TRIGGER_RES");
1052 complete(&coredev->trigger_done); 1052 complete(&coredev->trigger_done);
1053 break; 1053 break;
1054 case MSG_SMS_SLEEP_RESUME_COMP_IND: 1054 case MSG_SMS_SLEEP_RESUME_COMP_IND:
1055 complete(&coredev->resume_done); 1055 complete(&coredev->resume_done);
1056 break; 1056 break;
1057 case MSG_SMS_GPIO_CONFIG_EX_RES: 1057 case MSG_SMS_GPIO_CONFIG_EX_RES:
1058 sms_debug("MSG_SMS_GPIO_CONFIG_EX_RES"); 1058 sms_debug("MSG_SMS_GPIO_CONFIG_EX_RES");
1059 complete(&coredev->gpio_configuration_done); 1059 complete(&coredev->gpio_configuration_done);
1060 break; 1060 break;
1061 case MSG_SMS_GPIO_SET_LEVEL_RES: 1061 case MSG_SMS_GPIO_SET_LEVEL_RES:
1062 sms_debug("MSG_SMS_GPIO_SET_LEVEL_RES"); 1062 sms_debug("MSG_SMS_GPIO_SET_LEVEL_RES");
1063 complete(&coredev->gpio_set_level_done); 1063 complete(&coredev->gpio_set_level_done);
1064 break; 1064 break;
1065 case MSG_SMS_GPIO_GET_LEVEL_RES: 1065 case MSG_SMS_GPIO_GET_LEVEL_RES:
1066 { 1066 {
1067 u32 *msgdata = (u32 *) phdr; 1067 u32 *msgdata = (u32 *) phdr;
1068 coredev->gpio_get_res = msgdata[1]; 1068 coredev->gpio_get_res = msgdata[1];
1069 sms_debug("MSG_SMS_GPIO_GET_LEVEL_RES gpio level %d", 1069 sms_debug("MSG_SMS_GPIO_GET_LEVEL_RES gpio level %d",
1070 coredev->gpio_get_res); 1070 coredev->gpio_get_res);
1071 complete(&coredev->gpio_get_level_done); 1071 complete(&coredev->gpio_get_level_done);
1072 break; 1072 break;
1073 } 1073 }
1074 case MSG_SMS_START_IR_RES: 1074 case MSG_SMS_START_IR_RES:
1075 complete(&coredev->ir_init_done); 1075 complete(&coredev->ir_init_done);
1076 break; 1076 break;
1077 case MSG_SMS_IR_SAMPLES_IND: 1077 case MSG_SMS_IR_SAMPLES_IND:
1078 sms_ir_event(coredev, 1078 sms_ir_event(coredev,
1079 (const char *) 1079 (const char *)
1080 ((char *)phdr 1080 ((char *)phdr
1081 + sizeof(struct SmsMsgHdr_ST)), 1081 + sizeof(struct SmsMsgHdr_ST)),
1082 (int)phdr->msgLength 1082 (int)phdr->msgLength
1083 - sizeof(struct SmsMsgHdr_ST)); 1083 - sizeof(struct SmsMsgHdr_ST));
1084 break; 1084 break;
1085 1085
1086 default: 1086 default:
1087 break; 1087 break;
1088 } 1088 }
1089 smscore_putbuffer(coredev, cb); 1089 smscore_putbuffer(coredev, cb);
1090 } 1090 }
1091 } 1091 }
1092 EXPORT_SYMBOL_GPL(smscore_onresponse); 1092 EXPORT_SYMBOL_GPL(smscore_onresponse);
1093 1093
1094 /** 1094 /**
1095 * return pointer to next free buffer descriptor from core pool 1095 * return pointer to next free buffer descriptor from core pool
1096 * 1096 *
1097 * @param coredev pointer to a coredev object returned by 1097 * @param coredev pointer to a coredev object returned by
1098 * smscore_register_device 1098 * smscore_register_device
1099 * 1099 *
1100 * @return pointer to descriptor on success, NULL on error. 1100 * @return pointer to descriptor on success, NULL on error.
1101 */ 1101 */
1102 struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev) 1102 struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev)
1103 { 1103 {
1104 struct smscore_buffer_t *cb = NULL; 1104 struct smscore_buffer_t *cb = NULL;
1105 unsigned long flags; 1105 unsigned long flags;
1106 1106
1107 DEFINE_WAIT(wait); 1107 DEFINE_WAIT(wait);
1108 1108
1109 spin_lock_irqsave(&coredev->bufferslock, flags); 1109 spin_lock_irqsave(&coredev->bufferslock, flags);
1110 1110
1111 /* This function must return a valid buffer, since the buffer list is 1111 /* This function must return a valid buffer, since the buffer list is
1112 * finite, we check that there is an available buffer, if not, we wait 1112 * finite, we check that there is an available buffer, if not, we wait
1113 * until such buffer become available. 1113 * until such buffer become available.
1114 */ 1114 */
1115 1115
1116 prepare_to_wait(&coredev->buffer_mng_waitq, &wait, TASK_INTERRUPTIBLE); 1116 prepare_to_wait(&coredev->buffer_mng_waitq, &wait, TASK_INTERRUPTIBLE);
1117 1117
1118 if (list_empty(&coredev->buffers)) 1118 if (list_empty(&coredev->buffers))
1119 schedule(); 1119 schedule();
1120 1120
1121 finish_wait(&coredev->buffer_mng_waitq, &wait); 1121 finish_wait(&coredev->buffer_mng_waitq, &wait);
1122 1122
1123 cb = (struct smscore_buffer_t *) coredev->buffers.next; 1123 cb = (struct smscore_buffer_t *) coredev->buffers.next;
1124 list_del(&cb->entry); 1124 list_del(&cb->entry);
1125 1125
1126 spin_unlock_irqrestore(&coredev->bufferslock, flags); 1126 spin_unlock_irqrestore(&coredev->bufferslock, flags);
1127 1127
1128 return cb; 1128 return cb;
1129 } 1129 }
1130 EXPORT_SYMBOL_GPL(smscore_getbuffer); 1130 EXPORT_SYMBOL_GPL(smscore_getbuffer);
1131 1131
1132 /** 1132 /**
1133 * return buffer descriptor to a pool 1133 * return buffer descriptor to a pool
1134 * 1134 *
1135 * @param coredev pointer to a coredev object returned by 1135 * @param coredev pointer to a coredev object returned by
1136 * smscore_register_device 1136 * smscore_register_device
1137 * @param cb pointer buffer descriptor 1137 * @param cb pointer buffer descriptor
1138 * 1138 *
1139 */ 1139 */
1140 void smscore_putbuffer(struct smscore_device_t *coredev, 1140 void smscore_putbuffer(struct smscore_device_t *coredev,
1141 struct smscore_buffer_t *cb) { 1141 struct smscore_buffer_t *cb) {
1142 wake_up_interruptible(&coredev->buffer_mng_waitq); 1142 wake_up_interruptible(&coredev->buffer_mng_waitq);
1143 list_add_locked(&cb->entry, &coredev->buffers, &coredev->bufferslock); 1143 list_add_locked(&cb->entry, &coredev->buffers, &coredev->bufferslock);
1144 } 1144 }
1145 EXPORT_SYMBOL_GPL(smscore_putbuffer); 1145 EXPORT_SYMBOL_GPL(smscore_putbuffer);
1146 1146
1147 static int smscore_validate_client(struct smscore_device_t *coredev, 1147 static int smscore_validate_client(struct smscore_device_t *coredev,
1148 struct smscore_client_t *client, 1148 struct smscore_client_t *client,
1149 int data_type, int id) 1149 int data_type, int id)
1150 { 1150 {
1151 struct smscore_idlist_t *listentry; 1151 struct smscore_idlist_t *listentry;
1152 struct smscore_client_t *registered_client; 1152 struct smscore_client_t *registered_client;
1153 1153
1154 if (!client) { 1154 if (!client) {
1155 sms_err("bad parameter."); 1155 sms_err("bad parameter.");
1156 return -EFAULT; 1156 return -EFAULT;
1157 } 1157 }
1158 registered_client = smscore_find_client(coredev, data_type, id); 1158 registered_client = smscore_find_client(coredev, data_type, id);
1159 if (registered_client == client) 1159 if (registered_client == client)
1160 return 0; 1160 return 0;
1161 1161
1162 if (registered_client) { 1162 if (registered_client) {
1163 sms_err("The msg ID already registered to another client."); 1163 sms_err("The msg ID already registered to another client.");
1164 return -EEXIST; 1164 return -EEXIST;
1165 } 1165 }
1166 listentry = kzalloc(sizeof(struct smscore_idlist_t), GFP_KERNEL); 1166 listentry = kzalloc(sizeof(struct smscore_idlist_t), GFP_KERNEL);
1167 if (!listentry) { 1167 if (!listentry) {
1168 sms_err("Can't allocate memory for client id."); 1168 sms_err("Can't allocate memory for client id.");
1169 return -ENOMEM; 1169 return -ENOMEM;
1170 } 1170 }
1171 listentry->id = id; 1171 listentry->id = id;
1172 listentry->data_type = data_type; 1172 listentry->data_type = data_type;
1173 list_add_locked(&listentry->entry, &client->idlist, 1173 list_add_locked(&listentry->entry, &client->idlist,
1174 &coredev->clientslock); 1174 &coredev->clientslock);
1175 return 0; 1175 return 0;
1176 } 1176 }
1177 1177
1178 /** 1178 /**
1179 * creates smsclient object, check that id is taken by another client 1179 * creates smsclient object, check that id is taken by another client
1180 * 1180 *
1181 * @param coredev pointer to a coredev object from clients hotplug 1181 * @param coredev pointer to a coredev object from clients hotplug
1182 * @param initial_id all messages with this id would be sent to this client 1182 * @param initial_id all messages with this id would be sent to this client
1183 * @param data_type all messages of this type would be sent to this client 1183 * @param data_type all messages of this type would be sent to this client
1184 * @param onresponse_handler client handler that is called to 1184 * @param onresponse_handler client handler that is called to
1185 * process incoming messages 1185 * process incoming messages
1186 * @param onremove_handler client handler that is called when device is removed 1186 * @param onremove_handler client handler that is called when device is removed
1187 * @param context client-specific context 1187 * @param context client-specific context
1188 * @param client pointer to a value that receives created smsclient object 1188 * @param client pointer to a value that receives created smsclient object
1189 * 1189 *
1190 * @return 0 on success, <0 on error. 1190 * @return 0 on success, <0 on error.
1191 */ 1191 */
1192 int smscore_register_client(struct smscore_device_t *coredev, 1192 int smscore_register_client(struct smscore_device_t *coredev,
1193 struct smsclient_params_t *params, 1193 struct smsclient_params_t *params,
1194 struct smscore_client_t **client) 1194 struct smscore_client_t **client)
1195 { 1195 {
1196 struct smscore_client_t *newclient; 1196 struct smscore_client_t *newclient;
1197 /* check that no other channel with same parameters exists */ 1197 /* check that no other channel with same parameters exists */
1198 if (smscore_find_client(coredev, params->data_type, 1198 if (smscore_find_client(coredev, params->data_type,
1199 params->initial_id)) { 1199 params->initial_id)) {
1200 sms_err("Client already exist."); 1200 sms_err("Client already exist.");
1201 return -EEXIST; 1201 return -EEXIST;
1202 } 1202 }
1203 1203
1204 newclient = kzalloc(sizeof(struct smscore_client_t), GFP_KERNEL); 1204 newclient = kzalloc(sizeof(struct smscore_client_t), GFP_KERNEL);
1205 if (!newclient) { 1205 if (!newclient) {
1206 sms_err("Failed to allocate memory for client."); 1206 sms_err("Failed to allocate memory for client.");
1207 return -ENOMEM; 1207 return -ENOMEM;
1208 } 1208 }
1209 1209
1210 INIT_LIST_HEAD(&newclient->idlist); 1210 INIT_LIST_HEAD(&newclient->idlist);
1211 newclient->coredev = coredev; 1211 newclient->coredev = coredev;
1212 newclient->onresponse_handler = params->onresponse_handler; 1212 newclient->onresponse_handler = params->onresponse_handler;
1213 newclient->onremove_handler = params->onremove_handler; 1213 newclient->onremove_handler = params->onremove_handler;
1214 newclient->context = params->context; 1214 newclient->context = params->context;
1215 list_add_locked(&newclient->entry, &coredev->clients, 1215 list_add_locked(&newclient->entry, &coredev->clients,
1216 &coredev->clientslock); 1216 &coredev->clientslock);
1217 smscore_validate_client(coredev, newclient, params->data_type, 1217 smscore_validate_client(coredev, newclient, params->data_type,
1218 params->initial_id); 1218 params->initial_id);
1219 *client = newclient; 1219 *client = newclient;
1220 sms_debug("%p %d %d", params->context, params->data_type, 1220 sms_debug("%p %d %d", params->context, params->data_type,
1221 params->initial_id); 1221 params->initial_id);
1222 1222
1223 return 0; 1223 return 0;
1224 } 1224 }
1225 EXPORT_SYMBOL_GPL(smscore_register_client); 1225 EXPORT_SYMBOL_GPL(smscore_register_client);
1226 1226
1227 /** 1227 /**
1228 * frees smsclient object and all subclients associated with it 1228 * frees smsclient object and all subclients associated with it
1229 * 1229 *
1230 * @param client pointer to smsclient object returned by 1230 * @param client pointer to smsclient object returned by
1231 * smscore_register_client 1231 * smscore_register_client
1232 * 1232 *
1233 */ 1233 */
1234 void smscore_unregister_client(struct smscore_client_t *client) 1234 void smscore_unregister_client(struct smscore_client_t *client)
1235 { 1235 {
1236 struct smscore_device_t *coredev = client->coredev; 1236 struct smscore_device_t *coredev = client->coredev;
1237 unsigned long flags; 1237 unsigned long flags;
1238 1238
1239 spin_lock_irqsave(&coredev->clientslock, flags); 1239 spin_lock_irqsave(&coredev->clientslock, flags);
1240 1240
1241 1241
1242 while (!list_empty(&client->idlist)) { 1242 while (!list_empty(&client->idlist)) {
1243 struct smscore_idlist_t *identry = 1243 struct smscore_idlist_t *identry =
1244 (struct smscore_idlist_t *) client->idlist.next; 1244 (struct smscore_idlist_t *) client->idlist.next;
1245 list_del(&identry->entry); 1245 list_del(&identry->entry);
1246 kfree(identry); 1246 kfree(identry);
1247 } 1247 }
1248 1248
1249 sms_info("%p", client->context); 1249 sms_info("%p", client->context);
1250 1250
1251 list_del(&client->entry); 1251 list_del(&client->entry);
1252 kfree(client); 1252 kfree(client);
1253 1253
1254 spin_unlock_irqrestore(&coredev->clientslock, flags); 1254 spin_unlock_irqrestore(&coredev->clientslock, flags);
1255 } 1255 }
1256 EXPORT_SYMBOL_GPL(smscore_unregister_client); 1256 EXPORT_SYMBOL_GPL(smscore_unregister_client);
1257 1257
1258 /** 1258 /**
1259 * verifies that source id is not taken by another client, 1259 * verifies that source id is not taken by another client,
1260 * calls device handler to send requests to the device 1260 * calls device handler to send requests to the device
1261 * 1261 *
1262 * @param client pointer to smsclient object returned by 1262 * @param client pointer to smsclient object returned by
1263 * smscore_register_client 1263 * smscore_register_client
1264 * @param buffer pointer to a request buffer 1264 * @param buffer pointer to a request buffer
1265 * @param size size (in bytes) of request buffer 1265 * @param size size (in bytes) of request buffer
1266 * 1266 *
1267 * @return 0 on success, <0 on error. 1267 * @return 0 on success, <0 on error.
1268 */ 1268 */
1269 int smsclient_sendrequest(struct smscore_client_t *client, 1269 int smsclient_sendrequest(struct smscore_client_t *client,
1270 void *buffer, size_t size) 1270 void *buffer, size_t size)
1271 { 1271 {
1272 struct smscore_device_t *coredev; 1272 struct smscore_device_t *coredev;
1273 struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) buffer; 1273 struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) buffer;
1274 int rc; 1274 int rc;
1275 1275
1276 if (client == NULL) { 1276 if (client == NULL) {
1277 sms_err("Got NULL client"); 1277 sms_err("Got NULL client");
1278 return -EINVAL; 1278 return -EINVAL;
1279 } 1279 }
1280 1280
1281 coredev = client->coredev; 1281 coredev = client->coredev;
1282 1282
1283 /* check that no other channel with same id exists */ 1283 /* check that no other channel with same id exists */
1284 if (coredev == NULL) { 1284 if (coredev == NULL) {
1285 sms_err("Got NULL coredev"); 1285 sms_err("Got NULL coredev");
1286 return -EINVAL; 1286 return -EINVAL;
1287 } 1287 }
1288 1288
1289 rc = smscore_validate_client(client->coredev, client, 0, 1289 rc = smscore_validate_client(client->coredev, client, 0,
1290 phdr->msgSrcId); 1290 phdr->msgSrcId);
1291 if (rc < 0) 1291 if (rc < 0)
1292 return rc; 1292 return rc;
1293 1293
1294 return coredev->sendrequest_handler(coredev->context, buffer, size); 1294 return coredev->sendrequest_handler(coredev->context, buffer, size);
1295 } 1295 }
1296 EXPORT_SYMBOL_GPL(smsclient_sendrequest); 1296 EXPORT_SYMBOL_GPL(smsclient_sendrequest);
1297 1297
1298 1298
1299 /* old GPIO managments implementation */ 1299 /* old GPIO managments implementation */
1300 int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin, 1300 int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin,
1301 struct smscore_config_gpio *pinconfig) 1301 struct smscore_config_gpio *pinconfig)
1302 { 1302 {
1303 struct { 1303 struct {
1304 struct SmsMsgHdr_ST hdr; 1304 struct SmsMsgHdr_ST hdr;
1305 u32 data[6]; 1305 u32 data[6];
1306 } msg; 1306 } msg;
1307 1307
1308 if (coredev->device_flags & SMS_DEVICE_FAMILY2) { 1308 if (coredev->device_flags & SMS_DEVICE_FAMILY2) {
1309 msg.hdr.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; 1309 msg.hdr.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
1310 msg.hdr.msgDstId = HIF_TASK; 1310 msg.hdr.msgDstId = HIF_TASK;
1311 msg.hdr.msgFlags = 0; 1311 msg.hdr.msgFlags = 0;
1312 msg.hdr.msgType = MSG_SMS_GPIO_CONFIG_EX_REQ; 1312 msg.hdr.msgType = MSG_SMS_GPIO_CONFIG_EX_REQ;
1313 msg.hdr.msgLength = sizeof(msg); 1313 msg.hdr.msgLength = sizeof(msg);
1314 1314
1315 msg.data[0] = pin; 1315 msg.data[0] = pin;
1316 msg.data[1] = pinconfig->pullupdown; 1316 msg.data[1] = pinconfig->pullupdown;
1317 1317
1318 /* Convert slew rate for Nova: Fast(0) = 3 / Slow(1) = 0; */ 1318 /* Convert slew rate for Nova: Fast(0) = 3 / Slow(1) = 0; */
1319 msg.data[2] = pinconfig->outputslewrate == 0 ? 3 : 0; 1319 msg.data[2] = pinconfig->outputslewrate == 0 ? 3 : 0;
1320 1320
1321 switch (pinconfig->outputdriving) { 1321 switch (pinconfig->outputdriving) {
1322 case SMS_GPIO_OUTPUTDRIVING_16mA: 1322 case SMS_GPIO_OUTPUTDRIVING_16mA:
1323 msg.data[3] = 7; /* Nova - 16mA */ 1323 msg.data[3] = 7; /* Nova - 16mA */
1324 break; 1324 break;
1325 case SMS_GPIO_OUTPUTDRIVING_12mA: 1325 case SMS_GPIO_OUTPUTDRIVING_12mA:
1326 msg.data[3] = 5; /* Nova - 11mA */ 1326 msg.data[3] = 5; /* Nova - 11mA */
1327 break; 1327 break;
1328 case SMS_GPIO_OUTPUTDRIVING_8mA: 1328 case SMS_GPIO_OUTPUTDRIVING_8mA:
1329 msg.data[3] = 3; /* Nova - 7mA */ 1329 msg.data[3] = 3; /* Nova - 7mA */
1330 break; 1330 break;
1331 case SMS_GPIO_OUTPUTDRIVING_4mA: 1331 case SMS_GPIO_OUTPUTDRIVING_4mA:
1332 default: 1332 default:
1333 msg.data[3] = 2; /* Nova - 4mA */ 1333 msg.data[3] = 2; /* Nova - 4mA */
1334 break; 1334 break;
1335 } 1335 }
1336 1336
1337 msg.data[4] = pinconfig->direction; 1337 msg.data[4] = pinconfig->direction;
1338 msg.data[5] = 0; 1338 msg.data[5] = 0;
1339 } else /* TODO: SMS_DEVICE_FAMILY1 */ 1339 } else /* TODO: SMS_DEVICE_FAMILY1 */
1340 return -EINVAL; 1340 return -EINVAL;
1341 1341
1342 return coredev->sendrequest_handler(coredev->context, 1342 return coredev->sendrequest_handler(coredev->context,
1343 &msg, sizeof(msg)); 1343 &msg, sizeof(msg));
1344 } 1344 }
1345 1345
1346 int smscore_set_gpio(struct smscore_device_t *coredev, u32 pin, int level) 1346 int smscore_set_gpio(struct smscore_device_t *coredev, u32 pin, int level)
1347 { 1347 {
1348 struct { 1348 struct {
1349 struct SmsMsgHdr_ST hdr; 1349 struct SmsMsgHdr_ST hdr;
1350 u32 data[3]; 1350 u32 data[3];
1351 } msg; 1351 } msg;
1352 1352
1353 if (pin > MAX_GPIO_PIN_NUMBER) 1353 if (pin > MAX_GPIO_PIN_NUMBER)
1354 return -EINVAL; 1354 return -EINVAL;
1355 1355
1356 msg.hdr.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; 1356 msg.hdr.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
1357 msg.hdr.msgDstId = HIF_TASK; 1357 msg.hdr.msgDstId = HIF_TASK;
1358 msg.hdr.msgFlags = 0; 1358 msg.hdr.msgFlags = 0;
1359 msg.hdr.msgType = MSG_SMS_GPIO_SET_LEVEL_REQ; 1359 msg.hdr.msgType = MSG_SMS_GPIO_SET_LEVEL_REQ;
1360 msg.hdr.msgLength = sizeof(msg); 1360 msg.hdr.msgLength = sizeof(msg);
1361 1361
1362 msg.data[0] = pin; 1362 msg.data[0] = pin;
1363 msg.data[1] = level ? 1 : 0; 1363 msg.data[1] = level ? 1 : 0;
1364 msg.data[2] = 0; 1364 msg.data[2] = 0;
1365 1365
1366 return coredev->sendrequest_handler(coredev->context, 1366 return coredev->sendrequest_handler(coredev->context,
1367 &msg, sizeof(msg)); 1367 &msg, sizeof(msg));
1368 } 1368 }
1369 1369
1370 /* new GPIO managment implementation */ 1370 /* new GPIO management implementation */
1371 static int GetGpioPinParams(u32 PinNum, u32 *pTranslatedPinNum, 1371 static int GetGpioPinParams(u32 PinNum, u32 *pTranslatedPinNum,
1372 u32 *pGroupNum, u32 *pGroupCfg) { 1372 u32 *pGroupNum, u32 *pGroupCfg) {
1373 1373
1374 *pGroupCfg = 1; 1374 *pGroupCfg = 1;
1375 1375
1376 if (PinNum >= 0 && PinNum <= 1) { 1376 if (PinNum >= 0 && PinNum <= 1) {
1377 *pTranslatedPinNum = 0; 1377 *pTranslatedPinNum = 0;
1378 *pGroupNum = 9; 1378 *pGroupNum = 9;
1379 *pGroupCfg = 2; 1379 *pGroupCfg = 2;
1380 } else if (PinNum >= 2 && PinNum <= 6) { 1380 } else if (PinNum >= 2 && PinNum <= 6) {
1381 *pTranslatedPinNum = 2; 1381 *pTranslatedPinNum = 2;
1382 *pGroupNum = 0; 1382 *pGroupNum = 0;
1383 *pGroupCfg = 2; 1383 *pGroupCfg = 2;
1384 } else if (PinNum >= 7 && PinNum <= 11) { 1384 } else if (PinNum >= 7 && PinNum <= 11) {
1385 *pTranslatedPinNum = 7; 1385 *pTranslatedPinNum = 7;
1386 *pGroupNum = 1; 1386 *pGroupNum = 1;
1387 } else if (PinNum >= 12 && PinNum <= 15) { 1387 } else if (PinNum >= 12 && PinNum <= 15) {
1388 *pTranslatedPinNum = 12; 1388 *pTranslatedPinNum = 12;
1389 *pGroupNum = 2; 1389 *pGroupNum = 2;
1390 *pGroupCfg = 3; 1390 *pGroupCfg = 3;
1391 } else if (PinNum == 16) { 1391 } else if (PinNum == 16) {
1392 *pTranslatedPinNum = 16; 1392 *pTranslatedPinNum = 16;
1393 *pGroupNum = 23; 1393 *pGroupNum = 23;
1394 } else if (PinNum >= 17 && PinNum <= 24) { 1394 } else if (PinNum >= 17 && PinNum <= 24) {
1395 *pTranslatedPinNum = 17; 1395 *pTranslatedPinNum = 17;
1396 *pGroupNum = 3; 1396 *pGroupNum = 3;
1397 } else if (PinNum == 25) { 1397 } else if (PinNum == 25) {
1398 *pTranslatedPinNum = 25; 1398 *pTranslatedPinNum = 25;
1399 *pGroupNum = 6; 1399 *pGroupNum = 6;
1400 } else if (PinNum >= 26 && PinNum <= 28) { 1400 } else if (PinNum >= 26 && PinNum <= 28) {
1401 *pTranslatedPinNum = 26; 1401 *pTranslatedPinNum = 26;
1402 *pGroupNum = 4; 1402 *pGroupNum = 4;
1403 } else if (PinNum == 29) { 1403 } else if (PinNum == 29) {
1404 *pTranslatedPinNum = 29; 1404 *pTranslatedPinNum = 29;
1405 *pGroupNum = 5; 1405 *pGroupNum = 5;
1406 *pGroupCfg = 2; 1406 *pGroupCfg = 2;
1407 } else if (PinNum == 30) { 1407 } else if (PinNum == 30) {
1408 *pTranslatedPinNum = 30; 1408 *pTranslatedPinNum = 30;
1409 *pGroupNum = 8; 1409 *pGroupNum = 8;
1410 } else if (PinNum == 31) { 1410 } else if (PinNum == 31) {
1411 *pTranslatedPinNum = 31; 1411 *pTranslatedPinNum = 31;
1412 *pGroupNum = 17; 1412 *pGroupNum = 17;
1413 } else 1413 } else
1414 return -1; 1414 return -1;
1415 1415
1416 *pGroupCfg <<= 24; 1416 *pGroupCfg <<= 24;
1417 1417
1418 return 0; 1418 return 0;
1419 } 1419 }
1420 1420
1421 int smscore_gpio_configure(struct smscore_device_t *coredev, u8 PinNum, 1421 int smscore_gpio_configure(struct smscore_device_t *coredev, u8 PinNum,
1422 struct smscore_gpio_config *pGpioConfig) { 1422 struct smscore_gpio_config *pGpioConfig) {
1423 1423
1424 u32 totalLen; 1424 u32 totalLen;
1425 u32 TranslatedPinNum = 0; 1425 u32 TranslatedPinNum = 0;
1426 u32 GroupNum = 0; 1426 u32 GroupNum = 0;
1427 u32 ElectricChar; 1427 u32 ElectricChar;
1428 u32 groupCfg; 1428 u32 groupCfg;
1429 void *buffer; 1429 void *buffer;
1430 int rc; 1430 int rc;
1431 1431
1432 struct SetGpioMsg { 1432 struct SetGpioMsg {
1433 struct SmsMsgHdr_ST xMsgHeader; 1433 struct SmsMsgHdr_ST xMsgHeader;
1434 u32 msgData[6]; 1434 u32 msgData[6];
1435 } *pMsg; 1435 } *pMsg;
1436 1436
1437 1437
1438 if (PinNum > MAX_GPIO_PIN_NUMBER) 1438 if (PinNum > MAX_GPIO_PIN_NUMBER)
1439 return -EINVAL; 1439 return -EINVAL;
1440 1440
1441 if (pGpioConfig == NULL) 1441 if (pGpioConfig == NULL)
1442 return -EINVAL; 1442 return -EINVAL;
1443 1443
1444 totalLen = sizeof(struct SmsMsgHdr_ST) + (sizeof(u32) * 6); 1444 totalLen = sizeof(struct SmsMsgHdr_ST) + (sizeof(u32) * 6);
1445 1445
1446 buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT, 1446 buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT,
1447 GFP_KERNEL | GFP_DMA); 1447 GFP_KERNEL | GFP_DMA);
1448 if (!buffer) 1448 if (!buffer)
1449 return -ENOMEM; 1449 return -ENOMEM;
1450 1450
1451 pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer); 1451 pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer);
1452 1452
1453 pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; 1453 pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
1454 pMsg->xMsgHeader.msgDstId = HIF_TASK; 1454 pMsg->xMsgHeader.msgDstId = HIF_TASK;
1455 pMsg->xMsgHeader.msgFlags = 0; 1455 pMsg->xMsgHeader.msgFlags = 0;
1456 pMsg->xMsgHeader.msgLength = (u16) totalLen; 1456 pMsg->xMsgHeader.msgLength = (u16) totalLen;
1457 pMsg->msgData[0] = PinNum; 1457 pMsg->msgData[0] = PinNum;
1458 1458
1459 if (!(coredev->device_flags & SMS_DEVICE_FAMILY2)) { 1459 if (!(coredev->device_flags & SMS_DEVICE_FAMILY2)) {
1460 pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_CONFIG_REQ; 1460 pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_CONFIG_REQ;
1461 if (GetGpioPinParams(PinNum, &TranslatedPinNum, &GroupNum, 1461 if (GetGpioPinParams(PinNum, &TranslatedPinNum, &GroupNum,
1462 &groupCfg) != 0) 1462 &groupCfg) != 0)
1463 return -EINVAL; 1463 return -EINVAL;
1464 1464
1465 pMsg->msgData[1] = TranslatedPinNum; 1465 pMsg->msgData[1] = TranslatedPinNum;
1466 pMsg->msgData[2] = GroupNum; 1466 pMsg->msgData[2] = GroupNum;
1467 ElectricChar = (pGpioConfig->PullUpDown) 1467 ElectricChar = (pGpioConfig->PullUpDown)
1468 | (pGpioConfig->InputCharacteristics << 2) 1468 | (pGpioConfig->InputCharacteristics << 2)
1469 | (pGpioConfig->OutputSlewRate << 3) 1469 | (pGpioConfig->OutputSlewRate << 3)
1470 | (pGpioConfig->OutputDriving << 4); 1470 | (pGpioConfig->OutputDriving << 4);
1471 pMsg->msgData[3] = ElectricChar; 1471 pMsg->msgData[3] = ElectricChar;
1472 pMsg->msgData[4] = pGpioConfig->Direction; 1472 pMsg->msgData[4] = pGpioConfig->Direction;
1473 pMsg->msgData[5] = groupCfg; 1473 pMsg->msgData[5] = groupCfg;
1474 } else { 1474 } else {
1475 pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_CONFIG_EX_REQ; 1475 pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_CONFIG_EX_REQ;
1476 pMsg->msgData[1] = pGpioConfig->PullUpDown; 1476 pMsg->msgData[1] = pGpioConfig->PullUpDown;
1477 pMsg->msgData[2] = pGpioConfig->OutputSlewRate; 1477 pMsg->msgData[2] = pGpioConfig->OutputSlewRate;
1478 pMsg->msgData[3] = pGpioConfig->OutputDriving; 1478 pMsg->msgData[3] = pGpioConfig->OutputDriving;
1479 pMsg->msgData[4] = pGpioConfig->Direction; 1479 pMsg->msgData[4] = pGpioConfig->Direction;
1480 pMsg->msgData[5] = 0; 1480 pMsg->msgData[5] = 0;
1481 } 1481 }
1482 1482
1483 smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg); 1483 smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg);
1484 rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen, 1484 rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen,
1485 &coredev->gpio_configuration_done); 1485 &coredev->gpio_configuration_done);
1486 1486
1487 if (rc != 0) { 1487 if (rc != 0) {
1488 if (rc == -ETIME) 1488 if (rc == -ETIME)
1489 sms_err("smscore_gpio_configure timeout"); 1489 sms_err("smscore_gpio_configure timeout");
1490 else 1490 else
1491 sms_err("smscore_gpio_configure error"); 1491 sms_err("smscore_gpio_configure error");
1492 } 1492 }
1493 kfree(buffer); 1493 kfree(buffer);
1494 1494
1495 return rc; 1495 return rc;
1496 } 1496 }
1497 1497
1498 int smscore_gpio_set_level(struct smscore_device_t *coredev, u8 PinNum, 1498 int smscore_gpio_set_level(struct smscore_device_t *coredev, u8 PinNum,
1499 u8 NewLevel) { 1499 u8 NewLevel) {
1500 1500
1501 u32 totalLen; 1501 u32 totalLen;
1502 int rc; 1502 int rc;
1503 void *buffer; 1503 void *buffer;
1504 1504
1505 struct SetGpioMsg { 1505 struct SetGpioMsg {
1506 struct SmsMsgHdr_ST xMsgHeader; 1506 struct SmsMsgHdr_ST xMsgHeader;
1507 u32 msgData[3]; /* keep it 3 ! */ 1507 u32 msgData[3]; /* keep it 3 ! */
1508 } *pMsg; 1508 } *pMsg;
1509 1509
1510 if ((NewLevel > 1) || (PinNum > MAX_GPIO_PIN_NUMBER) || 1510 if ((NewLevel > 1) || (PinNum > MAX_GPIO_PIN_NUMBER) ||
1511 (PinNum > MAX_GPIO_PIN_NUMBER)) 1511 (PinNum > MAX_GPIO_PIN_NUMBER))
1512 return -EINVAL; 1512 return -EINVAL;
1513 1513
1514 totalLen = sizeof(struct SmsMsgHdr_ST) + 1514 totalLen = sizeof(struct SmsMsgHdr_ST) +
1515 (3 * sizeof(u32)); /* keep it 3 ! */ 1515 (3 * sizeof(u32)); /* keep it 3 ! */
1516 1516
1517 buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT, 1517 buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT,
1518 GFP_KERNEL | GFP_DMA); 1518 GFP_KERNEL | GFP_DMA);
1519 if (!buffer) 1519 if (!buffer)
1520 return -ENOMEM; 1520 return -ENOMEM;
1521 1521
1522 pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer); 1522 pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer);
1523 1523
1524 pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; 1524 pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
1525 pMsg->xMsgHeader.msgDstId = HIF_TASK; 1525 pMsg->xMsgHeader.msgDstId = HIF_TASK;
1526 pMsg->xMsgHeader.msgFlags = 0; 1526 pMsg->xMsgHeader.msgFlags = 0;
1527 pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_SET_LEVEL_REQ; 1527 pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_SET_LEVEL_REQ;
1528 pMsg->xMsgHeader.msgLength = (u16) totalLen; 1528 pMsg->xMsgHeader.msgLength = (u16) totalLen;
1529 pMsg->msgData[0] = PinNum; 1529 pMsg->msgData[0] = PinNum;
1530 pMsg->msgData[1] = NewLevel; 1530 pMsg->msgData[1] = NewLevel;
1531 1531
1532 /* Send message to SMS */ 1532 /* Send message to SMS */
1533 smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg); 1533 smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg);
1534 rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen, 1534 rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen,
1535 &coredev->gpio_set_level_done); 1535 &coredev->gpio_set_level_done);
1536 1536
1537 if (rc != 0) { 1537 if (rc != 0) {
1538 if (rc == -ETIME) 1538 if (rc == -ETIME)
1539 sms_err("smscore_gpio_set_level timeout"); 1539 sms_err("smscore_gpio_set_level timeout");
1540 else 1540 else
1541 sms_err("smscore_gpio_set_level error"); 1541 sms_err("smscore_gpio_set_level error");
1542 } 1542 }
1543 kfree(buffer); 1543 kfree(buffer);
1544 1544
1545 return rc; 1545 return rc;
1546 } 1546 }
1547 1547
1548 int smscore_gpio_get_level(struct smscore_device_t *coredev, u8 PinNum, 1548 int smscore_gpio_get_level(struct smscore_device_t *coredev, u8 PinNum,
1549 u8 *level) { 1549 u8 *level) {
1550 1550
1551 u32 totalLen; 1551 u32 totalLen;
1552 int rc; 1552 int rc;
1553 void *buffer; 1553 void *buffer;
1554 1554
1555 struct SetGpioMsg { 1555 struct SetGpioMsg {
1556 struct SmsMsgHdr_ST xMsgHeader; 1556 struct SmsMsgHdr_ST xMsgHeader;
1557 u32 msgData[2]; 1557 u32 msgData[2];
1558 } *pMsg; 1558 } *pMsg;
1559 1559
1560 1560
1561 if (PinNum > MAX_GPIO_PIN_NUMBER) 1561 if (PinNum > MAX_GPIO_PIN_NUMBER)
1562 return -EINVAL; 1562 return -EINVAL;
1563 1563
1564 totalLen = sizeof(struct SmsMsgHdr_ST) + (2 * sizeof(u32)); 1564 totalLen = sizeof(struct SmsMsgHdr_ST) + (2 * sizeof(u32));
1565 1565
1566 buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT, 1566 buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT,
1567 GFP_KERNEL | GFP_DMA); 1567 GFP_KERNEL | GFP_DMA);
1568 if (!buffer) 1568 if (!buffer)
1569 return -ENOMEM; 1569 return -ENOMEM;
1570 1570
1571 pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer); 1571 pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer);
1572 1572
1573 pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; 1573 pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
1574 pMsg->xMsgHeader.msgDstId = HIF_TASK; 1574 pMsg->xMsgHeader.msgDstId = HIF_TASK;
1575 pMsg->xMsgHeader.msgFlags = 0; 1575 pMsg->xMsgHeader.msgFlags = 0;
1576 pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_GET_LEVEL_REQ; 1576 pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_GET_LEVEL_REQ;
1577 pMsg->xMsgHeader.msgLength = (u16) totalLen; 1577 pMsg->xMsgHeader.msgLength = (u16) totalLen;
1578 pMsg->msgData[0] = PinNum; 1578 pMsg->msgData[0] = PinNum;
1579 pMsg->msgData[1] = 0; 1579 pMsg->msgData[1] = 0;
1580 1580
1581 /* Send message to SMS */ 1581 /* Send message to SMS */
1582 smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg); 1582 smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg);
1583 rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen, 1583 rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen,
1584 &coredev->gpio_get_level_done); 1584 &coredev->gpio_get_level_done);
1585 1585
1586 if (rc != 0) { 1586 if (rc != 0) {
1587 if (rc == -ETIME) 1587 if (rc == -ETIME)
1588 sms_err("smscore_gpio_get_level timeout"); 1588 sms_err("smscore_gpio_get_level timeout");
1589 else 1589 else
1590 sms_err("smscore_gpio_get_level error"); 1590 sms_err("smscore_gpio_get_level error");
1591 } 1591 }
1592 kfree(buffer); 1592 kfree(buffer);
1593 1593
1594 /* Its a race between other gpio_get_level() and the copy of the single 1594 /* Its a race between other gpio_get_level() and the copy of the single
1595 * global 'coredev->gpio_get_res' to the function's variable 'level' 1595 * global 'coredev->gpio_get_res' to the function's variable 'level'
1596 */ 1596 */
1597 *level = coredev->gpio_get_res; 1597 *level = coredev->gpio_get_res;
1598 1598
1599 return rc; 1599 return rc;
1600 } 1600 }
1601 1601
1602 static int __init smscore_module_init(void) 1602 static int __init smscore_module_init(void)
1603 { 1603 {
1604 int rc = 0; 1604 int rc = 0;
1605 1605
1606 INIT_LIST_HEAD(&g_smscore_notifyees); 1606 INIT_LIST_HEAD(&g_smscore_notifyees);
1607 INIT_LIST_HEAD(&g_smscore_devices); 1607 INIT_LIST_HEAD(&g_smscore_devices);
1608 kmutex_init(&g_smscore_deviceslock); 1608 kmutex_init(&g_smscore_deviceslock);
1609 1609
1610 INIT_LIST_HEAD(&g_smscore_registry); 1610 INIT_LIST_HEAD(&g_smscore_registry);
1611 kmutex_init(&g_smscore_registrylock); 1611 kmutex_init(&g_smscore_registrylock);
1612 1612
1613 return rc; 1613 return rc;
1614 } 1614 }
1615 1615
1616 static void __exit smscore_module_exit(void) 1616 static void __exit smscore_module_exit(void)
1617 { 1617 {
1618 kmutex_lock(&g_smscore_deviceslock); 1618 kmutex_lock(&g_smscore_deviceslock);
1619 while (!list_empty(&g_smscore_notifyees)) { 1619 while (!list_empty(&g_smscore_notifyees)) {
1620 struct smscore_device_notifyee_t *notifyee = 1620 struct smscore_device_notifyee_t *notifyee =
1621 (struct smscore_device_notifyee_t *) 1621 (struct smscore_device_notifyee_t *)
1622 g_smscore_notifyees.next; 1622 g_smscore_notifyees.next;
1623 1623
1624 list_del(&notifyee->entry); 1624 list_del(&notifyee->entry);
1625 kfree(notifyee); 1625 kfree(notifyee);
1626 } 1626 }
1627 kmutex_unlock(&g_smscore_deviceslock); 1627 kmutex_unlock(&g_smscore_deviceslock);
1628 1628
1629 kmutex_lock(&g_smscore_registrylock); 1629 kmutex_lock(&g_smscore_registrylock);
1630 while (!list_empty(&g_smscore_registry)) { 1630 while (!list_empty(&g_smscore_registry)) {
1631 struct smscore_registry_entry_t *entry = 1631 struct smscore_registry_entry_t *entry =
1632 (struct smscore_registry_entry_t *) 1632 (struct smscore_registry_entry_t *)
1633 g_smscore_registry.next; 1633 g_smscore_registry.next;
1634 1634
1635 list_del(&entry->entry); 1635 list_del(&entry->entry);
1636 kfree(entry); 1636 kfree(entry);
1637 } 1637 }
1638 kmutex_unlock(&g_smscore_registrylock); 1638 kmutex_unlock(&g_smscore_registrylock);
1639 1639
1640 sms_debug(""); 1640 sms_debug("");
1641 } 1641 }
1642 1642
1643 module_init(smscore_module_init); 1643 module_init(smscore_module_init);
1644 module_exit(smscore_module_exit); 1644 module_exit(smscore_module_exit);
1645 1645
1646 MODULE_DESCRIPTION("Siano MDTV Core module"); 1646 MODULE_DESCRIPTION("Siano MDTV Core module");
1647 MODULE_AUTHOR("Siano Mobile Silicon, Inc. (uris@siano-ms.com)"); 1647 MODULE_AUTHOR("Siano Mobile Silicon, Inc. (uris@siano-ms.com)");
1648 MODULE_LICENSE("GPL"); 1648 MODULE_LICENSE("GPL");
1649 1649
drivers/media/dvb/siano/smscoreapi.h
1 /**************************************************************** 1 /****************************************************************
2 2
3 Siano Mobile Silicon, Inc. 3 Siano Mobile Silicon, Inc.
4 MDTV receiver kernel modules. 4 MDTV receiver kernel modules.
5 Copyright (C) 2006-2008, Uri Shkolnik, Anatoly Greenblat 5 Copyright (C) 2006-2008, Uri Shkolnik, Anatoly Greenblat
6 6
7 This program is free software: you can redistribute it and/or modify 7 This program is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by 8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 2 of the License, or 9 the Free Software Foundation, either version 2 of the License, or
10 (at your option) any later version. 10 (at your option) any later version.
11 11
12 This program is distributed in the hope that it will be useful, 12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details. 15 GNU General Public License for more details.
16 16
17 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. 18 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 19
20 ****************************************************************/ 20 ****************************************************************/
21 21
22 #ifndef __SMS_CORE_API_H__ 22 #ifndef __SMS_CORE_API_H__
23 #define __SMS_CORE_API_H__ 23 #define __SMS_CORE_API_H__
24 24
25 #include <linux/version.h> 25 #include <linux/version.h>
26 #include <linux/device.h> 26 #include <linux/device.h>
27 #include <linux/list.h> 27 #include <linux/list.h>
28 #include <linux/mm.h> 28 #include <linux/mm.h>
29 #include <linux/scatterlist.h> 29 #include <linux/scatterlist.h>
30 #include <linux/types.h> 30 #include <linux/types.h>
31 #include <linux/mutex.h> 31 #include <linux/mutex.h>
32 #include <linux/wait.h> 32 #include <linux/wait.h>
33 #include <linux/timer.h> 33 #include <linux/timer.h>
34 34
35 #include <asm/page.h> 35 #include <asm/page.h>
36 36
37 #include "smsir.h" 37 #include "smsir.h"
38 38
39 #define kmutex_init(_p_) mutex_init(_p_) 39 #define kmutex_init(_p_) mutex_init(_p_)
40 #define kmutex_lock(_p_) mutex_lock(_p_) 40 #define kmutex_lock(_p_) mutex_lock(_p_)
41 #define kmutex_trylock(_p_) mutex_trylock(_p_) 41 #define kmutex_trylock(_p_) mutex_trylock(_p_)
42 #define kmutex_unlock(_p_) mutex_unlock(_p_) 42 #define kmutex_unlock(_p_) mutex_unlock(_p_)
43 43
44 #ifndef min 44 #ifndef min
45 #define min(a, b) (((a) < (b)) ? (a) : (b)) 45 #define min(a, b) (((a) < (b)) ? (a) : (b))
46 #endif 46 #endif
47 47
48 #define SMS_PROTOCOL_MAX_RAOUNDTRIP_MS (10000) 48 #define SMS_PROTOCOL_MAX_RAOUNDTRIP_MS (10000)
49 #define SMS_ALLOC_ALIGNMENT 128 49 #define SMS_ALLOC_ALIGNMENT 128
50 #define SMS_DMA_ALIGNMENT 16 50 #define SMS_DMA_ALIGNMENT 16
51 #define SMS_ALIGN_ADDRESS(addr) \ 51 #define SMS_ALIGN_ADDRESS(addr) \
52 ((((uintptr_t)(addr)) + (SMS_DMA_ALIGNMENT-1)) & ~(SMS_DMA_ALIGNMENT-1)) 52 ((((uintptr_t)(addr)) + (SMS_DMA_ALIGNMENT-1)) & ~(SMS_DMA_ALIGNMENT-1))
53 53
54 #define SMS_DEVICE_FAMILY2 1 54 #define SMS_DEVICE_FAMILY2 1
55 #define SMS_ROM_NO_RESPONSE 2 55 #define SMS_ROM_NO_RESPONSE 2
56 #define SMS_DEVICE_NOT_READY 0x8000000 56 #define SMS_DEVICE_NOT_READY 0x8000000
57 57
58 enum sms_device_type_st { 58 enum sms_device_type_st {
59 SMS_STELLAR = 0, 59 SMS_STELLAR = 0,
60 SMS_NOVA_A0, 60 SMS_NOVA_A0,
61 SMS_NOVA_B0, 61 SMS_NOVA_B0,
62 SMS_VEGA, 62 SMS_VEGA,
63 SMS_NUM_OF_DEVICE_TYPES 63 SMS_NUM_OF_DEVICE_TYPES
64 }; 64 };
65 65
66 struct smscore_device_t; 66 struct smscore_device_t;
67 struct smscore_client_t; 67 struct smscore_client_t;
68 struct smscore_buffer_t; 68 struct smscore_buffer_t;
69 69
70 typedef int (*hotplug_t)(struct smscore_device_t *coredev, 70 typedef int (*hotplug_t)(struct smscore_device_t *coredev,
71 struct device *device, int arrival); 71 struct device *device, int arrival);
72 72
73 typedef int (*setmode_t)(void *context, int mode); 73 typedef int (*setmode_t)(void *context, int mode);
74 typedef void (*detectmode_t)(void *context, int *mode); 74 typedef void (*detectmode_t)(void *context, int *mode);
75 typedef int (*sendrequest_t)(void *context, void *buffer, size_t size); 75 typedef int (*sendrequest_t)(void *context, void *buffer, size_t size);
76 typedef int (*loadfirmware_t)(void *context, void *buffer, size_t size); 76 typedef int (*loadfirmware_t)(void *context, void *buffer, size_t size);
77 typedef int (*preload_t)(void *context); 77 typedef int (*preload_t)(void *context);
78 typedef int (*postload_t)(void *context); 78 typedef int (*postload_t)(void *context);
79 79
80 typedef int (*onresponse_t)(void *context, struct smscore_buffer_t *cb); 80 typedef int (*onresponse_t)(void *context, struct smscore_buffer_t *cb);
81 typedef void (*onremove_t)(void *context); 81 typedef void (*onremove_t)(void *context);
82 82
83 struct smscore_buffer_t { 83 struct smscore_buffer_t {
84 /* public members, once passed to clients can be changed freely */ 84 /* public members, once passed to clients can be changed freely */
85 struct list_head entry; 85 struct list_head entry;
86 int size; 86 int size;
87 int offset; 87 int offset;
88 88
89 /* private members, read-only for clients */ 89 /* private members, read-only for clients */
90 void *p; 90 void *p;
91 dma_addr_t phys; 91 dma_addr_t phys;
92 unsigned long offset_in_common; 92 unsigned long offset_in_common;
93 }; 93 };
94 94
95 struct smsdevice_params_t { 95 struct smsdevice_params_t {
96 struct device *device; 96 struct device *device;
97 97
98 int buffer_size; 98 int buffer_size;
99 int num_buffers; 99 int num_buffers;
100 100
101 char devpath[32]; 101 char devpath[32];
102 unsigned long flags; 102 unsigned long flags;
103 103
104 setmode_t setmode_handler; 104 setmode_t setmode_handler;
105 detectmode_t detectmode_handler; 105 detectmode_t detectmode_handler;
106 sendrequest_t sendrequest_handler; 106 sendrequest_t sendrequest_handler;
107 preload_t preload_handler; 107 preload_t preload_handler;
108 postload_t postload_handler; 108 postload_t postload_handler;
109 109
110 void *context; 110 void *context;
111 enum sms_device_type_st device_type; 111 enum sms_device_type_st device_type;
112 }; 112 };
113 113
114 struct smsclient_params_t { 114 struct smsclient_params_t {
115 int initial_id; 115 int initial_id;
116 int data_type; 116 int data_type;
117 onresponse_t onresponse_handler; 117 onresponse_t onresponse_handler;
118 onremove_t onremove_handler; 118 onremove_t onremove_handler;
119 void *context; 119 void *context;
120 }; 120 };
121 121
122 struct smscore_device_t { 122 struct smscore_device_t {
123 struct list_head entry; 123 struct list_head entry;
124 124
125 struct list_head clients; 125 struct list_head clients;
126 struct list_head subclients; 126 struct list_head subclients;
127 spinlock_t clientslock; 127 spinlock_t clientslock;
128 128
129 struct list_head buffers; 129 struct list_head buffers;
130 spinlock_t bufferslock; 130 spinlock_t bufferslock;
131 int num_buffers; 131 int num_buffers;
132 132
133 void *common_buffer; 133 void *common_buffer;
134 int common_buffer_size; 134 int common_buffer_size;
135 dma_addr_t common_buffer_phys; 135 dma_addr_t common_buffer_phys;
136 136
137 void *context; 137 void *context;
138 struct device *device; 138 struct device *device;
139 139
140 char devpath[32]; 140 char devpath[32];
141 unsigned long device_flags; 141 unsigned long device_flags;
142 142
143 setmode_t setmode_handler; 143 setmode_t setmode_handler;
144 detectmode_t detectmode_handler; 144 detectmode_t detectmode_handler;
145 sendrequest_t sendrequest_handler; 145 sendrequest_t sendrequest_handler;
146 preload_t preload_handler; 146 preload_t preload_handler;
147 postload_t postload_handler; 147 postload_t postload_handler;
148 148
149 int mode, modes_supported; 149 int mode, modes_supported;
150 150
151 /* host <--> device messages */ 151 /* host <--> device messages */
152 struct completion version_ex_done, data_download_done, trigger_done; 152 struct completion version_ex_done, data_download_done, trigger_done;
153 struct completion init_device_done, reload_start_done, resume_done; 153 struct completion init_device_done, reload_start_done, resume_done;
154 struct completion gpio_configuration_done, gpio_set_level_done; 154 struct completion gpio_configuration_done, gpio_set_level_done;
155 struct completion gpio_get_level_done, ir_init_done; 155 struct completion gpio_get_level_done, ir_init_done;
156 156
157 /* Buffer management */ 157 /* Buffer management */
158 wait_queue_head_t buffer_mng_waitq; 158 wait_queue_head_t buffer_mng_waitq;
159 159
160 /* GPIO */ 160 /* GPIO */
161 int gpio_get_res; 161 int gpio_get_res;
162 162
163 /* Target hardware board */ 163 /* Target hardware board */
164 int board_id; 164 int board_id;
165 165
166 /* Firmware */ 166 /* Firmware */
167 u8 *fw_buf; 167 u8 *fw_buf;
168 u32 fw_buf_size; 168 u32 fw_buf_size;
169 169
170 /* Infrared (IR) */ 170 /* Infrared (IR) */
171 struct ir_t ir; 171 struct ir_t ir;
172 172
173 int led_state; 173 int led_state;
174 }; 174 };
175 175
176 /* GPIO definitions for antenna frequency domain control (SMS8021) */ 176 /* GPIO definitions for antenna frequency domain control (SMS8021) */
177 #define SMS_ANTENNA_GPIO_0 1 177 #define SMS_ANTENNA_GPIO_0 1
178 #define SMS_ANTENNA_GPIO_1 0 178 #define SMS_ANTENNA_GPIO_1 0
179 179
180 #define BW_8_MHZ 0 180 #define BW_8_MHZ 0
181 #define BW_7_MHZ 1 181 #define BW_7_MHZ 1
182 #define BW_6_MHZ 2 182 #define BW_6_MHZ 2
183 #define BW_5_MHZ 3 183 #define BW_5_MHZ 3
184 #define BW_ISDBT_1SEG 4 184 #define BW_ISDBT_1SEG 4
185 #define BW_ISDBT_3SEG 5 185 #define BW_ISDBT_3SEG 5
186 186
187 #define MSG_HDR_FLAG_SPLIT_MSG 4 187 #define MSG_HDR_FLAG_SPLIT_MSG 4
188 188
189 #define MAX_GPIO_PIN_NUMBER 31 189 #define MAX_GPIO_PIN_NUMBER 31
190 190
191 #define HIF_TASK 11 191 #define HIF_TASK 11
192 #define SMS_HOST_LIB 150 192 #define SMS_HOST_LIB 150
193 #define DVBT_BDA_CONTROL_MSG_ID 201 193 #define DVBT_BDA_CONTROL_MSG_ID 201
194 194
195 #define SMS_MAX_PAYLOAD_SIZE 240 195 #define SMS_MAX_PAYLOAD_SIZE 240
196 #define SMS_TUNE_TIMEOUT 500 196 #define SMS_TUNE_TIMEOUT 500
197 197
198 #define MSG_SMS_GPIO_CONFIG_REQ 507 198 #define MSG_SMS_GPIO_CONFIG_REQ 507
199 #define MSG_SMS_GPIO_CONFIG_RES 508 199 #define MSG_SMS_GPIO_CONFIG_RES 508
200 #define MSG_SMS_GPIO_SET_LEVEL_REQ 509 200 #define MSG_SMS_GPIO_SET_LEVEL_REQ 509
201 #define MSG_SMS_GPIO_SET_LEVEL_RES 510 201 #define MSG_SMS_GPIO_SET_LEVEL_RES 510
202 #define MSG_SMS_GPIO_GET_LEVEL_REQ 511 202 #define MSG_SMS_GPIO_GET_LEVEL_REQ 511
203 #define MSG_SMS_GPIO_GET_LEVEL_RES 512 203 #define MSG_SMS_GPIO_GET_LEVEL_RES 512
204 #define MSG_SMS_RF_TUNE_REQ 561 204 #define MSG_SMS_RF_TUNE_REQ 561
205 #define MSG_SMS_RF_TUNE_RES 562 205 #define MSG_SMS_RF_TUNE_RES 562
206 #define MSG_SMS_INIT_DEVICE_REQ 578 206 #define MSG_SMS_INIT_DEVICE_REQ 578
207 #define MSG_SMS_INIT_DEVICE_RES 579 207 #define MSG_SMS_INIT_DEVICE_RES 579
208 #define MSG_SMS_ADD_PID_FILTER_REQ 601 208 #define MSG_SMS_ADD_PID_FILTER_REQ 601
209 #define MSG_SMS_ADD_PID_FILTER_RES 602 209 #define MSG_SMS_ADD_PID_FILTER_RES 602
210 #define MSG_SMS_REMOVE_PID_FILTER_REQ 603 210 #define MSG_SMS_REMOVE_PID_FILTER_REQ 603
211 #define MSG_SMS_REMOVE_PID_FILTER_RES 604 211 #define MSG_SMS_REMOVE_PID_FILTER_RES 604
212 #define MSG_SMS_DAB_CHANNEL 607 212 #define MSG_SMS_DAB_CHANNEL 607
213 #define MSG_SMS_GET_PID_FILTER_LIST_REQ 608 213 #define MSG_SMS_GET_PID_FILTER_LIST_REQ 608
214 #define MSG_SMS_GET_PID_FILTER_LIST_RES 609 214 #define MSG_SMS_GET_PID_FILTER_LIST_RES 609
215 #define MSG_SMS_HO_PER_SLICES_IND 630 215 #define MSG_SMS_HO_PER_SLICES_IND 630
216 #define MSG_SMS_SET_ANTENNA_CONFIG_REQ 651 216 #define MSG_SMS_SET_ANTENNA_CONFIG_REQ 651
217 #define MSG_SMS_SET_ANTENNA_CONFIG_RES 652 217 #define MSG_SMS_SET_ANTENNA_CONFIG_RES 652
218 #define MSG_SMS_SLEEP_RESUME_COMP_IND 655 218 #define MSG_SMS_SLEEP_RESUME_COMP_IND 655
219 #define MSG_SMS_DATA_DOWNLOAD_REQ 660 219 #define MSG_SMS_DATA_DOWNLOAD_REQ 660
220 #define MSG_SMS_DATA_DOWNLOAD_RES 661 220 #define MSG_SMS_DATA_DOWNLOAD_RES 661
221 #define MSG_SMS_SWDOWNLOAD_TRIGGER_REQ 664 221 #define MSG_SMS_SWDOWNLOAD_TRIGGER_REQ 664
222 #define MSG_SMS_SWDOWNLOAD_TRIGGER_RES 665 222 #define MSG_SMS_SWDOWNLOAD_TRIGGER_RES 665
223 #define MSG_SMS_SWDOWNLOAD_BACKDOOR_REQ 666 223 #define MSG_SMS_SWDOWNLOAD_BACKDOOR_REQ 666
224 #define MSG_SMS_SWDOWNLOAD_BACKDOOR_RES 667 224 #define MSG_SMS_SWDOWNLOAD_BACKDOOR_RES 667
225 #define MSG_SMS_GET_VERSION_EX_REQ 668 225 #define MSG_SMS_GET_VERSION_EX_REQ 668
226 #define MSG_SMS_GET_VERSION_EX_RES 669 226 #define MSG_SMS_GET_VERSION_EX_RES 669
227 #define MSG_SMS_SET_CLOCK_OUTPUT_REQ 670 227 #define MSG_SMS_SET_CLOCK_OUTPUT_REQ 670
228 #define MSG_SMS_I2C_SET_FREQ_REQ 685 228 #define MSG_SMS_I2C_SET_FREQ_REQ 685
229 #define MSG_SMS_GENERIC_I2C_REQ 687 229 #define MSG_SMS_GENERIC_I2C_REQ 687
230 #define MSG_SMS_GENERIC_I2C_RES 688 230 #define MSG_SMS_GENERIC_I2C_RES 688
231 #define MSG_SMS_DVBT_BDA_DATA 693 231 #define MSG_SMS_DVBT_BDA_DATA 693
232 #define MSG_SW_RELOAD_REQ 697 232 #define MSG_SW_RELOAD_REQ 697
233 #define MSG_SMS_DATA_MSG 699 233 #define MSG_SMS_DATA_MSG 699
234 #define MSG_SW_RELOAD_START_REQ 702 234 #define MSG_SW_RELOAD_START_REQ 702
235 #define MSG_SW_RELOAD_START_RES 703 235 #define MSG_SW_RELOAD_START_RES 703
236 #define MSG_SW_RELOAD_EXEC_REQ 704 236 #define MSG_SW_RELOAD_EXEC_REQ 704
237 #define MSG_SW_RELOAD_EXEC_RES 705 237 #define MSG_SW_RELOAD_EXEC_RES 705
238 #define MSG_SMS_SPI_INT_LINE_SET_REQ 710 238 #define MSG_SMS_SPI_INT_LINE_SET_REQ 710
239 #define MSG_SMS_GPIO_CONFIG_EX_REQ 712 239 #define MSG_SMS_GPIO_CONFIG_EX_REQ 712
240 #define MSG_SMS_GPIO_CONFIG_EX_RES 713 240 #define MSG_SMS_GPIO_CONFIG_EX_RES 713
241 #define MSG_SMS_ISDBT_TUNE_REQ 776 241 #define MSG_SMS_ISDBT_TUNE_REQ 776
242 #define MSG_SMS_ISDBT_TUNE_RES 777 242 #define MSG_SMS_ISDBT_TUNE_RES 777
243 #define MSG_SMS_TRANSMISSION_IND 782 243 #define MSG_SMS_TRANSMISSION_IND 782
244 #define MSG_SMS_START_IR_REQ 800 244 #define MSG_SMS_START_IR_REQ 800
245 #define MSG_SMS_START_IR_RES 801 245 #define MSG_SMS_START_IR_RES 801
246 #define MSG_SMS_IR_SAMPLES_IND 802 246 #define MSG_SMS_IR_SAMPLES_IND 802
247 #define MSG_SMS_SIGNAL_DETECTED_IND 827 247 #define MSG_SMS_SIGNAL_DETECTED_IND 827
248 #define MSG_SMS_NO_SIGNAL_IND 828 248 #define MSG_SMS_NO_SIGNAL_IND 828
249 249
250 #define SMS_INIT_MSG_EX(ptr, type, src, dst, len) do { \ 250 #define SMS_INIT_MSG_EX(ptr, type, src, dst, len) do { \
251 (ptr)->msgType = type; (ptr)->msgSrcId = src; (ptr)->msgDstId = dst; \ 251 (ptr)->msgType = type; (ptr)->msgSrcId = src; (ptr)->msgDstId = dst; \
252 (ptr)->msgLength = len; (ptr)->msgFlags = 0; \ 252 (ptr)->msgLength = len; (ptr)->msgFlags = 0; \
253 } while (0) 253 } while (0)
254 254
255 #define SMS_INIT_MSG(ptr, type, len) \ 255 #define SMS_INIT_MSG(ptr, type, len) \
256 SMS_INIT_MSG_EX(ptr, type, 0, HIF_TASK, len) 256 SMS_INIT_MSG_EX(ptr, type, 0, HIF_TASK, len)
257 257
258 enum SMS_DVB3_EVENTS { 258 enum SMS_DVB3_EVENTS {
259 DVB3_EVENT_INIT = 0, 259 DVB3_EVENT_INIT = 0,
260 DVB3_EVENT_SLEEP, 260 DVB3_EVENT_SLEEP,
261 DVB3_EVENT_HOTPLUG, 261 DVB3_EVENT_HOTPLUG,
262 DVB3_EVENT_FE_LOCK, 262 DVB3_EVENT_FE_LOCK,
263 DVB3_EVENT_FE_UNLOCK, 263 DVB3_EVENT_FE_UNLOCK,
264 DVB3_EVENT_UNC_OK, 264 DVB3_EVENT_UNC_OK,
265 DVB3_EVENT_UNC_ERR 265 DVB3_EVENT_UNC_ERR
266 }; 266 };
267 267
268 enum SMS_DEVICE_MODE { 268 enum SMS_DEVICE_MODE {
269 DEVICE_MODE_NONE = -1, 269 DEVICE_MODE_NONE = -1,
270 DEVICE_MODE_DVBT = 0, 270 DEVICE_MODE_DVBT = 0,
271 DEVICE_MODE_DVBH, 271 DEVICE_MODE_DVBH,
272 DEVICE_MODE_DAB_TDMB, 272 DEVICE_MODE_DAB_TDMB,
273 DEVICE_MODE_DAB_TDMB_DABIP, 273 DEVICE_MODE_DAB_TDMB_DABIP,
274 DEVICE_MODE_DVBT_BDA, 274 DEVICE_MODE_DVBT_BDA,
275 DEVICE_MODE_ISDBT, 275 DEVICE_MODE_ISDBT,
276 DEVICE_MODE_ISDBT_BDA, 276 DEVICE_MODE_ISDBT_BDA,
277 DEVICE_MODE_CMMB, 277 DEVICE_MODE_CMMB,
278 DEVICE_MODE_RAW_TUNER, 278 DEVICE_MODE_RAW_TUNER,
279 DEVICE_MODE_MAX, 279 DEVICE_MODE_MAX,
280 }; 280 };
281 281
282 struct SmsMsgHdr_ST { 282 struct SmsMsgHdr_ST {
283 u16 msgType; 283 u16 msgType;
284 u8 msgSrcId; 284 u8 msgSrcId;
285 u8 msgDstId; 285 u8 msgDstId;
286 u16 msgLength; /* Length of entire message, including header */ 286 u16 msgLength; /* Length of entire message, including header */
287 u16 msgFlags; 287 u16 msgFlags;
288 }; 288 };
289 289
290 struct SmsMsgData_ST { 290 struct SmsMsgData_ST {
291 struct SmsMsgHdr_ST xMsgHeader; 291 struct SmsMsgHdr_ST xMsgHeader;
292 u32 msgData[1]; 292 u32 msgData[1];
293 }; 293 };
294 294
295 struct SmsMsgData_ST2 { 295 struct SmsMsgData_ST2 {
296 struct SmsMsgHdr_ST xMsgHeader; 296 struct SmsMsgHdr_ST xMsgHeader;
297 u32 msgData[2]; 297 u32 msgData[2];
298 }; 298 };
299 299
300 struct SmsDataDownload_ST { 300 struct SmsDataDownload_ST {
301 struct SmsMsgHdr_ST xMsgHeader; 301 struct SmsMsgHdr_ST xMsgHeader;
302 u32 MemAddr; 302 u32 MemAddr;
303 u8 Payload[SMS_MAX_PAYLOAD_SIZE]; 303 u8 Payload[SMS_MAX_PAYLOAD_SIZE];
304 }; 304 };
305 305
306 struct SmsVersionRes_ST { 306 struct SmsVersionRes_ST {
307 struct SmsMsgHdr_ST xMsgHeader; 307 struct SmsMsgHdr_ST xMsgHeader;
308 308
309 u16 ChipModel; /* e.g. 0x1102 for SMS-1102 "Nova" */ 309 u16 ChipModel; /* e.g. 0x1102 for SMS-1102 "Nova" */
310 u8 Step; /* 0 - Step A */ 310 u8 Step; /* 0 - Step A */
311 u8 MetalFix; /* 0 - Metal 0 */ 311 u8 MetalFix; /* 0 - Metal 0 */
312 312
313 /* FirmwareId 0xFF if ROM, otherwise the 313 /* FirmwareId 0xFF if ROM, otherwise the
314 * value indicated by SMSHOSTLIB_DEVICE_MODES_E */ 314 * value indicated by SMSHOSTLIB_DEVICE_MODES_E */
315 u8 FirmwareId; 315 u8 FirmwareId;
316 /* SupportedProtocols Bitwise OR combination of 316 /* SupportedProtocols Bitwise OR combination of
317 * supported protocols */ 317 * supported protocols */
318 u8 SupportedProtocols; 318 u8 SupportedProtocols;
319 319
320 u8 VersionMajor; 320 u8 VersionMajor;
321 u8 VersionMinor; 321 u8 VersionMinor;
322 u8 VersionPatch; 322 u8 VersionPatch;
323 u8 VersionFieldPatch; 323 u8 VersionFieldPatch;
324 324
325 u8 RomVersionMajor; 325 u8 RomVersionMajor;
326 u8 RomVersionMinor; 326 u8 RomVersionMinor;
327 u8 RomVersionPatch; 327 u8 RomVersionPatch;
328 u8 RomVersionFieldPatch; 328 u8 RomVersionFieldPatch;
329 329
330 u8 TextLabel[34]; 330 u8 TextLabel[34];
331 }; 331 };
332 332
333 struct SmsFirmware_ST { 333 struct SmsFirmware_ST {
334 u32 CheckSum; 334 u32 CheckSum;
335 u32 Length; 335 u32 Length;
336 u32 StartAddress; 336 u32 StartAddress;
337 u8 Payload[1]; 337 u8 Payload[1];
338 }; 338 };
339 339
340 /* Statistics information returned as response for 340 /* Statistics information returned as response for
341 * SmsHostApiGetStatistics_Req */ 341 * SmsHostApiGetStatistics_Req */
342 struct SMSHOSTLIB_STATISTICS_S { 342 struct SMSHOSTLIB_STATISTICS_S {
343 u32 Reserved; /* Reserved */ 343 u32 Reserved; /* Reserved */
344 344
345 /* Common parameters */ 345 /* Common parameters */
346 u32 IsRfLocked; /* 0 - not locked, 1 - locked */ 346 u32 IsRfLocked; /* 0 - not locked, 1 - locked */
347 u32 IsDemodLocked; /* 0 - not locked, 1 - locked */ 347 u32 IsDemodLocked; /* 0 - not locked, 1 - locked */
348 u32 IsExternalLNAOn; /* 0 - external LNA off, 1 - external LNA on */ 348 u32 IsExternalLNAOn; /* 0 - external LNA off, 1 - external LNA on */
349 349
350 /* Reception quality */ 350 /* Reception quality */
351 s32 SNR; /* dB */ 351 s32 SNR; /* dB */
352 u32 BER; /* Post Viterbi BER [1E-5] */ 352 u32 BER; /* Post Viterbi BER [1E-5] */
353 u32 FIB_CRC; /* CRC errors percentage, valid only for DAB */ 353 u32 FIB_CRC; /* CRC errors percentage, valid only for DAB */
354 u32 TS_PER; /* Transport stream PER, 354 u32 TS_PER; /* Transport stream PER,
355 0xFFFFFFFF indicate N/A, valid only for DVB-T/H */ 355 0xFFFFFFFF indicate N/A, valid only for DVB-T/H */
356 u32 MFER; /* DVB-H frame error rate in percentage, 356 u32 MFER; /* DVB-H frame error rate in percentage,
357 0xFFFFFFFF indicate N/A, valid only for DVB-H */ 357 0xFFFFFFFF indicate N/A, valid only for DVB-H */
358 s32 RSSI; /* dBm */ 358 s32 RSSI; /* dBm */
359 s32 InBandPwr; /* In band power in dBM */ 359 s32 InBandPwr; /* In band power in dBM */
360 s32 CarrierOffset; /* Carrier Offset in bin/1024 */ 360 s32 CarrierOffset; /* Carrier Offset in bin/1024 */
361 361
362 /* Transmission parameters */ 362 /* Transmission parameters */
363 u32 Frequency; /* Frequency in Hz */ 363 u32 Frequency; /* Frequency in Hz */
364 u32 Bandwidth; /* Bandwidth in MHz, valid only for DVB-T/H */ 364 u32 Bandwidth; /* Bandwidth in MHz, valid only for DVB-T/H */
365 u32 TransmissionMode; /* Transmission Mode, for DAB modes 1-4, 365 u32 TransmissionMode; /* Transmission Mode, for DAB modes 1-4,
366 for DVB-T/H FFT mode carriers in Kilos */ 366 for DVB-T/H FFT mode carriers in Kilos */
367 u32 ModemState; /* from SMSHOSTLIB_DVB_MODEM_STATE_ET, 367 u32 ModemState; /* from SMSHOSTLIB_DVB_MODEM_STATE_ET,
368 valid only for DVB-T/H */ 368 valid only for DVB-T/H */
369 u32 GuardInterval; /* Guard Interval from 369 u32 GuardInterval; /* Guard Interval from
370 SMSHOSTLIB_GUARD_INTERVALS_ET, valid only for DVB-T/H */ 370 SMSHOSTLIB_GUARD_INTERVALS_ET, valid only for DVB-T/H */
371 u32 CodeRate; /* Code Rate from SMSHOSTLIB_CODE_RATE_ET, 371 u32 CodeRate; /* Code Rate from SMSHOSTLIB_CODE_RATE_ET,
372 valid only for DVB-T/H */ 372 valid only for DVB-T/H */
373 u32 LPCodeRate; /* Low Priority Code Rate from 373 u32 LPCodeRate; /* Low Priority Code Rate from
374 SMSHOSTLIB_CODE_RATE_ET, valid only for DVB-T/H */ 374 SMSHOSTLIB_CODE_RATE_ET, valid only for DVB-T/H */
375 u32 Hierarchy; /* Hierarchy from SMSHOSTLIB_HIERARCHY_ET, 375 u32 Hierarchy; /* Hierarchy from SMSHOSTLIB_HIERARCHY_ET,
376 valid only for DVB-T/H */ 376 valid only for DVB-T/H */
377 u32 Constellation; /* Constellation from 377 u32 Constellation; /* Constellation from
378 SMSHOSTLIB_CONSTELLATION_ET, valid only for DVB-T/H */ 378 SMSHOSTLIB_CONSTELLATION_ET, valid only for DVB-T/H */
379 379
380 /* Burst parameters, valid only for DVB-H */ 380 /* Burst parameters, valid only for DVB-H */
381 u32 BurstSize; /* Current burst size in bytes, 381 u32 BurstSize; /* Current burst size in bytes,
382 valid only for DVB-H */ 382 valid only for DVB-H */
383 u32 BurstDuration; /* Current burst duration in mSec, 383 u32 BurstDuration; /* Current burst duration in mSec,
384 valid only for DVB-H */ 384 valid only for DVB-H */
385 u32 BurstCycleTime; /* Current burst cycle time in mSec, 385 u32 BurstCycleTime; /* Current burst cycle time in mSec,
386 valid only for DVB-H */ 386 valid only for DVB-H */
387 u32 CalculatedBurstCycleTime;/* Current burst cycle time in mSec, 387 u32 CalculatedBurstCycleTime;/* Current burst cycle time in mSec,
388 as calculated by demodulator, valid only for DVB-H */ 388 as calculated by demodulator, valid only for DVB-H */
389 u32 NumOfRows; /* Number of rows in MPE table, 389 u32 NumOfRows; /* Number of rows in MPE table,
390 valid only for DVB-H */ 390 valid only for DVB-H */
391 u32 NumOfPaddCols; /* Number of padding columns in MPE table, 391 u32 NumOfPaddCols; /* Number of padding columns in MPE table,
392 valid only for DVB-H */ 392 valid only for DVB-H */
393 u32 NumOfPunctCols; /* Number of puncturing columns in MPE table, 393 u32 NumOfPunctCols; /* Number of puncturing columns in MPE table,
394 valid only for DVB-H */ 394 valid only for DVB-H */
395 u32 ErrorTSPackets; /* Number of erroneous 395 u32 ErrorTSPackets; /* Number of erroneous
396 transport-stream packets */ 396 transport-stream packets */
397 u32 TotalTSPackets; /* Total number of transport-stream packets */ 397 u32 TotalTSPackets; /* Total number of transport-stream packets */
398 u32 NumOfValidMpeTlbs; /* Number of MPE tables which do not include 398 u32 NumOfValidMpeTlbs; /* Number of MPE tables which do not include
399 errors after MPE RS decoding */ 399 errors after MPE RS decoding */
400 u32 NumOfInvalidMpeTlbs;/* Number of MPE tables which include errors 400 u32 NumOfInvalidMpeTlbs;/* Number of MPE tables which include errors
401 after MPE RS decoding */ 401 after MPE RS decoding */
402 u32 NumOfCorrectedMpeTlbs;/* Number of MPE tables which were 402 u32 NumOfCorrectedMpeTlbs;/* Number of MPE tables which were
403 corrected by MPE RS decoding */ 403 corrected by MPE RS decoding */
404 /* Common params */ 404 /* Common params */
405 u32 BERErrorCount; /* Number of errornous SYNC bits. */ 405 u32 BERErrorCount; /* Number of errornous SYNC bits. */
406 u32 BERBitCount; /* Total number of SYNC bits. */ 406 u32 BERBitCount; /* Total number of SYNC bits. */
407 407
408 /* Interface information */ 408 /* Interface information */
409 u32 SmsToHostTxErrors; /* Total number of transmission errors. */ 409 u32 SmsToHostTxErrors; /* Total number of transmission errors. */
410 410
411 /* DAB/T-DMB */ 411 /* DAB/T-DMB */
412 u32 PreBER; /* DAB/T-DMB only: Pre Viterbi BER [1E-5] */ 412 u32 PreBER; /* DAB/T-DMB only: Pre Viterbi BER [1E-5] */
413 413
414 /* DVB-H TPS parameters */ 414 /* DVB-H TPS parameters */
415 u32 CellId; /* TPS Cell ID in bits 15..0, bits 31..16 zero; 415 u32 CellId; /* TPS Cell ID in bits 15..0, bits 31..16 zero;
416 if set to 0xFFFFFFFF cell_id not yet recovered */ 416 if set to 0xFFFFFFFF cell_id not yet recovered */
417 u32 DvbhSrvIndHP; /* DVB-H service indication info, bit 1 - 417 u32 DvbhSrvIndHP; /* DVB-H service indication info, bit 1 -
418 Time Slicing indicator, bit 0 - MPE-FEC indicator */ 418 Time Slicing indicator, bit 0 - MPE-FEC indicator */
419 u32 DvbhSrvIndLP; /* DVB-H service indication info, bit 1 - 419 u32 DvbhSrvIndLP; /* DVB-H service indication info, bit 1 -
420 Time Slicing indicator, bit 0 - MPE-FEC indicator */ 420 Time Slicing indicator, bit 0 - MPE-FEC indicator */
421 421
422 u32 NumMPEReceived; /* DVB-H, Num MPE section received */ 422 u32 NumMPEReceived; /* DVB-H, Num MPE section received */
423 423
424 u32 ReservedFields[10]; /* Reserved */ 424 u32 ReservedFields[10]; /* Reserved */
425 }; 425 };
426 426
427 struct PID_STATISTICS_DATA_S { 427 struct PID_STATISTICS_DATA_S {
428 struct PID_BURST_S { 428 struct PID_BURST_S {
429 u32 size; 429 u32 size;
430 u32 padding_cols; 430 u32 padding_cols;
431 u32 punct_cols; 431 u32 punct_cols;
432 u32 duration; 432 u32 duration;
433 u32 cycle; 433 u32 cycle;
434 u32 calc_cycle; 434 u32 calc_cycle;
435 } burst; 435 } burst;
436 436
437 u32 tot_tbl_cnt; 437 u32 tot_tbl_cnt;
438 u32 invalid_tbl_cnt; 438 u32 invalid_tbl_cnt;
439 u32 tot_cor_tbl; 439 u32 tot_cor_tbl;
440 }; 440 };
441 441
442 struct PID_DATA_S { 442 struct PID_DATA_S {
443 u32 pid; 443 u32 pid;
444 u32 num_rows; 444 u32 num_rows;
445 struct PID_STATISTICS_DATA_S pid_statistics; 445 struct PID_STATISTICS_DATA_S pid_statistics;
446 }; 446 };
447 447
448 #define CORRECT_STAT_RSSI(_stat) ((_stat).RSSI *= -1) 448 #define CORRECT_STAT_RSSI(_stat) ((_stat).RSSI *= -1)
449 #define CORRECT_STAT_BANDWIDTH(_stat) (_stat.Bandwidth = 8 - _stat.Bandwidth) 449 #define CORRECT_STAT_BANDWIDTH(_stat) (_stat.Bandwidth = 8 - _stat.Bandwidth)
450 #define CORRECT_STAT_TRANSMISSON_MODE(_stat) \ 450 #define CORRECT_STAT_TRANSMISSON_MODE(_stat) \
451 if (_stat.TransmissionMode == 0) \ 451 if (_stat.TransmissionMode == 0) \
452 _stat.TransmissionMode = 2; \ 452 _stat.TransmissionMode = 2; \
453 else if (_stat.TransmissionMode == 1) \ 453 else if (_stat.TransmissionMode == 1) \
454 _stat.TransmissionMode = 8; \ 454 _stat.TransmissionMode = 8; \
455 else \ 455 else \
456 _stat.TransmissionMode = 4; 456 _stat.TransmissionMode = 4;
457 457
458 struct TRANSMISSION_STATISTICS_S { 458 struct TRANSMISSION_STATISTICS_S {
459 u32 Frequency; /* Frequency in Hz */ 459 u32 Frequency; /* Frequency in Hz */
460 u32 Bandwidth; /* Bandwidth in MHz */ 460 u32 Bandwidth; /* Bandwidth in MHz */
461 u32 TransmissionMode; /* FFT mode carriers in Kilos */ 461 u32 TransmissionMode; /* FFT mode carriers in Kilos */
462 u32 GuardInterval; /* Guard Interval from 462 u32 GuardInterval; /* Guard Interval from
463 SMSHOSTLIB_GUARD_INTERVALS_ET */ 463 SMSHOSTLIB_GUARD_INTERVALS_ET */
464 u32 CodeRate; /* Code Rate from SMSHOSTLIB_CODE_RATE_ET */ 464 u32 CodeRate; /* Code Rate from SMSHOSTLIB_CODE_RATE_ET */
465 u32 LPCodeRate; /* Low Priority Code Rate from 465 u32 LPCodeRate; /* Low Priority Code Rate from
466 SMSHOSTLIB_CODE_RATE_ET */ 466 SMSHOSTLIB_CODE_RATE_ET */
467 u32 Hierarchy; /* Hierarchy from SMSHOSTLIB_HIERARCHY_ET */ 467 u32 Hierarchy; /* Hierarchy from SMSHOSTLIB_HIERARCHY_ET */
468 u32 Constellation; /* Constellation from 468 u32 Constellation; /* Constellation from
469 SMSHOSTLIB_CONSTELLATION_ET */ 469 SMSHOSTLIB_CONSTELLATION_ET */
470 470
471 /* DVB-H TPS parameters */ 471 /* DVB-H TPS parameters */
472 u32 CellId; /* TPS Cell ID in bits 15..0, bits 31..16 zero; 472 u32 CellId; /* TPS Cell ID in bits 15..0, bits 31..16 zero;
473 if set to 0xFFFFFFFF cell_id not yet recovered */ 473 if set to 0xFFFFFFFF cell_id not yet recovered */
474 u32 DvbhSrvIndHP; /* DVB-H service indication info, bit 1 - 474 u32 DvbhSrvIndHP; /* DVB-H service indication info, bit 1 -
475 Time Slicing indicator, bit 0 - MPE-FEC indicator */ 475 Time Slicing indicator, bit 0 - MPE-FEC indicator */
476 u32 DvbhSrvIndLP; /* DVB-H service indication info, bit 1 - 476 u32 DvbhSrvIndLP; /* DVB-H service indication info, bit 1 -
477 Time Slicing indicator, bit 0 - MPE-FEC indicator */ 477 Time Slicing indicator, bit 0 - MPE-FEC indicator */
478 u32 IsDemodLocked; /* 0 - not locked, 1 - locked */ 478 u32 IsDemodLocked; /* 0 - not locked, 1 - locked */
479 }; 479 };
480 480
481 struct RECEPTION_STATISTICS_S { 481 struct RECEPTION_STATISTICS_S {
482 u32 IsRfLocked; /* 0 - not locked, 1 - locked */ 482 u32 IsRfLocked; /* 0 - not locked, 1 - locked */
483 u32 IsDemodLocked; /* 0 - not locked, 1 - locked */ 483 u32 IsDemodLocked; /* 0 - not locked, 1 - locked */
484 u32 IsExternalLNAOn; /* 0 - external LNA off, 1 - external LNA on */ 484 u32 IsExternalLNAOn; /* 0 - external LNA off, 1 - external LNA on */
485 485
486 u32 ModemState; /* from SMSHOSTLIB_DVB_MODEM_STATE_ET */ 486 u32 ModemState; /* from SMSHOSTLIB_DVB_MODEM_STATE_ET */
487 s32 SNR; /* dB */ 487 s32 SNR; /* dB */
488 u32 BER; /* Post Viterbi BER [1E-5] */ 488 u32 BER; /* Post Viterbi BER [1E-5] */
489 u32 BERErrorCount; /* Number of erronous SYNC bits. */ 489 u32 BERErrorCount; /* Number of erronous SYNC bits. */
490 u32 BERBitCount; /* Total number of SYNC bits. */ 490 u32 BERBitCount; /* Total number of SYNC bits. */
491 u32 TS_PER; /* Transport stream PER, 491 u32 TS_PER; /* Transport stream PER,
492 0xFFFFFFFF indicate N/A */ 492 0xFFFFFFFF indicate N/A */
493 u32 MFER; /* DVB-H frame error rate in percentage, 493 u32 MFER; /* DVB-H frame error rate in percentage,
494 0xFFFFFFFF indicate N/A, valid only for DVB-H */ 494 0xFFFFFFFF indicate N/A, valid only for DVB-H */
495 s32 RSSI; /* dBm */ 495 s32 RSSI; /* dBm */
496 s32 InBandPwr; /* In band power in dBM */ 496 s32 InBandPwr; /* In band power in dBM */
497 s32 CarrierOffset; /* Carrier Offset in bin/1024 */ 497 s32 CarrierOffset; /* Carrier Offset in bin/1024 */
498 u32 ErrorTSPackets; /* Number of erroneous 498 u32 ErrorTSPackets; /* Number of erroneous
499 transport-stream packets */ 499 transport-stream packets */
500 u32 TotalTSPackets; /* Total number of transport-stream packets */ 500 u32 TotalTSPackets; /* Total number of transport-stream packets */
501 501
502 s32 MRC_SNR; /* dB */ 502 s32 MRC_SNR; /* dB */
503 s32 MRC_RSSI; /* dBm */ 503 s32 MRC_RSSI; /* dBm */
504 s32 MRC_InBandPwr; /* In band power in dBM */ 504 s32 MRC_InBandPwr; /* In band power in dBM */
505 }; 505 };
506 506
507 507
508 /* Statistics information returned as response for 508 /* Statistics information returned as response for
509 * SmsHostApiGetStatisticsEx_Req for DVB applications, SMS1100 and up */ 509 * SmsHostApiGetStatisticsEx_Req for DVB applications, SMS1100 and up */
510 struct SMSHOSTLIB_STATISTICS_DVB_S { 510 struct SMSHOSTLIB_STATISTICS_DVB_S {
511 /* Reception */ 511 /* Reception */
512 struct RECEPTION_STATISTICS_S ReceptionData; 512 struct RECEPTION_STATISTICS_S ReceptionData;
513 513
514 /* Transmission parameters */ 514 /* Transmission parameters */
515 struct TRANSMISSION_STATISTICS_S TransmissionData; 515 struct TRANSMISSION_STATISTICS_S TransmissionData;
516 516
517 /* Burst parameters, valid only for DVB-H */ 517 /* Burst parameters, valid only for DVB-H */
518 #define SRVM_MAX_PID_FILTERS 8 518 #define SRVM_MAX_PID_FILTERS 8
519 struct PID_DATA_S PidData[SRVM_MAX_PID_FILTERS]; 519 struct PID_DATA_S PidData[SRVM_MAX_PID_FILTERS];
520 }; 520 };
521 521
522 struct SRVM_SIGNAL_STATUS_S { 522 struct SRVM_SIGNAL_STATUS_S {
523 u32 result; 523 u32 result;
524 u32 snr; 524 u32 snr;
525 u32 tsPackets; 525 u32 tsPackets;
526 u32 etsPackets; 526 u32 etsPackets;
527 u32 constellation; 527 u32 constellation;
528 u32 hpCode; 528 u32 hpCode;
529 u32 tpsSrvIndLP; 529 u32 tpsSrvIndLP;
530 u32 tpsSrvIndHP; 530 u32 tpsSrvIndHP;
531 u32 cellId; 531 u32 cellId;
532 u32 reason; 532 u32 reason;
533 533
534 s32 inBandPower; 534 s32 inBandPower;
535 u32 requestId; 535 u32 requestId;
536 }; 536 };
537 537
538 struct SMSHOSTLIB_I2C_REQ_ST { 538 struct SMSHOSTLIB_I2C_REQ_ST {
539 u32 DeviceAddress; /* I2c device address */ 539 u32 DeviceAddress; /* I2c device address */
540 u32 WriteCount; /* number of bytes to write */ 540 u32 WriteCount; /* number of bytes to write */
541 u32 ReadCount; /* number of bytes to read */ 541 u32 ReadCount; /* number of bytes to read */
542 u8 Data[1]; 542 u8 Data[1];
543 }; 543 };
544 544
545 struct SMSHOSTLIB_I2C_RES_ST { 545 struct SMSHOSTLIB_I2C_RES_ST {
546 u32 Status; /* non-zero value in case of failure */ 546 u32 Status; /* non-zero value in case of failure */
547 u32 ReadCount; /* number of bytes read */ 547 u32 ReadCount; /* number of bytes read */
548 u8 Data[1]; 548 u8 Data[1];
549 }; 549 };
550 550
551 551
552 struct smscore_config_gpio { 552 struct smscore_config_gpio {
553 #define SMS_GPIO_DIRECTION_INPUT 0 553 #define SMS_GPIO_DIRECTION_INPUT 0
554 #define SMS_GPIO_DIRECTION_OUTPUT 1 554 #define SMS_GPIO_DIRECTION_OUTPUT 1
555 u8 direction; 555 u8 direction;
556 556
557 #define SMS_GPIO_PULLUPDOWN_NONE 0 557 #define SMS_GPIO_PULLUPDOWN_NONE 0
558 #define SMS_GPIO_PULLUPDOWN_PULLDOWN 1 558 #define SMS_GPIO_PULLUPDOWN_PULLDOWN 1
559 #define SMS_GPIO_PULLUPDOWN_PULLUP 2 559 #define SMS_GPIO_PULLUPDOWN_PULLUP 2
560 #define SMS_GPIO_PULLUPDOWN_KEEPER 3 560 #define SMS_GPIO_PULLUPDOWN_KEEPER 3
561 u8 pullupdown; 561 u8 pullupdown;
562 562
563 #define SMS_GPIO_INPUTCHARACTERISTICS_NORMAL 0 563 #define SMS_GPIO_INPUTCHARACTERISTICS_NORMAL 0
564 #define SMS_GPIO_INPUTCHARACTERISTICS_SCHMITT 1 564 #define SMS_GPIO_INPUTCHARACTERISTICS_SCHMITT 1
565 u8 inputcharacteristics; 565 u8 inputcharacteristics;
566 566
567 #define SMS_GPIO_OUTPUTSLEWRATE_FAST 0 567 #define SMS_GPIO_OUTPUTSLEWRATE_FAST 0
568 #define SMS_GPIO_OUTPUTSLEWRATE_SLOW 1 568 #define SMS_GPIO_OUTPUTSLEWRATE_SLOW 1
569 u8 outputslewrate; 569 u8 outputslewrate;
570 570
571 #define SMS_GPIO_OUTPUTDRIVING_4mA 0 571 #define SMS_GPIO_OUTPUTDRIVING_4mA 0
572 #define SMS_GPIO_OUTPUTDRIVING_8mA 1 572 #define SMS_GPIO_OUTPUTDRIVING_8mA 1
573 #define SMS_GPIO_OUTPUTDRIVING_12mA 2 573 #define SMS_GPIO_OUTPUTDRIVING_12mA 2
574 #define SMS_GPIO_OUTPUTDRIVING_16mA 3 574 #define SMS_GPIO_OUTPUTDRIVING_16mA 3
575 u8 outputdriving; 575 u8 outputdriving;
576 }; 576 };
577 577
578 struct smscore_gpio_config { 578 struct smscore_gpio_config {
579 #define SMS_GPIO_DIRECTION_INPUT 0 579 #define SMS_GPIO_DIRECTION_INPUT 0
580 #define SMS_GPIO_DIRECTION_OUTPUT 1 580 #define SMS_GPIO_DIRECTION_OUTPUT 1
581 u8 Direction; 581 u8 Direction;
582 582
583 #define SMS_GPIO_PULL_UP_DOWN_NONE 0 583 #define SMS_GPIO_PULL_UP_DOWN_NONE 0
584 #define SMS_GPIO_PULL_UP_DOWN_PULLDOWN 1 584 #define SMS_GPIO_PULL_UP_DOWN_PULLDOWN 1
585 #define SMS_GPIO_PULL_UP_DOWN_PULLUP 2 585 #define SMS_GPIO_PULL_UP_DOWN_PULLUP 2
586 #define SMS_GPIO_PULL_UP_DOWN_KEEPER 3 586 #define SMS_GPIO_PULL_UP_DOWN_KEEPER 3
587 u8 PullUpDown; 587 u8 PullUpDown;
588 588
589 #define SMS_GPIO_INPUT_CHARACTERISTICS_NORMAL 0 589 #define SMS_GPIO_INPUT_CHARACTERISTICS_NORMAL 0
590 #define SMS_GPIO_INPUT_CHARACTERISTICS_SCHMITT 1 590 #define SMS_GPIO_INPUT_CHARACTERISTICS_SCHMITT 1
591 u8 InputCharacteristics; 591 u8 InputCharacteristics;
592 592
593 #define SMS_GPIO_OUTPUT_SLEW_RATE_SLOW 1 /* 10xx */ 593 #define SMS_GPIO_OUTPUT_SLEW_RATE_SLOW 1 /* 10xx */
594 #define SMS_GPIO_OUTPUT_SLEW_RATE_FAST 0 /* 10xx */ 594 #define SMS_GPIO_OUTPUT_SLEW_RATE_FAST 0 /* 10xx */
595 595
596 596
597 #define SMS_GPIO_OUTPUT_SLEW_RATE_0_45_V_NS 0 /* 11xx */ 597 #define SMS_GPIO_OUTPUT_SLEW_RATE_0_45_V_NS 0 /* 11xx */
598 #define SMS_GPIO_OUTPUT_SLEW_RATE_0_9_V_NS 1 /* 11xx */ 598 #define SMS_GPIO_OUTPUT_SLEW_RATE_0_9_V_NS 1 /* 11xx */
599 #define SMS_GPIO_OUTPUT_SLEW_RATE_1_7_V_NS 2 /* 11xx */ 599 #define SMS_GPIO_OUTPUT_SLEW_RATE_1_7_V_NS 2 /* 11xx */
600 #define SMS_GPIO_OUTPUT_SLEW_RATE_3_3_V_NS 3 /* 11xx */ 600 #define SMS_GPIO_OUTPUT_SLEW_RATE_3_3_V_NS 3 /* 11xx */
601 u8 OutputSlewRate; 601 u8 OutputSlewRate;
602 602
603 #define SMS_GPIO_OUTPUT_DRIVING_S_4mA 0 /* 10xx */ 603 #define SMS_GPIO_OUTPUT_DRIVING_S_4mA 0 /* 10xx */
604 #define SMS_GPIO_OUTPUT_DRIVING_S_8mA 1 /* 10xx */ 604 #define SMS_GPIO_OUTPUT_DRIVING_S_8mA 1 /* 10xx */
605 #define SMS_GPIO_OUTPUT_DRIVING_S_12mA 2 /* 10xx */ 605 #define SMS_GPIO_OUTPUT_DRIVING_S_12mA 2 /* 10xx */
606 #define SMS_GPIO_OUTPUT_DRIVING_S_16mA 3 /* 10xx */ 606 #define SMS_GPIO_OUTPUT_DRIVING_S_16mA 3 /* 10xx */
607 607
608 #define SMS_GPIO_OUTPUT_DRIVING_1_5mA 0 /* 11xx */ 608 #define SMS_GPIO_OUTPUT_DRIVING_1_5mA 0 /* 11xx */
609 #define SMS_GPIO_OUTPUT_DRIVING_2_8mA 1 /* 11xx */ 609 #define SMS_GPIO_OUTPUT_DRIVING_2_8mA 1 /* 11xx */
610 #define SMS_GPIO_OUTPUT_DRIVING_4mA 2 /* 11xx */ 610 #define SMS_GPIO_OUTPUT_DRIVING_4mA 2 /* 11xx */
611 #define SMS_GPIO_OUTPUT_DRIVING_7mA 3 /* 11xx */ 611 #define SMS_GPIO_OUTPUT_DRIVING_7mA 3 /* 11xx */
612 #define SMS_GPIO_OUTPUT_DRIVING_10mA 4 /* 11xx */ 612 #define SMS_GPIO_OUTPUT_DRIVING_10mA 4 /* 11xx */
613 #define SMS_GPIO_OUTPUT_DRIVING_11mA 5 /* 11xx */ 613 #define SMS_GPIO_OUTPUT_DRIVING_11mA 5 /* 11xx */
614 #define SMS_GPIO_OUTPUT_DRIVING_14mA 6 /* 11xx */ 614 #define SMS_GPIO_OUTPUT_DRIVING_14mA 6 /* 11xx */
615 #define SMS_GPIO_OUTPUT_DRIVING_16mA 7 /* 11xx */ 615 #define SMS_GPIO_OUTPUT_DRIVING_16mA 7 /* 11xx */
616 u8 OutputDriving; 616 u8 OutputDriving;
617 }; 617 };
618 618
619 extern void smscore_registry_setmode(char *devpath, int mode); 619 extern void smscore_registry_setmode(char *devpath, int mode);
620 extern int smscore_registry_getmode(char *devpath); 620 extern int smscore_registry_getmode(char *devpath);
621 621
622 extern int smscore_register_hotplug(hotplug_t hotplug); 622 extern int smscore_register_hotplug(hotplug_t hotplug);
623 extern void smscore_unregister_hotplug(hotplug_t hotplug); 623 extern void smscore_unregister_hotplug(hotplug_t hotplug);
624 624
625 extern int smscore_register_device(struct smsdevice_params_t *params, 625 extern int smscore_register_device(struct smsdevice_params_t *params,
626 struct smscore_device_t **coredev); 626 struct smscore_device_t **coredev);
627 extern void smscore_unregister_device(struct smscore_device_t *coredev); 627 extern void smscore_unregister_device(struct smscore_device_t *coredev);
628 628
629 extern int smscore_start_device(struct smscore_device_t *coredev); 629 extern int smscore_start_device(struct smscore_device_t *coredev);
630 extern int smscore_load_firmware(struct smscore_device_t *coredev, 630 extern int smscore_load_firmware(struct smscore_device_t *coredev,
631 char *filename, 631 char *filename,
632 loadfirmware_t loadfirmware_handler); 632 loadfirmware_t loadfirmware_handler);
633 633
634 extern int smscore_set_device_mode(struct smscore_device_t *coredev, int mode); 634 extern int smscore_set_device_mode(struct smscore_device_t *coredev, int mode);
635 extern int smscore_get_device_mode(struct smscore_device_t *coredev); 635 extern int smscore_get_device_mode(struct smscore_device_t *coredev);
636 636
637 extern int smscore_register_client(struct smscore_device_t *coredev, 637 extern int smscore_register_client(struct smscore_device_t *coredev,
638 struct smsclient_params_t *params, 638 struct smsclient_params_t *params,
639 struct smscore_client_t **client); 639 struct smscore_client_t **client);
640 extern void smscore_unregister_client(struct smscore_client_t *client); 640 extern void smscore_unregister_client(struct smscore_client_t *client);
641 641
642 extern int smsclient_sendrequest(struct smscore_client_t *client, 642 extern int smsclient_sendrequest(struct smscore_client_t *client,
643 void *buffer, size_t size); 643 void *buffer, size_t size);
644 extern void smscore_onresponse(struct smscore_device_t *coredev, 644 extern void smscore_onresponse(struct smscore_device_t *coredev,
645 struct smscore_buffer_t *cb); 645 struct smscore_buffer_t *cb);
646 646
647 extern int smscore_get_common_buffer_size(struct smscore_device_t *coredev); 647 extern int smscore_get_common_buffer_size(struct smscore_device_t *coredev);
648 extern int smscore_map_common_buffer(struct smscore_device_t *coredev, 648 extern int smscore_map_common_buffer(struct smscore_device_t *coredev,
649 struct vm_area_struct *vma); 649 struct vm_area_struct *vma);
650 extern int smscore_get_fw_filename(struct smscore_device_t *coredev, 650 extern int smscore_get_fw_filename(struct smscore_device_t *coredev,
651 int mode, char *filename); 651 int mode, char *filename);
652 extern int smscore_send_fw_file(struct smscore_device_t *coredev, 652 extern int smscore_send_fw_file(struct smscore_device_t *coredev,
653 u8 *ufwbuf, int size); 653 u8 *ufwbuf, int size);
654 654
655 extern 655 extern
656 struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev); 656 struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev);
657 extern void smscore_putbuffer(struct smscore_device_t *coredev, 657 extern void smscore_putbuffer(struct smscore_device_t *coredev,
658 struct smscore_buffer_t *cb); 658 struct smscore_buffer_t *cb);
659 659
660 /* old GPIO managment */ 660 /* old GPIO management */
661 int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin, 661 int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin,
662 struct smscore_config_gpio *pinconfig); 662 struct smscore_config_gpio *pinconfig);
663 int smscore_set_gpio(struct smscore_device_t *coredev, u32 pin, int level); 663 int smscore_set_gpio(struct smscore_device_t *coredev, u32 pin, int level);
664 664
665 /* new GPIO managment */ 665 /* new GPIO management */
666 extern int smscore_gpio_configure(struct smscore_device_t *coredev, u8 PinNum, 666 extern int smscore_gpio_configure(struct smscore_device_t *coredev, u8 PinNum,
667 struct smscore_gpio_config *pGpioConfig); 667 struct smscore_gpio_config *pGpioConfig);
668 extern int smscore_gpio_set_level(struct smscore_device_t *coredev, u8 PinNum, 668 extern int smscore_gpio_set_level(struct smscore_device_t *coredev, u8 PinNum,
669 u8 NewLevel); 669 u8 NewLevel);
670 extern int smscore_gpio_get_level(struct smscore_device_t *coredev, u8 PinNum, 670 extern int smscore_gpio_get_level(struct smscore_device_t *coredev, u8 PinNum,
671 u8 *level); 671 u8 *level);
672 672
673 void smscore_set_board_id(struct smscore_device_t *core, int id); 673 void smscore_set_board_id(struct smscore_device_t *core, int id);
674 int smscore_get_board_id(struct smscore_device_t *core); 674 int smscore_get_board_id(struct smscore_device_t *core);
675 675
676 int smscore_led_state(struct smscore_device_t *core, int led); 676 int smscore_led_state(struct smscore_device_t *core, int led);
677 677
678 678
679 /* ------------------------------------------------------------------------ */ 679 /* ------------------------------------------------------------------------ */
680 680
681 #define DBG_INFO 1 681 #define DBG_INFO 1
682 #define DBG_ADV 2 682 #define DBG_ADV 2
683 683
684 #define sms_printk(kern, fmt, arg...) \ 684 #define sms_printk(kern, fmt, arg...) \
685 printk(kern "%s: " fmt "\n", __func__, ##arg) 685 printk(kern "%s: " fmt "\n", __func__, ##arg)
686 686
687 #define dprintk(kern, lvl, fmt, arg...) do {\ 687 #define dprintk(kern, lvl, fmt, arg...) do {\
688 if (sms_dbg & lvl) \ 688 if (sms_dbg & lvl) \
689 sms_printk(kern, fmt, ##arg); } while (0) 689 sms_printk(kern, fmt, ##arg); } while (0)
690 690
691 #define sms_log(fmt, arg...) sms_printk(KERN_INFO, fmt, ##arg) 691 #define sms_log(fmt, arg...) sms_printk(KERN_INFO, fmt, ##arg)
692 #define sms_err(fmt, arg...) \ 692 #define sms_err(fmt, arg...) \
693 sms_printk(KERN_ERR, "line: %d: " fmt, __LINE__, ##arg) 693 sms_printk(KERN_ERR, "line: %d: " fmt, __LINE__, ##arg)
694 #define sms_warn(fmt, arg...) sms_printk(KERN_WARNING, fmt, ##arg) 694 #define sms_warn(fmt, arg...) sms_printk(KERN_WARNING, fmt, ##arg)
695 #define sms_info(fmt, arg...) \ 695 #define sms_info(fmt, arg...) \
696 dprintk(KERN_INFO, DBG_INFO, fmt, ##arg) 696 dprintk(KERN_INFO, DBG_INFO, fmt, ##arg)
697 #define sms_debug(fmt, arg...) \ 697 #define sms_debug(fmt, arg...) \
698 dprintk(KERN_DEBUG, DBG_ADV, fmt, ##arg) 698 dprintk(KERN_DEBUG, DBG_ADV, fmt, ##arg)
699 699
700 700
701 #endif /* __SMS_CORE_API_H__ */ 701 #endif /* __SMS_CORE_API_H__ */
702 702
drivers/media/radio/radio-mr800.c
1 /* 1 /*
2 * A driver for the AverMedia MR 800 USB FM radio. This device plugs 2 * A driver for the AverMedia MR 800 USB FM radio. This device plugs
3 * into both the USB and an analog audio input, so this thing 3 * into both the USB and an analog audio input, so this thing
4 * only deals with initialization and frequency setting, the 4 * only deals with initialization and frequency setting, the
5 * audio data has to be handled by a sound driver. 5 * audio data has to be handled by a sound driver.
6 * 6 *
7 * Copyright (c) 2008 Alexey Klimov <klimov.linux@gmail.com> 7 * Copyright (c) 2008 Alexey Klimov <klimov.linux@gmail.com>
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by 10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or 11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version. 12 * (at your option) any later version.
13 * 13 *
14 * This program is distributed in the hope that it will be useful, 14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details. 17 * GNU General Public License for more details.
18 * 18 *
19 * You should have received a copy of the GNU General Public License 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 20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */ 22 */
23 23
24 /* 24 /*
25 * Big thanks to authors and contributors of dsbr100.c and radio-si470x.c 25 * Big thanks to authors and contributors of dsbr100.c and radio-si470x.c
26 * 26 *
27 * When work was looked pretty good, i discover this: 27 * When work was looked pretty good, i discover this:
28 * http://av-usbradio.sourceforge.net/index.php 28 * http://av-usbradio.sourceforge.net/index.php
29 * http://sourceforge.net/projects/av-usbradio/ 29 * http://sourceforge.net/projects/av-usbradio/
30 * Latest release of theirs project was in 2005. 30 * Latest release of theirs project was in 2005.
31 * Probably, this driver could be improved trough using their 31 * Probably, this driver could be improved trough using their
32 * achievements (specifications given). 32 * achievements (specifications given).
33 * Also, Faidon Liambotis <paravoid@debian.org> wrote nice driver for this radio 33 * Also, Faidon Liambotis <paravoid@debian.org> wrote nice driver for this radio
34 * in 2007. He allowed to use his driver to improve current mr800 radio driver. 34 * in 2007. He allowed to use his driver to improve current mr800 radio driver.
35 * http://kerneltrap.org/mailarchive/linux-usb-devel/2007/10/11/342492 35 * http://kerneltrap.org/mailarchive/linux-usb-devel/2007/10/11/342492
36 * 36 *
37 * Version 0.01: First working version. 37 * Version 0.01: First working version.
38 * It's required to blacklist AverMedia USB Radio 38 * It's required to blacklist AverMedia USB Radio
39 * in usbhid/hid-quirks.c 39 * in usbhid/hid-quirks.c
40 * Version 0.10: A lot of cleanups and fixes: unpluging the device, 40 * Version 0.10: A lot of cleanups and fixes: unpluging the device,
41 * few mutex locks were added, codinstyle issues, etc. 41 * few mutex locks were added, codinstyle issues, etc.
42 * Added stereo support. Thanks to 42 * Added stereo support. Thanks to
43 * Douglas Schilling Landgraf <dougsland@gmail.com> and 43 * Douglas Schilling Landgraf <dougsland@gmail.com> and
44 * David Ellingsworth <david@identd.dyndns.org> 44 * David Ellingsworth <david@identd.dyndns.org>
45 * for discussion, help and support. 45 * for discussion, help and support.
46 * Version 0.11: Converted to v4l2_device. 46 * Version 0.11: Converted to v4l2_device.
47 * 47 *
48 * Many things to do: 48 * Many things to do:
49 * - Correct power managment of device (suspend & resume) 49 * - Correct power management of device (suspend & resume)
50 * - Add code for scanning and smooth tuning 50 * - Add code for scanning and smooth tuning
51 * - Add code for sensitivity value 51 * - Add code for sensitivity value
52 * - Correct mistakes 52 * - Correct mistakes
53 * - In Japan another FREQ_MIN and FREQ_MAX 53 * - In Japan another FREQ_MIN and FREQ_MAX
54 */ 54 */
55 55
56 /* kernel includes */ 56 /* kernel includes */
57 #include <linux/kernel.h> 57 #include <linux/kernel.h>
58 #include <linux/module.h> 58 #include <linux/module.h>
59 #include <linux/init.h> 59 #include <linux/init.h>
60 #include <linux/slab.h> 60 #include <linux/slab.h>
61 #include <linux/smp_lock.h> 61 #include <linux/smp_lock.h>
62 #include <linux/input.h> 62 #include <linux/input.h>
63 #include <linux/videodev2.h> 63 #include <linux/videodev2.h>
64 #include <media/v4l2-device.h> 64 #include <media/v4l2-device.h>
65 #include <media/v4l2-ioctl.h> 65 #include <media/v4l2-ioctl.h>
66 #include <linux/usb.h> 66 #include <linux/usb.h>
67 #include <linux/version.h> /* for KERNEL_VERSION MACRO */ 67 #include <linux/version.h> /* for KERNEL_VERSION MACRO */
68 #include <linux/mutex.h> 68 #include <linux/mutex.h>
69 69
70 /* driver and module definitions */ 70 /* driver and module definitions */
71 #define DRIVER_AUTHOR "Alexey Klimov <klimov.linux@gmail.com>" 71 #define DRIVER_AUTHOR "Alexey Klimov <klimov.linux@gmail.com>"
72 #define DRIVER_DESC "AverMedia MR 800 USB FM radio driver" 72 #define DRIVER_DESC "AverMedia MR 800 USB FM radio driver"
73 #define DRIVER_VERSION "0.11" 73 #define DRIVER_VERSION "0.11"
74 #define RADIO_VERSION KERNEL_VERSION(0, 1, 1) 74 #define RADIO_VERSION KERNEL_VERSION(0, 1, 1)
75 75
76 MODULE_AUTHOR(DRIVER_AUTHOR); 76 MODULE_AUTHOR(DRIVER_AUTHOR);
77 MODULE_DESCRIPTION(DRIVER_DESC); 77 MODULE_DESCRIPTION(DRIVER_DESC);
78 MODULE_LICENSE("GPL"); 78 MODULE_LICENSE("GPL");
79 79
80 #define USB_AMRADIO_VENDOR 0x07ca 80 #define USB_AMRADIO_VENDOR 0x07ca
81 #define USB_AMRADIO_PRODUCT 0xb800 81 #define USB_AMRADIO_PRODUCT 0xb800
82 82
83 /* dev_warn macro with driver name */ 83 /* dev_warn macro with driver name */
84 #define MR800_DRIVER_NAME "radio-mr800" 84 #define MR800_DRIVER_NAME "radio-mr800"
85 #define amradio_dev_warn(dev, fmt, arg...) \ 85 #define amradio_dev_warn(dev, fmt, arg...) \
86 dev_warn(dev, MR800_DRIVER_NAME " - " fmt, ##arg) 86 dev_warn(dev, MR800_DRIVER_NAME " - " fmt, ##arg)
87 87
88 /* Probably USB_TIMEOUT should be modified in module parameter */ 88 /* Probably USB_TIMEOUT should be modified in module parameter */
89 #define BUFFER_LENGTH 8 89 #define BUFFER_LENGTH 8
90 #define USB_TIMEOUT 500 90 #define USB_TIMEOUT 500
91 91
92 /* Frequency limits in MHz -- these are European values. For Japanese 92 /* Frequency limits in MHz -- these are European values. For Japanese
93 devices, that would be 76 and 91. */ 93 devices, that would be 76 and 91. */
94 #define FREQ_MIN 87.5 94 #define FREQ_MIN 87.5
95 #define FREQ_MAX 108.0 95 #define FREQ_MAX 108.0
96 #define FREQ_MUL 16000 96 #define FREQ_MUL 16000
97 97
98 /* 98 /*
99 * Commands that device should understand 99 * Commands that device should understand
100 * List isnt full and will be updated with implementation of new functions 100 * List isnt full and will be updated with implementation of new functions
101 */ 101 */
102 #define AMRADIO_SET_FREQ 0xa4 102 #define AMRADIO_SET_FREQ 0xa4
103 #define AMRADIO_SET_MUTE 0xab 103 #define AMRADIO_SET_MUTE 0xab
104 #define AMRADIO_SET_MONO 0xae 104 #define AMRADIO_SET_MONO 0xae
105 105
106 /* Comfortable defines for amradio_set_mute */ 106 /* Comfortable defines for amradio_set_mute */
107 #define AMRADIO_START 0x00 107 #define AMRADIO_START 0x00
108 #define AMRADIO_STOP 0x01 108 #define AMRADIO_STOP 0x01
109 109
110 /* Comfortable defines for amradio_set_stereo */ 110 /* Comfortable defines for amradio_set_stereo */
111 #define WANT_STEREO 0x00 111 #define WANT_STEREO 0x00
112 #define WANT_MONO 0x01 112 #define WANT_MONO 0x01
113 113
114 /* module parameter */ 114 /* module parameter */
115 static int radio_nr = -1; 115 static int radio_nr = -1;
116 module_param(radio_nr, int, 0); 116 module_param(radio_nr, int, 0);
117 MODULE_PARM_DESC(radio_nr, "Radio Nr"); 117 MODULE_PARM_DESC(radio_nr, "Radio Nr");
118 118
119 static int usb_amradio_probe(struct usb_interface *intf, 119 static int usb_amradio_probe(struct usb_interface *intf,
120 const struct usb_device_id *id); 120 const struct usb_device_id *id);
121 static void usb_amradio_disconnect(struct usb_interface *intf); 121 static void usb_amradio_disconnect(struct usb_interface *intf);
122 static int usb_amradio_open(struct file *file); 122 static int usb_amradio_open(struct file *file);
123 static int usb_amradio_close(struct file *file); 123 static int usb_amradio_close(struct file *file);
124 static int usb_amradio_suspend(struct usb_interface *intf, 124 static int usb_amradio_suspend(struct usb_interface *intf,
125 pm_message_t message); 125 pm_message_t message);
126 static int usb_amradio_resume(struct usb_interface *intf); 126 static int usb_amradio_resume(struct usb_interface *intf);
127 127
128 /* Data for one (physical) device */ 128 /* Data for one (physical) device */
129 struct amradio_device { 129 struct amradio_device {
130 /* reference to USB and video device */ 130 /* reference to USB and video device */
131 struct usb_device *usbdev; 131 struct usb_device *usbdev;
132 struct video_device *videodev; 132 struct video_device *videodev;
133 struct v4l2_device v4l2_dev; 133 struct v4l2_device v4l2_dev;
134 134
135 unsigned char *buffer; 135 unsigned char *buffer;
136 struct mutex lock; /* buffer locking */ 136 struct mutex lock; /* buffer locking */
137 int curfreq; 137 int curfreq;
138 int stereo; 138 int stereo;
139 int users; 139 int users;
140 int removed; 140 int removed;
141 int muted; 141 int muted;
142 }; 142 };
143 143
144 /* USB Device ID List */ 144 /* USB Device ID List */
145 static struct usb_device_id usb_amradio_device_table[] = { 145 static struct usb_device_id usb_amradio_device_table[] = {
146 {USB_DEVICE_AND_INTERFACE_INFO(USB_AMRADIO_VENDOR, USB_AMRADIO_PRODUCT, 146 {USB_DEVICE_AND_INTERFACE_INFO(USB_AMRADIO_VENDOR, USB_AMRADIO_PRODUCT,
147 USB_CLASS_HID, 0, 0) }, 147 USB_CLASS_HID, 0, 0) },
148 { } /* Terminating entry */ 148 { } /* Terminating entry */
149 }; 149 };
150 150
151 MODULE_DEVICE_TABLE(usb, usb_amradio_device_table); 151 MODULE_DEVICE_TABLE(usb, usb_amradio_device_table);
152 152
153 /* USB subsystem interface */ 153 /* USB subsystem interface */
154 static struct usb_driver usb_amradio_driver = { 154 static struct usb_driver usb_amradio_driver = {
155 .name = MR800_DRIVER_NAME, 155 .name = MR800_DRIVER_NAME,
156 .probe = usb_amradio_probe, 156 .probe = usb_amradio_probe,
157 .disconnect = usb_amradio_disconnect, 157 .disconnect = usb_amradio_disconnect,
158 .suspend = usb_amradio_suspend, 158 .suspend = usb_amradio_suspend,
159 .resume = usb_amradio_resume, 159 .resume = usb_amradio_resume,
160 .reset_resume = usb_amradio_resume, 160 .reset_resume = usb_amradio_resume,
161 .id_table = usb_amradio_device_table, 161 .id_table = usb_amradio_device_table,
162 .supports_autosuspend = 0, 162 .supports_autosuspend = 0,
163 }; 163 };
164 164
165 /* switch on/off the radio. Send 8 bytes to device */ 165 /* switch on/off the radio. Send 8 bytes to device */
166 static int amradio_set_mute(struct amradio_device *radio, char argument) 166 static int amradio_set_mute(struct amradio_device *radio, char argument)
167 { 167 {
168 int retval; 168 int retval;
169 int size; 169 int size;
170 170
171 /* safety check */ 171 /* safety check */
172 if (radio->removed) 172 if (radio->removed)
173 return -EIO; 173 return -EIO;
174 174
175 mutex_lock(&radio->lock); 175 mutex_lock(&radio->lock);
176 176
177 radio->buffer[0] = 0x00; 177 radio->buffer[0] = 0x00;
178 radio->buffer[1] = 0x55; 178 radio->buffer[1] = 0x55;
179 radio->buffer[2] = 0xaa; 179 radio->buffer[2] = 0xaa;
180 radio->buffer[3] = 0x00; 180 radio->buffer[3] = 0x00;
181 radio->buffer[4] = AMRADIO_SET_MUTE; 181 radio->buffer[4] = AMRADIO_SET_MUTE;
182 radio->buffer[5] = argument; 182 radio->buffer[5] = argument;
183 radio->buffer[6] = 0x00; 183 radio->buffer[6] = 0x00;
184 radio->buffer[7] = 0x00; 184 radio->buffer[7] = 0x00;
185 185
186 retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2), 186 retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2),
187 (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT); 187 (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT);
188 188
189 if (retval < 0 || size != BUFFER_LENGTH) { 189 if (retval < 0 || size != BUFFER_LENGTH) {
190 mutex_unlock(&radio->lock); 190 mutex_unlock(&radio->lock);
191 return retval; 191 return retval;
192 } 192 }
193 193
194 radio->muted = argument; 194 radio->muted = argument;
195 195
196 mutex_unlock(&radio->lock); 196 mutex_unlock(&radio->lock);
197 197
198 return retval; 198 return retval;
199 } 199 }
200 200
201 /* set a frequency, freq is defined by v4l's TUNER_LOW, i.e. 1/16th kHz */ 201 /* set a frequency, freq is defined by v4l's TUNER_LOW, i.e. 1/16th kHz */
202 static int amradio_setfreq(struct amradio_device *radio, int freq) 202 static int amradio_setfreq(struct amradio_device *radio, int freq)
203 { 203 {
204 int retval; 204 int retval;
205 int size; 205 int size;
206 unsigned short freq_send = 0x10 + (freq >> 3) / 25; 206 unsigned short freq_send = 0x10 + (freq >> 3) / 25;
207 207
208 /* safety check */ 208 /* safety check */
209 if (radio->removed) 209 if (radio->removed)
210 return -EIO; 210 return -EIO;
211 211
212 mutex_lock(&radio->lock); 212 mutex_lock(&radio->lock);
213 213
214 radio->buffer[0] = 0x00; 214 radio->buffer[0] = 0x00;
215 radio->buffer[1] = 0x55; 215 radio->buffer[1] = 0x55;
216 radio->buffer[2] = 0xaa; 216 radio->buffer[2] = 0xaa;
217 radio->buffer[3] = 0x03; 217 radio->buffer[3] = 0x03;
218 radio->buffer[4] = AMRADIO_SET_FREQ; 218 radio->buffer[4] = AMRADIO_SET_FREQ;
219 radio->buffer[5] = 0x00; 219 radio->buffer[5] = 0x00;
220 radio->buffer[6] = 0x00; 220 radio->buffer[6] = 0x00;
221 radio->buffer[7] = 0x08; 221 radio->buffer[7] = 0x08;
222 222
223 retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2), 223 retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2),
224 (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT); 224 (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT);
225 225
226 if (retval < 0 || size != BUFFER_LENGTH) { 226 if (retval < 0 || size != BUFFER_LENGTH) {
227 mutex_unlock(&radio->lock); 227 mutex_unlock(&radio->lock);
228 return retval; 228 return retval;
229 } 229 }
230 230
231 /* frequency is calculated from freq_send and placed in first 2 bytes */ 231 /* frequency is calculated from freq_send and placed in first 2 bytes */
232 radio->buffer[0] = (freq_send >> 8) & 0xff; 232 radio->buffer[0] = (freq_send >> 8) & 0xff;
233 radio->buffer[1] = freq_send & 0xff; 233 radio->buffer[1] = freq_send & 0xff;
234 radio->buffer[2] = 0x01; 234 radio->buffer[2] = 0x01;
235 radio->buffer[3] = 0x00; 235 radio->buffer[3] = 0x00;
236 radio->buffer[4] = 0x00; 236 radio->buffer[4] = 0x00;
237 /* 5 and 6 bytes of buffer already = 0x00 */ 237 /* 5 and 6 bytes of buffer already = 0x00 */
238 radio->buffer[7] = 0x00; 238 radio->buffer[7] = 0x00;
239 239
240 retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2), 240 retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2),
241 (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT); 241 (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT);
242 242
243 if (retval < 0 || size != BUFFER_LENGTH) { 243 if (retval < 0 || size != BUFFER_LENGTH) {
244 mutex_unlock(&radio->lock); 244 mutex_unlock(&radio->lock);
245 return retval; 245 return retval;
246 } 246 }
247 247
248 mutex_unlock(&radio->lock); 248 mutex_unlock(&radio->lock);
249 249
250 return retval; 250 return retval;
251 } 251 }
252 252
253 static int amradio_set_stereo(struct amradio_device *radio, char argument) 253 static int amradio_set_stereo(struct amradio_device *radio, char argument)
254 { 254 {
255 int retval; 255 int retval;
256 int size; 256 int size;
257 257
258 /* safety check */ 258 /* safety check */
259 if (radio->removed) 259 if (radio->removed)
260 return -EIO; 260 return -EIO;
261 261
262 mutex_lock(&radio->lock); 262 mutex_lock(&radio->lock);
263 263
264 radio->buffer[0] = 0x00; 264 radio->buffer[0] = 0x00;
265 radio->buffer[1] = 0x55; 265 radio->buffer[1] = 0x55;
266 radio->buffer[2] = 0xaa; 266 radio->buffer[2] = 0xaa;
267 radio->buffer[3] = 0x00; 267 radio->buffer[3] = 0x00;
268 radio->buffer[4] = AMRADIO_SET_MONO; 268 radio->buffer[4] = AMRADIO_SET_MONO;
269 radio->buffer[5] = argument; 269 radio->buffer[5] = argument;
270 radio->buffer[6] = 0x00; 270 radio->buffer[6] = 0x00;
271 radio->buffer[7] = 0x00; 271 radio->buffer[7] = 0x00;
272 272
273 retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2), 273 retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2),
274 (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT); 274 (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT);
275 275
276 if (retval < 0 || size != BUFFER_LENGTH) { 276 if (retval < 0 || size != BUFFER_LENGTH) {
277 radio->stereo = -1; 277 radio->stereo = -1;
278 mutex_unlock(&radio->lock); 278 mutex_unlock(&radio->lock);
279 return retval; 279 return retval;
280 } 280 }
281 281
282 radio->stereo = 1; 282 radio->stereo = 1;
283 283
284 mutex_unlock(&radio->lock); 284 mutex_unlock(&radio->lock);
285 285
286 return retval; 286 return retval;
287 } 287 }
288 288
289 /* Handle unplugging the device. 289 /* Handle unplugging the device.
290 * We call video_unregister_device in any case. 290 * We call video_unregister_device in any case.
291 * The last function called in this procedure is 291 * The last function called in this procedure is
292 * usb_amradio_device_release. 292 * usb_amradio_device_release.
293 */ 293 */
294 static void usb_amradio_disconnect(struct usb_interface *intf) 294 static void usb_amradio_disconnect(struct usb_interface *intf)
295 { 295 {
296 struct amradio_device *radio = usb_get_intfdata(intf); 296 struct amradio_device *radio = usb_get_intfdata(intf);
297 297
298 mutex_lock(&radio->lock); 298 mutex_lock(&radio->lock);
299 radio->removed = 1; 299 radio->removed = 1;
300 mutex_unlock(&radio->lock); 300 mutex_unlock(&radio->lock);
301 301
302 usb_set_intfdata(intf, NULL); 302 usb_set_intfdata(intf, NULL);
303 video_unregister_device(radio->videodev); 303 video_unregister_device(radio->videodev);
304 v4l2_device_disconnect(&radio->v4l2_dev); 304 v4l2_device_disconnect(&radio->v4l2_dev);
305 } 305 }
306 306
307 /* vidioc_querycap - query device capabilities */ 307 /* vidioc_querycap - query device capabilities */
308 static int vidioc_querycap(struct file *file, void *priv, 308 static int vidioc_querycap(struct file *file, void *priv,
309 struct v4l2_capability *v) 309 struct v4l2_capability *v)
310 { 310 {
311 struct amradio_device *radio = video_drvdata(file); 311 struct amradio_device *radio = video_drvdata(file);
312 312
313 strlcpy(v->driver, "radio-mr800", sizeof(v->driver)); 313 strlcpy(v->driver, "radio-mr800", sizeof(v->driver));
314 strlcpy(v->card, "AverMedia MR 800 USB FM Radio", sizeof(v->card)); 314 strlcpy(v->card, "AverMedia MR 800 USB FM Radio", sizeof(v->card));
315 usb_make_path(radio->usbdev, v->bus_info, sizeof(v->bus_info)); 315 usb_make_path(radio->usbdev, v->bus_info, sizeof(v->bus_info));
316 v->version = RADIO_VERSION; 316 v->version = RADIO_VERSION;
317 v->capabilities = V4L2_CAP_TUNER; 317 v->capabilities = V4L2_CAP_TUNER;
318 return 0; 318 return 0;
319 } 319 }
320 320
321 /* vidioc_g_tuner - get tuner attributes */ 321 /* vidioc_g_tuner - get tuner attributes */
322 static int vidioc_g_tuner(struct file *file, void *priv, 322 static int vidioc_g_tuner(struct file *file, void *priv,
323 struct v4l2_tuner *v) 323 struct v4l2_tuner *v)
324 { 324 {
325 struct amradio_device *radio = video_get_drvdata(video_devdata(file)); 325 struct amradio_device *radio = video_get_drvdata(video_devdata(file));
326 int retval; 326 int retval;
327 327
328 /* safety check */ 328 /* safety check */
329 if (radio->removed) 329 if (radio->removed)
330 return -EIO; 330 return -EIO;
331 331
332 if (v->index > 0) 332 if (v->index > 0)
333 return -EINVAL; 333 return -EINVAL;
334 334
335 /* TODO: Add function which look is signal stereo or not 335 /* TODO: Add function which look is signal stereo or not
336 * amradio_getstat(radio); 336 * amradio_getstat(radio);
337 */ 337 */
338 338
339 /* we call amradio_set_stereo to set radio->stereo 339 /* we call amradio_set_stereo to set radio->stereo
340 * Honestly, amradio_getstat should cover this in future and 340 * Honestly, amradio_getstat should cover this in future and
341 * amradio_set_stereo shouldn't be here 341 * amradio_set_stereo shouldn't be here
342 */ 342 */
343 retval = amradio_set_stereo(radio, WANT_STEREO); 343 retval = amradio_set_stereo(radio, WANT_STEREO);
344 if (retval < 0) 344 if (retval < 0)
345 amradio_dev_warn(&radio->videodev->dev, 345 amradio_dev_warn(&radio->videodev->dev,
346 "set stereo failed\n"); 346 "set stereo failed\n");
347 347
348 strcpy(v->name, "FM"); 348 strcpy(v->name, "FM");
349 v->type = V4L2_TUNER_RADIO; 349 v->type = V4L2_TUNER_RADIO;
350 v->rangelow = FREQ_MIN * FREQ_MUL; 350 v->rangelow = FREQ_MIN * FREQ_MUL;
351 v->rangehigh = FREQ_MAX * FREQ_MUL; 351 v->rangehigh = FREQ_MAX * FREQ_MUL;
352 v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; 352 v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
353 v->capability = V4L2_TUNER_CAP_LOW; 353 v->capability = V4L2_TUNER_CAP_LOW;
354 if (radio->stereo) 354 if (radio->stereo)
355 v->audmode = V4L2_TUNER_MODE_STEREO; 355 v->audmode = V4L2_TUNER_MODE_STEREO;
356 else 356 else
357 v->audmode = V4L2_TUNER_MODE_MONO; 357 v->audmode = V4L2_TUNER_MODE_MONO;
358 v->signal = 0xffff; /* Can't get the signal strength, sad.. */ 358 v->signal = 0xffff; /* Can't get the signal strength, sad.. */
359 v->afc = 0; /* Don't know what is this */ 359 v->afc = 0; /* Don't know what is this */
360 return 0; 360 return 0;
361 } 361 }
362 362
363 /* vidioc_s_tuner - set tuner attributes */ 363 /* vidioc_s_tuner - set tuner attributes */
364 static int vidioc_s_tuner(struct file *file, void *priv, 364 static int vidioc_s_tuner(struct file *file, void *priv,
365 struct v4l2_tuner *v) 365 struct v4l2_tuner *v)
366 { 366 {
367 struct amradio_device *radio = video_get_drvdata(video_devdata(file)); 367 struct amradio_device *radio = video_get_drvdata(video_devdata(file));
368 int retval; 368 int retval;
369 369
370 /* safety check */ 370 /* safety check */
371 if (radio->removed) 371 if (radio->removed)
372 return -EIO; 372 return -EIO;
373 373
374 if (v->index > 0) 374 if (v->index > 0)
375 return -EINVAL; 375 return -EINVAL;
376 376
377 /* mono/stereo selector */ 377 /* mono/stereo selector */
378 switch (v->audmode) { 378 switch (v->audmode) {
379 case V4L2_TUNER_MODE_MONO: 379 case V4L2_TUNER_MODE_MONO:
380 retval = amradio_set_stereo(radio, WANT_MONO); 380 retval = amradio_set_stereo(radio, WANT_MONO);
381 if (retval < 0) 381 if (retval < 0)
382 amradio_dev_warn(&radio->videodev->dev, 382 amradio_dev_warn(&radio->videodev->dev,
383 "set mono failed\n"); 383 "set mono failed\n");
384 break; 384 break;
385 case V4L2_TUNER_MODE_STEREO: 385 case V4L2_TUNER_MODE_STEREO:
386 retval = amradio_set_stereo(radio, WANT_STEREO); 386 retval = amradio_set_stereo(radio, WANT_STEREO);
387 if (retval < 0) 387 if (retval < 0)
388 amradio_dev_warn(&radio->videodev->dev, 388 amradio_dev_warn(&radio->videodev->dev,
389 "set stereo failed\n"); 389 "set stereo failed\n");
390 break; 390 break;
391 default: 391 default:
392 return -EINVAL; 392 return -EINVAL;
393 } 393 }
394 394
395 return 0; 395 return 0;
396 } 396 }
397 397
398 /* vidioc_s_frequency - set tuner radio frequency */ 398 /* vidioc_s_frequency - set tuner radio frequency */
399 static int vidioc_s_frequency(struct file *file, void *priv, 399 static int vidioc_s_frequency(struct file *file, void *priv,
400 struct v4l2_frequency *f) 400 struct v4l2_frequency *f)
401 { 401 {
402 struct amradio_device *radio = video_get_drvdata(video_devdata(file)); 402 struct amradio_device *radio = video_get_drvdata(video_devdata(file));
403 int retval; 403 int retval;
404 404
405 /* safety check */ 405 /* safety check */
406 if (radio->removed) 406 if (radio->removed)
407 return -EIO; 407 return -EIO;
408 408
409 mutex_lock(&radio->lock); 409 mutex_lock(&radio->lock);
410 radio->curfreq = f->frequency; 410 radio->curfreq = f->frequency;
411 mutex_unlock(&radio->lock); 411 mutex_unlock(&radio->lock);
412 412
413 retval = amradio_setfreq(radio, radio->curfreq); 413 retval = amradio_setfreq(radio, radio->curfreq);
414 if (retval < 0) 414 if (retval < 0)
415 amradio_dev_warn(&radio->videodev->dev, 415 amradio_dev_warn(&radio->videodev->dev,
416 "set frequency failed\n"); 416 "set frequency failed\n");
417 return 0; 417 return 0;
418 } 418 }
419 419
420 /* vidioc_g_frequency - get tuner radio frequency */ 420 /* vidioc_g_frequency - get tuner radio frequency */
421 static int vidioc_g_frequency(struct file *file, void *priv, 421 static int vidioc_g_frequency(struct file *file, void *priv,
422 struct v4l2_frequency *f) 422 struct v4l2_frequency *f)
423 { 423 {
424 struct amradio_device *radio = video_get_drvdata(video_devdata(file)); 424 struct amradio_device *radio = video_get_drvdata(video_devdata(file));
425 425
426 /* safety check */ 426 /* safety check */
427 if (radio->removed) 427 if (radio->removed)
428 return -EIO; 428 return -EIO;
429 429
430 f->type = V4L2_TUNER_RADIO; 430 f->type = V4L2_TUNER_RADIO;
431 f->frequency = radio->curfreq; 431 f->frequency = radio->curfreq;
432 return 0; 432 return 0;
433 } 433 }
434 434
435 /* vidioc_queryctrl - enumerate control items */ 435 /* vidioc_queryctrl - enumerate control items */
436 static int vidioc_queryctrl(struct file *file, void *priv, 436 static int vidioc_queryctrl(struct file *file, void *priv,
437 struct v4l2_queryctrl *qc) 437 struct v4l2_queryctrl *qc)
438 { 438 {
439 switch (qc->id) { 439 switch (qc->id) {
440 case V4L2_CID_AUDIO_MUTE: 440 case V4L2_CID_AUDIO_MUTE:
441 return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1); 441 return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
442 } 442 }
443 443
444 return -EINVAL; 444 return -EINVAL;
445 } 445 }
446 446
447 /* vidioc_g_ctrl - get the value of a control */ 447 /* vidioc_g_ctrl - get the value of a control */
448 static int vidioc_g_ctrl(struct file *file, void *priv, 448 static int vidioc_g_ctrl(struct file *file, void *priv,
449 struct v4l2_control *ctrl) 449 struct v4l2_control *ctrl)
450 { 450 {
451 struct amradio_device *radio = video_get_drvdata(video_devdata(file)); 451 struct amradio_device *radio = video_get_drvdata(video_devdata(file));
452 452
453 /* safety check */ 453 /* safety check */
454 if (radio->removed) 454 if (radio->removed)
455 return -EIO; 455 return -EIO;
456 456
457 switch (ctrl->id) { 457 switch (ctrl->id) {
458 case V4L2_CID_AUDIO_MUTE: 458 case V4L2_CID_AUDIO_MUTE:
459 ctrl->value = radio->muted; 459 ctrl->value = radio->muted;
460 return 0; 460 return 0;
461 } 461 }
462 return -EINVAL; 462 return -EINVAL;
463 } 463 }
464 464
465 /* vidioc_s_ctrl - set the value of a control */ 465 /* vidioc_s_ctrl - set the value of a control */
466 static int vidioc_s_ctrl(struct file *file, void *priv, 466 static int vidioc_s_ctrl(struct file *file, void *priv,
467 struct v4l2_control *ctrl) 467 struct v4l2_control *ctrl)
468 { 468 {
469 struct amradio_device *radio = video_get_drvdata(video_devdata(file)); 469 struct amradio_device *radio = video_get_drvdata(video_devdata(file));
470 int retval; 470 int retval;
471 471
472 /* safety check */ 472 /* safety check */
473 if (radio->removed) 473 if (radio->removed)
474 return -EIO; 474 return -EIO;
475 475
476 switch (ctrl->id) { 476 switch (ctrl->id) {
477 case V4L2_CID_AUDIO_MUTE: 477 case V4L2_CID_AUDIO_MUTE:
478 if (ctrl->value) { 478 if (ctrl->value) {
479 retval = amradio_set_mute(radio, AMRADIO_STOP); 479 retval = amradio_set_mute(radio, AMRADIO_STOP);
480 if (retval < 0) { 480 if (retval < 0) {
481 amradio_dev_warn(&radio->videodev->dev, 481 amradio_dev_warn(&radio->videodev->dev,
482 "amradio_stop failed\n"); 482 "amradio_stop failed\n");
483 return -1; 483 return -1;
484 } 484 }
485 } else { 485 } else {
486 retval = amradio_set_mute(radio, AMRADIO_START); 486 retval = amradio_set_mute(radio, AMRADIO_START);
487 if (retval < 0) { 487 if (retval < 0) {
488 amradio_dev_warn(&radio->videodev->dev, 488 amradio_dev_warn(&radio->videodev->dev,
489 "amradio_start failed\n"); 489 "amradio_start failed\n");
490 return -1; 490 return -1;
491 } 491 }
492 } 492 }
493 return 0; 493 return 0;
494 } 494 }
495 return -EINVAL; 495 return -EINVAL;
496 } 496 }
497 497
498 /* vidioc_g_audio - get audio attributes */ 498 /* vidioc_g_audio - get audio attributes */
499 static int vidioc_g_audio(struct file *file, void *priv, 499 static int vidioc_g_audio(struct file *file, void *priv,
500 struct v4l2_audio *a) 500 struct v4l2_audio *a)
501 { 501 {
502 if (a->index > 1) 502 if (a->index > 1)
503 return -EINVAL; 503 return -EINVAL;
504 504
505 strcpy(a->name, "Radio"); 505 strcpy(a->name, "Radio");
506 a->capability = V4L2_AUDCAP_STEREO; 506 a->capability = V4L2_AUDCAP_STEREO;
507 return 0; 507 return 0;
508 } 508 }
509 509
510 /* vidioc_s_audio - set audio attributes */ 510 /* vidioc_s_audio - set audio attributes */
511 static int vidioc_s_audio(struct file *file, void *priv, 511 static int vidioc_s_audio(struct file *file, void *priv,
512 struct v4l2_audio *a) 512 struct v4l2_audio *a)
513 { 513 {
514 if (a->index != 0) 514 if (a->index != 0)
515 return -EINVAL; 515 return -EINVAL;
516 return 0; 516 return 0;
517 } 517 }
518 518
519 /* vidioc_g_input - get input */ 519 /* vidioc_g_input - get input */
520 static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i) 520 static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
521 { 521 {
522 *i = 0; 522 *i = 0;
523 return 0; 523 return 0;
524 } 524 }
525 525
526 /* vidioc_s_input - set input */ 526 /* vidioc_s_input - set input */
527 static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) 527 static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
528 { 528 {
529 if (i != 0) 529 if (i != 0)
530 return -EINVAL; 530 return -EINVAL;
531 return 0; 531 return 0;
532 } 532 }
533 533
534 /* open device - amradio_start() and amradio_setfreq() */ 534 /* open device - amradio_start() and amradio_setfreq() */
535 static int usb_amradio_open(struct file *file) 535 static int usb_amradio_open(struct file *file)
536 { 536 {
537 struct amradio_device *radio = video_get_drvdata(video_devdata(file)); 537 struct amradio_device *radio = video_get_drvdata(video_devdata(file));
538 int retval; 538 int retval;
539 539
540 lock_kernel(); 540 lock_kernel();
541 541
542 radio->users = 1; 542 radio->users = 1;
543 radio->muted = 1; 543 radio->muted = 1;
544 544
545 retval = amradio_set_mute(radio, AMRADIO_START); 545 retval = amradio_set_mute(radio, AMRADIO_START);
546 if (retval < 0) { 546 if (retval < 0) {
547 amradio_dev_warn(&radio->videodev->dev, 547 amradio_dev_warn(&radio->videodev->dev,
548 "radio did not start up properly\n"); 548 "radio did not start up properly\n");
549 radio->users = 0; 549 radio->users = 0;
550 unlock_kernel(); 550 unlock_kernel();
551 return -EIO; 551 return -EIO;
552 } 552 }
553 553
554 retval = amradio_set_stereo(radio, WANT_STEREO); 554 retval = amradio_set_stereo(radio, WANT_STEREO);
555 if (retval < 0) 555 if (retval < 0)
556 amradio_dev_warn(&radio->videodev->dev, 556 amradio_dev_warn(&radio->videodev->dev,
557 "set stereo failed\n"); 557 "set stereo failed\n");
558 558
559 retval = amradio_setfreq(radio, radio->curfreq); 559 retval = amradio_setfreq(radio, radio->curfreq);
560 if (retval < 0) 560 if (retval < 0)
561 amradio_dev_warn(&radio->videodev->dev, 561 amradio_dev_warn(&radio->videodev->dev,
562 "set frequency failed\n"); 562 "set frequency failed\n");
563 563
564 unlock_kernel(); 564 unlock_kernel();
565 return 0; 565 return 0;
566 } 566 }
567 567
568 /*close device */ 568 /*close device */
569 static int usb_amradio_close(struct file *file) 569 static int usb_amradio_close(struct file *file)
570 { 570 {
571 struct amradio_device *radio = video_get_drvdata(video_devdata(file)); 571 struct amradio_device *radio = video_get_drvdata(video_devdata(file));
572 int retval; 572 int retval;
573 573
574 if (!radio) 574 if (!radio)
575 return -ENODEV; 575 return -ENODEV;
576 576
577 mutex_lock(&radio->lock); 577 mutex_lock(&radio->lock);
578 radio->users = 0; 578 radio->users = 0;
579 mutex_unlock(&radio->lock); 579 mutex_unlock(&radio->lock);
580 580
581 if (!radio->removed) { 581 if (!radio->removed) {
582 retval = amradio_set_mute(radio, AMRADIO_STOP); 582 retval = amradio_set_mute(radio, AMRADIO_STOP);
583 if (retval < 0) 583 if (retval < 0)
584 amradio_dev_warn(&radio->videodev->dev, 584 amradio_dev_warn(&radio->videodev->dev,
585 "amradio_stop failed\n"); 585 "amradio_stop failed\n");
586 } 586 }
587 587
588 return 0; 588 return 0;
589 } 589 }
590 590
591 /* Suspend device - stop device. Need to be checked and fixed */ 591 /* Suspend device - stop device. Need to be checked and fixed */
592 static int usb_amradio_suspend(struct usb_interface *intf, pm_message_t message) 592 static int usb_amradio_suspend(struct usb_interface *intf, pm_message_t message)
593 { 593 {
594 struct amradio_device *radio = usb_get_intfdata(intf); 594 struct amradio_device *radio = usb_get_intfdata(intf);
595 int retval; 595 int retval;
596 596
597 retval = amradio_set_mute(radio, AMRADIO_STOP); 597 retval = amradio_set_mute(radio, AMRADIO_STOP);
598 if (retval < 0) 598 if (retval < 0)
599 dev_warn(&intf->dev, "amradio_stop failed\n"); 599 dev_warn(&intf->dev, "amradio_stop failed\n");
600 600
601 dev_info(&intf->dev, "going into suspend..\n"); 601 dev_info(&intf->dev, "going into suspend..\n");
602 602
603 return 0; 603 return 0;
604 } 604 }
605 605
606 /* Resume device - start device. Need to be checked and fixed */ 606 /* Resume device - start device. Need to be checked and fixed */
607 static int usb_amradio_resume(struct usb_interface *intf) 607 static int usb_amradio_resume(struct usb_interface *intf)
608 { 608 {
609 struct amradio_device *radio = usb_get_intfdata(intf); 609 struct amradio_device *radio = usb_get_intfdata(intf);
610 int retval; 610 int retval;
611 611
612 retval = amradio_set_mute(radio, AMRADIO_START); 612 retval = amradio_set_mute(radio, AMRADIO_START);
613 if (retval < 0) 613 if (retval < 0)
614 dev_warn(&intf->dev, "amradio_start failed\n"); 614 dev_warn(&intf->dev, "amradio_start failed\n");
615 615
616 dev_info(&intf->dev, "coming out of suspend..\n"); 616 dev_info(&intf->dev, "coming out of suspend..\n");
617 617
618 return 0; 618 return 0;
619 } 619 }
620 620
621 /* File system interface */ 621 /* File system interface */
622 static const struct v4l2_file_operations usb_amradio_fops = { 622 static const struct v4l2_file_operations usb_amradio_fops = {
623 .owner = THIS_MODULE, 623 .owner = THIS_MODULE,
624 .open = usb_amradio_open, 624 .open = usb_amradio_open,
625 .release = usb_amradio_close, 625 .release = usb_amradio_close,
626 .ioctl = video_ioctl2, 626 .ioctl = video_ioctl2,
627 }; 627 };
628 628
629 static const struct v4l2_ioctl_ops usb_amradio_ioctl_ops = { 629 static const struct v4l2_ioctl_ops usb_amradio_ioctl_ops = {
630 .vidioc_querycap = vidioc_querycap, 630 .vidioc_querycap = vidioc_querycap,
631 .vidioc_g_tuner = vidioc_g_tuner, 631 .vidioc_g_tuner = vidioc_g_tuner,
632 .vidioc_s_tuner = vidioc_s_tuner, 632 .vidioc_s_tuner = vidioc_s_tuner,
633 .vidioc_g_frequency = vidioc_g_frequency, 633 .vidioc_g_frequency = vidioc_g_frequency,
634 .vidioc_s_frequency = vidioc_s_frequency, 634 .vidioc_s_frequency = vidioc_s_frequency,
635 .vidioc_queryctrl = vidioc_queryctrl, 635 .vidioc_queryctrl = vidioc_queryctrl,
636 .vidioc_g_ctrl = vidioc_g_ctrl, 636 .vidioc_g_ctrl = vidioc_g_ctrl,
637 .vidioc_s_ctrl = vidioc_s_ctrl, 637 .vidioc_s_ctrl = vidioc_s_ctrl,
638 .vidioc_g_audio = vidioc_g_audio, 638 .vidioc_g_audio = vidioc_g_audio,
639 .vidioc_s_audio = vidioc_s_audio, 639 .vidioc_s_audio = vidioc_s_audio,
640 .vidioc_g_input = vidioc_g_input, 640 .vidioc_g_input = vidioc_g_input,
641 .vidioc_s_input = vidioc_s_input, 641 .vidioc_s_input = vidioc_s_input,
642 }; 642 };
643 643
644 static void usb_amradio_video_device_release(struct video_device *videodev) 644 static void usb_amradio_video_device_release(struct video_device *videodev)
645 { 645 {
646 struct amradio_device *radio = video_get_drvdata(videodev); 646 struct amradio_device *radio = video_get_drvdata(videodev);
647 647
648 /* we call v4l to free radio->videodev */ 648 /* we call v4l to free radio->videodev */
649 video_device_release(videodev); 649 video_device_release(videodev);
650 650
651 v4l2_device_unregister(&radio->v4l2_dev); 651 v4l2_device_unregister(&radio->v4l2_dev);
652 652
653 /* free rest memory */ 653 /* free rest memory */
654 kfree(radio->buffer); 654 kfree(radio->buffer);
655 kfree(radio); 655 kfree(radio);
656 } 656 }
657 657
658 /* check if the device is present and register with v4l and usb if it is */ 658 /* check if the device is present and register with v4l and usb if it is */
659 static int usb_amradio_probe(struct usb_interface *intf, 659 static int usb_amradio_probe(struct usb_interface *intf,
660 const struct usb_device_id *id) 660 const struct usb_device_id *id)
661 { 661 {
662 struct amradio_device *radio; 662 struct amradio_device *radio;
663 struct v4l2_device *v4l2_dev; 663 struct v4l2_device *v4l2_dev;
664 int retval; 664 int retval;
665 665
666 radio = kzalloc(sizeof(struct amradio_device), GFP_KERNEL); 666 radio = kzalloc(sizeof(struct amradio_device), GFP_KERNEL);
667 667
668 if (!radio) { 668 if (!radio) {
669 dev_err(&intf->dev, "kmalloc for amradio_device failed\n"); 669 dev_err(&intf->dev, "kmalloc for amradio_device failed\n");
670 return -ENOMEM; 670 return -ENOMEM;
671 } 671 }
672 672
673 radio->buffer = kmalloc(BUFFER_LENGTH, GFP_KERNEL); 673 radio->buffer = kmalloc(BUFFER_LENGTH, GFP_KERNEL);
674 674
675 if (!radio->buffer) { 675 if (!radio->buffer) {
676 dev_err(&intf->dev, "kmalloc for radio->buffer failed\n"); 676 dev_err(&intf->dev, "kmalloc for radio->buffer failed\n");
677 kfree(radio); 677 kfree(radio);
678 return -ENOMEM; 678 return -ENOMEM;
679 } 679 }
680 680
681 v4l2_dev = &radio->v4l2_dev; 681 v4l2_dev = &radio->v4l2_dev;
682 retval = v4l2_device_register(&intf->dev, v4l2_dev); 682 retval = v4l2_device_register(&intf->dev, v4l2_dev);
683 if (retval < 0) { 683 if (retval < 0) {
684 dev_err(&intf->dev, "couldn't register v4l2_device\n"); 684 dev_err(&intf->dev, "couldn't register v4l2_device\n");
685 kfree(radio->buffer); 685 kfree(radio->buffer);
686 kfree(radio); 686 kfree(radio);
687 return retval; 687 return retval;
688 } 688 }
689 689
690 radio->videodev = video_device_alloc(); 690 radio->videodev = video_device_alloc();
691 691
692 if (!radio->videodev) { 692 if (!radio->videodev) {
693 dev_err(&intf->dev, "video_device_alloc failed\n"); 693 dev_err(&intf->dev, "video_device_alloc failed\n");
694 kfree(radio->buffer); 694 kfree(radio->buffer);
695 kfree(radio); 695 kfree(radio);
696 return -ENOMEM; 696 return -ENOMEM;
697 } 697 }
698 698
699 strlcpy(radio->videodev->name, v4l2_dev->name, sizeof(radio->videodev->name)); 699 strlcpy(radio->videodev->name, v4l2_dev->name, sizeof(radio->videodev->name));
700 radio->videodev->v4l2_dev = v4l2_dev; 700 radio->videodev->v4l2_dev = v4l2_dev;
701 radio->videodev->fops = &usb_amradio_fops; 701 radio->videodev->fops = &usb_amradio_fops;
702 radio->videodev->ioctl_ops = &usb_amradio_ioctl_ops; 702 radio->videodev->ioctl_ops = &usb_amradio_ioctl_ops;
703 radio->videodev->release = usb_amradio_video_device_release; 703 radio->videodev->release = usb_amradio_video_device_release;
704 704
705 radio->removed = 0; 705 radio->removed = 0;
706 radio->users = 0; 706 radio->users = 0;
707 radio->usbdev = interface_to_usbdev(intf); 707 radio->usbdev = interface_to_usbdev(intf);
708 radio->curfreq = 95.16 * FREQ_MUL; 708 radio->curfreq = 95.16 * FREQ_MUL;
709 radio->stereo = -1; 709 radio->stereo = -1;
710 710
711 mutex_init(&radio->lock); 711 mutex_init(&radio->lock);
712 712
713 video_set_drvdata(radio->videodev, radio); 713 video_set_drvdata(radio->videodev, radio);
714 714
715 retval = video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr); 715 retval = video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr);
716 if (retval < 0) { 716 if (retval < 0) {
717 dev_err(&intf->dev, "could not register video device\n"); 717 dev_err(&intf->dev, "could not register video device\n");
718 video_device_release(radio->videodev); 718 video_device_release(radio->videodev);
719 v4l2_device_unregister(v4l2_dev); 719 v4l2_device_unregister(v4l2_dev);
720 kfree(radio->buffer); 720 kfree(radio->buffer);
721 kfree(radio); 721 kfree(radio);
722 return -EIO; 722 return -EIO;
723 } 723 }
724 724
725 usb_set_intfdata(intf, radio); 725 usb_set_intfdata(intf, radio);
726 return 0; 726 return 0;
727 } 727 }
728 728
729 static int __init amradio_init(void) 729 static int __init amradio_init(void)
730 { 730 {
731 int retval = usb_register(&usb_amradio_driver); 731 int retval = usb_register(&usb_amradio_driver);
732 732
733 pr_info(KBUILD_MODNAME 733 pr_info(KBUILD_MODNAME
734 ": version " DRIVER_VERSION " " DRIVER_DESC "\n"); 734 ": version " DRIVER_VERSION " " DRIVER_DESC "\n");
735 735
736 if (retval) 736 if (retval)
737 pr_err(KBUILD_MODNAME 737 pr_err(KBUILD_MODNAME
738 ": usb_register failed. Error number %d\n", retval); 738 ": usb_register failed. Error number %d\n", retval);
739 739
740 return retval; 740 return retval;
741 } 741 }
742 742
743 static void __exit amradio_exit(void) 743 static void __exit amradio_exit(void)
744 { 744 {
745 usb_deregister(&usb_amradio_driver); 745 usb_deregister(&usb_amradio_driver);
746 } 746 }
747 747
748 module_init(amradio_init); 748 module_init(amradio_init);
749 module_exit(amradio_exit); 749 module_exit(amradio_exit);
750 750
751 751
drivers/message/fusion/mptbase.c
1 /* 1 /*
2 * linux/drivers/message/fusion/mptbase.c 2 * linux/drivers/message/fusion/mptbase.c
3 * This is the Fusion MPT base driver which supports multiple 3 * This is the Fusion MPT base driver which supports multiple
4 * (SCSI + LAN) specialized protocol drivers. 4 * (SCSI + LAN) specialized protocol drivers.
5 * For use with LSI PCI chip/adapter(s) 5 * For use with LSI PCI chip/adapter(s)
6 * running LSI Fusion MPT (Message Passing Technology) firmware. 6 * running LSI Fusion MPT (Message Passing Technology) firmware.
7 * 7 *
8 * Copyright (c) 1999-2008 LSI Corporation 8 * Copyright (c) 1999-2008 LSI Corporation
9 * (mailto:DL-MPTFusionLinux@lsi.com) 9 * (mailto:DL-MPTFusionLinux@lsi.com)
10 * 10 *
11 */ 11 */
12 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 12 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
13 /* 13 /*
14 This program is free software; you can redistribute it and/or modify 14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by 15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; version 2 of the License. 16 the Free Software Foundation; version 2 of the License.
17 17
18 This program is distributed in the hope that it will be useful, 18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of 19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details. 21 GNU General Public License for more details.
22 22
23 NO WARRANTY 23 NO WARRANTY
24 THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR 24 THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
25 CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT 25 CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
26 LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, 26 LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
27 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is 27 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
28 solely responsible for determining the appropriateness of using and 28 solely responsible for determining the appropriateness of using and
29 distributing the Program and assumes all risks associated with its 29 distributing the Program and assumes all risks associated with its
30 exercise of rights under this Agreement, including but not limited to 30 exercise of rights under this Agreement, including but not limited to
31 the risks and costs of program errors, damage to or loss of data, 31 the risks and costs of program errors, damage to or loss of data,
32 programs or equipment, and unavailability or interruption of operations. 32 programs or equipment, and unavailability or interruption of operations.
33 33
34 DISCLAIMER OF LIABILITY 34 DISCLAIMER OF LIABILITY
35 NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY 35 NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
36 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND 37 DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
38 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 38 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
39 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 39 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
40 USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED 40 USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
41 HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES 41 HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
42 42
43 You should have received a copy of the GNU General Public License 43 You should have received a copy of the GNU General Public License
44 along with this program; if not, write to the Free Software 44 along with this program; if not, write to the Free Software
45 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 45 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
46 */ 46 */
47 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 47 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
48 48
49 #include <linux/kernel.h> 49 #include <linux/kernel.h>
50 #include <linux/module.h> 50 #include <linux/module.h>
51 #include <linux/errno.h> 51 #include <linux/errno.h>
52 #include <linux/init.h> 52 #include <linux/init.h>
53 #include <linux/slab.h> 53 #include <linux/slab.h>
54 #include <linux/types.h> 54 #include <linux/types.h>
55 #include <linux/pci.h> 55 #include <linux/pci.h>
56 #include <linux/kdev_t.h> 56 #include <linux/kdev_t.h>
57 #include <linux/blkdev.h> 57 #include <linux/blkdev.h>
58 #include <linux/delay.h> 58 #include <linux/delay.h>
59 #include <linux/interrupt.h> /* needed for in_interrupt() proto */ 59 #include <linux/interrupt.h> /* needed for in_interrupt() proto */
60 #include <linux/dma-mapping.h> 60 #include <linux/dma-mapping.h>
61 #include <asm/io.h> 61 #include <asm/io.h>
62 #ifdef CONFIG_MTRR 62 #ifdef CONFIG_MTRR
63 #include <asm/mtrr.h> 63 #include <asm/mtrr.h>
64 #endif 64 #endif
65 65
66 #include "mptbase.h" 66 #include "mptbase.h"
67 #include "lsi/mpi_log_fc.h" 67 #include "lsi/mpi_log_fc.h"
68 68
69 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 69 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
70 #define my_NAME "Fusion MPT base driver" 70 #define my_NAME "Fusion MPT base driver"
71 #define my_VERSION MPT_LINUX_VERSION_COMMON 71 #define my_VERSION MPT_LINUX_VERSION_COMMON
72 #define MYNAM "mptbase" 72 #define MYNAM "mptbase"
73 73
74 MODULE_AUTHOR(MODULEAUTHOR); 74 MODULE_AUTHOR(MODULEAUTHOR);
75 MODULE_DESCRIPTION(my_NAME); 75 MODULE_DESCRIPTION(my_NAME);
76 MODULE_LICENSE("GPL"); 76 MODULE_LICENSE("GPL");
77 MODULE_VERSION(my_VERSION); 77 MODULE_VERSION(my_VERSION);
78 78
79 /* 79 /*
80 * cmd line parameters 80 * cmd line parameters
81 */ 81 */
82 82
83 static int mpt_msi_enable_spi; 83 static int mpt_msi_enable_spi;
84 module_param(mpt_msi_enable_spi, int, 0); 84 module_param(mpt_msi_enable_spi, int, 0);
85 MODULE_PARM_DESC(mpt_msi_enable_spi, " Enable MSI Support for SPI \ 85 MODULE_PARM_DESC(mpt_msi_enable_spi, " Enable MSI Support for SPI \
86 controllers (default=0)"); 86 controllers (default=0)");
87 87
88 static int mpt_msi_enable_fc; 88 static int mpt_msi_enable_fc;
89 module_param(mpt_msi_enable_fc, int, 0); 89 module_param(mpt_msi_enable_fc, int, 0);
90 MODULE_PARM_DESC(mpt_msi_enable_fc, " Enable MSI Support for FC \ 90 MODULE_PARM_DESC(mpt_msi_enable_fc, " Enable MSI Support for FC \
91 controllers (default=0)"); 91 controllers (default=0)");
92 92
93 static int mpt_msi_enable_sas; 93 static int mpt_msi_enable_sas;
94 module_param(mpt_msi_enable_sas, int, 0); 94 module_param(mpt_msi_enable_sas, int, 0);
95 MODULE_PARM_DESC(mpt_msi_enable_sas, " Enable MSI Support for SAS \ 95 MODULE_PARM_DESC(mpt_msi_enable_sas, " Enable MSI Support for SAS \
96 controllers (default=0)"); 96 controllers (default=0)");
97 97
98 98
99 static int mpt_channel_mapping; 99 static int mpt_channel_mapping;
100 module_param(mpt_channel_mapping, int, 0); 100 module_param(mpt_channel_mapping, int, 0);
101 MODULE_PARM_DESC(mpt_channel_mapping, " Mapping id's to channels (default=0)"); 101 MODULE_PARM_DESC(mpt_channel_mapping, " Mapping id's to channels (default=0)");
102 102
103 static int mpt_debug_level; 103 static int mpt_debug_level;
104 static int mpt_set_debug_level(const char *val, struct kernel_param *kp); 104 static int mpt_set_debug_level(const char *val, struct kernel_param *kp);
105 module_param_call(mpt_debug_level, mpt_set_debug_level, param_get_int, 105 module_param_call(mpt_debug_level, mpt_set_debug_level, param_get_int,
106 &mpt_debug_level, 0600); 106 &mpt_debug_level, 0600);
107 MODULE_PARM_DESC(mpt_debug_level, " debug level - refer to mptdebug.h \ 107 MODULE_PARM_DESC(mpt_debug_level, " debug level - refer to mptdebug.h \
108 - (default=0)"); 108 - (default=0)");
109 109
110 int mpt_fwfault_debug; 110 int mpt_fwfault_debug;
111 EXPORT_SYMBOL(mpt_fwfault_debug); 111 EXPORT_SYMBOL(mpt_fwfault_debug);
112 module_param_call(mpt_fwfault_debug, param_set_int, param_get_int, 112 module_param_call(mpt_fwfault_debug, param_set_int, param_get_int,
113 &mpt_fwfault_debug, 0600); 113 &mpt_fwfault_debug, 0600);
114 MODULE_PARM_DESC(mpt_fwfault_debug, "Enable detection of Firmware fault" 114 MODULE_PARM_DESC(mpt_fwfault_debug, "Enable detection of Firmware fault"
115 " and halt Firmware on fault - (default=0)"); 115 " and halt Firmware on fault - (default=0)");
116 116
117 117
118 118
119 #ifdef MFCNT 119 #ifdef MFCNT
120 static int mfcounter = 0; 120 static int mfcounter = 0;
121 #define PRINT_MF_COUNT 20000 121 #define PRINT_MF_COUNT 20000
122 #endif 122 #endif
123 123
124 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 124 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
125 /* 125 /*
126 * Public data... 126 * Public data...
127 */ 127 */
128 128
129 static struct proc_dir_entry *mpt_proc_root_dir; 129 static struct proc_dir_entry *mpt_proc_root_dir;
130 130
131 #define WHOINIT_UNKNOWN 0xAA 131 #define WHOINIT_UNKNOWN 0xAA
132 132
133 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 133 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
134 /* 134 /*
135 * Private data... 135 * Private data...
136 */ 136 */
137 /* Adapter link list */ 137 /* Adapter link list */
138 LIST_HEAD(ioc_list); 138 LIST_HEAD(ioc_list);
139 /* Callback lookup table */ 139 /* Callback lookup table */
140 static MPT_CALLBACK MptCallbacks[MPT_MAX_PROTOCOL_DRIVERS]; 140 static MPT_CALLBACK MptCallbacks[MPT_MAX_PROTOCOL_DRIVERS];
141 /* Protocol driver class lookup table */ 141 /* Protocol driver class lookup table */
142 static int MptDriverClass[MPT_MAX_PROTOCOL_DRIVERS]; 142 static int MptDriverClass[MPT_MAX_PROTOCOL_DRIVERS];
143 /* Event handler lookup table */ 143 /* Event handler lookup table */
144 static MPT_EVHANDLER MptEvHandlers[MPT_MAX_PROTOCOL_DRIVERS]; 144 static MPT_EVHANDLER MptEvHandlers[MPT_MAX_PROTOCOL_DRIVERS];
145 /* Reset handler lookup table */ 145 /* Reset handler lookup table */
146 static MPT_RESETHANDLER MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS]; 146 static MPT_RESETHANDLER MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS];
147 static struct mpt_pci_driver *MptDeviceDriverHandlers[MPT_MAX_PROTOCOL_DRIVERS]; 147 static struct mpt_pci_driver *MptDeviceDriverHandlers[MPT_MAX_PROTOCOL_DRIVERS];
148 148
149 149
150 /* 150 /*
151 * Driver Callback Index's 151 * Driver Callback Index's
152 */ 152 */
153 static u8 mpt_base_index = MPT_MAX_PROTOCOL_DRIVERS; 153 static u8 mpt_base_index = MPT_MAX_PROTOCOL_DRIVERS;
154 static u8 last_drv_idx; 154 static u8 last_drv_idx;
155 155
156 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 156 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
157 /* 157 /*
158 * Forward protos... 158 * Forward protos...
159 */ 159 */
160 static irqreturn_t mpt_interrupt(int irq, void *bus_id); 160 static irqreturn_t mpt_interrupt(int irq, void *bus_id);
161 static int mptbase_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, 161 static int mptbase_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
162 MPT_FRAME_HDR *reply); 162 MPT_FRAME_HDR *reply);
163 static int mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, 163 static int mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes,
164 u32 *req, int replyBytes, u16 *u16reply, int maxwait, 164 u32 *req, int replyBytes, u16 *u16reply, int maxwait,
165 int sleepFlag); 165 int sleepFlag);
166 static int mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag); 166 static int mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag);
167 static void mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev); 167 static void mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev);
168 static void mpt_adapter_disable(MPT_ADAPTER *ioc); 168 static void mpt_adapter_disable(MPT_ADAPTER *ioc);
169 static void mpt_adapter_dispose(MPT_ADAPTER *ioc); 169 static void mpt_adapter_dispose(MPT_ADAPTER *ioc);
170 170
171 static void MptDisplayIocCapabilities(MPT_ADAPTER *ioc); 171 static void MptDisplayIocCapabilities(MPT_ADAPTER *ioc);
172 static int MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag); 172 static int MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag);
173 static int GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason); 173 static int GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason);
174 static int GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag); 174 static int GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
175 static int SendIocInit(MPT_ADAPTER *ioc, int sleepFlag); 175 static int SendIocInit(MPT_ADAPTER *ioc, int sleepFlag);
176 static int SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag); 176 static int SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
177 static int mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag); 177 static int mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag);
178 static int mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag); 178 static int mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag);
179 static int mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag); 179 static int mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
180 static int KickStart(MPT_ADAPTER *ioc, int ignore, int sleepFlag); 180 static int KickStart(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
181 static int SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag); 181 static int SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag);
182 static int PrimeIocFifos(MPT_ADAPTER *ioc); 182 static int PrimeIocFifos(MPT_ADAPTER *ioc);
183 static int WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag); 183 static int WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
184 static int WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag); 184 static int WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
185 static int WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag); 185 static int WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
186 static int GetLanConfigPages(MPT_ADAPTER *ioc); 186 static int GetLanConfigPages(MPT_ADAPTER *ioc);
187 static int GetIoUnitPage2(MPT_ADAPTER *ioc); 187 static int GetIoUnitPage2(MPT_ADAPTER *ioc);
188 int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode); 188 int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
189 static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum); 189 static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum);
190 static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum); 190 static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum);
191 static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc); 191 static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc);
192 static void mpt_read_ioc_pg_4(MPT_ADAPTER *ioc); 192 static void mpt_read_ioc_pg_4(MPT_ADAPTER *ioc);
193 static void mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc); 193 static void mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc);
194 static int SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch, 194 static int SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch,
195 int sleepFlag); 195 int sleepFlag);
196 static int SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp); 196 static int SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp);
197 static int mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag); 197 static int mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag);
198 static int mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init); 198 static int mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init);
199 199
200 #ifdef CONFIG_PROC_FS 200 #ifdef CONFIG_PROC_FS
201 static int procmpt_summary_read(char *buf, char **start, off_t offset, 201 static int procmpt_summary_read(char *buf, char **start, off_t offset,
202 int request, int *eof, void *data); 202 int request, int *eof, void *data);
203 static int procmpt_version_read(char *buf, char **start, off_t offset, 203 static int procmpt_version_read(char *buf, char **start, off_t offset,
204 int request, int *eof, void *data); 204 int request, int *eof, void *data);
205 static int procmpt_iocinfo_read(char *buf, char **start, off_t offset, 205 static int procmpt_iocinfo_read(char *buf, char **start, off_t offset,
206 int request, int *eof, void *data); 206 int request, int *eof, void *data);
207 #endif 207 #endif
208 static void mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc); 208 static void mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc);
209 209
210 static int ProcessEventNotification(MPT_ADAPTER *ioc, 210 static int ProcessEventNotification(MPT_ADAPTER *ioc,
211 EventNotificationReply_t *evReply, int *evHandlers); 211 EventNotificationReply_t *evReply, int *evHandlers);
212 static void mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf); 212 static void mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf);
213 static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info); 213 static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
214 static void mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info); 214 static void mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info);
215 static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info); 215 static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info);
216 static int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc); 216 static int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc);
217 static void mpt_inactive_raid_list_free(MPT_ADAPTER *ioc); 217 static void mpt_inactive_raid_list_free(MPT_ADAPTER *ioc);
218 218
219 /* module entry point */ 219 /* module entry point */
220 static int __init fusion_init (void); 220 static int __init fusion_init (void);
221 static void __exit fusion_exit (void); 221 static void __exit fusion_exit (void);
222 222
223 #define CHIPREG_READ32(addr) readl_relaxed(addr) 223 #define CHIPREG_READ32(addr) readl_relaxed(addr)
224 #define CHIPREG_READ32_dmasync(addr) readl(addr) 224 #define CHIPREG_READ32_dmasync(addr) readl(addr)
225 #define CHIPREG_WRITE32(addr,val) writel(val, addr) 225 #define CHIPREG_WRITE32(addr,val) writel(val, addr)
226 #define CHIPREG_PIO_WRITE32(addr,val) outl(val, (unsigned long)addr) 226 #define CHIPREG_PIO_WRITE32(addr,val) outl(val, (unsigned long)addr)
227 #define CHIPREG_PIO_READ32(addr) inl((unsigned long)addr) 227 #define CHIPREG_PIO_READ32(addr) inl((unsigned long)addr)
228 228
229 static void 229 static void
230 pci_disable_io_access(struct pci_dev *pdev) 230 pci_disable_io_access(struct pci_dev *pdev)
231 { 231 {
232 u16 command_reg; 232 u16 command_reg;
233 233
234 pci_read_config_word(pdev, PCI_COMMAND, &command_reg); 234 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
235 command_reg &= ~1; 235 command_reg &= ~1;
236 pci_write_config_word(pdev, PCI_COMMAND, command_reg); 236 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
237 } 237 }
238 238
239 static void 239 static void
240 pci_enable_io_access(struct pci_dev *pdev) 240 pci_enable_io_access(struct pci_dev *pdev)
241 { 241 {
242 u16 command_reg; 242 u16 command_reg;
243 243
244 pci_read_config_word(pdev, PCI_COMMAND, &command_reg); 244 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
245 command_reg |= 1; 245 command_reg |= 1;
246 pci_write_config_word(pdev, PCI_COMMAND, command_reg); 246 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
247 } 247 }
248 248
249 static int mpt_set_debug_level(const char *val, struct kernel_param *kp) 249 static int mpt_set_debug_level(const char *val, struct kernel_param *kp)
250 { 250 {
251 int ret = param_set_int(val, kp); 251 int ret = param_set_int(val, kp);
252 MPT_ADAPTER *ioc; 252 MPT_ADAPTER *ioc;
253 253
254 if (ret) 254 if (ret)
255 return ret; 255 return ret;
256 256
257 list_for_each_entry(ioc, &ioc_list, list) 257 list_for_each_entry(ioc, &ioc_list, list)
258 ioc->debug_level = mpt_debug_level; 258 ioc->debug_level = mpt_debug_level;
259 return 0; 259 return 0;
260 } 260 }
261 261
262 /** 262 /**
263 * mpt_get_cb_idx - obtain cb_idx for registered driver 263 * mpt_get_cb_idx - obtain cb_idx for registered driver
264 * @dclass: class driver enum 264 * @dclass: class driver enum
265 * 265 *
266 * Returns cb_idx, or zero means it wasn't found 266 * Returns cb_idx, or zero means it wasn't found
267 **/ 267 **/
268 static u8 268 static u8
269 mpt_get_cb_idx(MPT_DRIVER_CLASS dclass) 269 mpt_get_cb_idx(MPT_DRIVER_CLASS dclass)
270 { 270 {
271 u8 cb_idx; 271 u8 cb_idx;
272 272
273 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) 273 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--)
274 if (MptDriverClass[cb_idx] == dclass) 274 if (MptDriverClass[cb_idx] == dclass)
275 return cb_idx; 275 return cb_idx;
276 return 0; 276 return 0;
277 } 277 }
278 278
279 /** 279 /**
280 * mpt_is_discovery_complete - determine if discovery has completed 280 * mpt_is_discovery_complete - determine if discovery has completed
281 * @ioc: per adatper instance 281 * @ioc: per adatper instance
282 * 282 *
283 * Returns 1 when discovery completed, else zero. 283 * Returns 1 when discovery completed, else zero.
284 */ 284 */
285 static int 285 static int
286 mpt_is_discovery_complete(MPT_ADAPTER *ioc) 286 mpt_is_discovery_complete(MPT_ADAPTER *ioc)
287 { 287 {
288 ConfigExtendedPageHeader_t hdr; 288 ConfigExtendedPageHeader_t hdr;
289 CONFIGPARMS cfg; 289 CONFIGPARMS cfg;
290 SasIOUnitPage0_t *buffer; 290 SasIOUnitPage0_t *buffer;
291 dma_addr_t dma_handle; 291 dma_addr_t dma_handle;
292 int rc = 0; 292 int rc = 0;
293 293
294 memset(&hdr, 0, sizeof(ConfigExtendedPageHeader_t)); 294 memset(&hdr, 0, sizeof(ConfigExtendedPageHeader_t));
295 memset(&cfg, 0, sizeof(CONFIGPARMS)); 295 memset(&cfg, 0, sizeof(CONFIGPARMS));
296 hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION; 296 hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION;
297 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED; 297 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
298 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT; 298 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
299 cfg.cfghdr.ehdr = &hdr; 299 cfg.cfghdr.ehdr = &hdr;
300 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 300 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
301 301
302 if ((mpt_config(ioc, &cfg))) 302 if ((mpt_config(ioc, &cfg)))
303 goto out; 303 goto out;
304 if (!hdr.ExtPageLength) 304 if (!hdr.ExtPageLength)
305 goto out; 305 goto out;
306 306
307 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4, 307 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
308 &dma_handle); 308 &dma_handle);
309 if (!buffer) 309 if (!buffer)
310 goto out; 310 goto out;
311 311
312 cfg.physAddr = dma_handle; 312 cfg.physAddr = dma_handle;
313 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 313 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
314 314
315 if ((mpt_config(ioc, &cfg))) 315 if ((mpt_config(ioc, &cfg)))
316 goto out_free_consistent; 316 goto out_free_consistent;
317 317
318 if (!(buffer->PhyData[0].PortFlags & 318 if (!(buffer->PhyData[0].PortFlags &
319 MPI_SAS_IOUNIT0_PORT_FLAGS_DISCOVERY_IN_PROGRESS)) 319 MPI_SAS_IOUNIT0_PORT_FLAGS_DISCOVERY_IN_PROGRESS))
320 rc = 1; 320 rc = 1;
321 321
322 out_free_consistent: 322 out_free_consistent:
323 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4, 323 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
324 buffer, dma_handle); 324 buffer, dma_handle);
325 out: 325 out:
326 return rc; 326 return rc;
327 } 327 }
328 328
329 /** 329 /**
330 * mpt_fault_reset_work - work performed on workq after ioc fault 330 * mpt_fault_reset_work - work performed on workq after ioc fault
331 * @work: input argument, used to derive ioc 331 * @work: input argument, used to derive ioc
332 * 332 *
333 **/ 333 **/
334 static void 334 static void
335 mpt_fault_reset_work(struct work_struct *work) 335 mpt_fault_reset_work(struct work_struct *work)
336 { 336 {
337 MPT_ADAPTER *ioc = 337 MPT_ADAPTER *ioc =
338 container_of(work, MPT_ADAPTER, fault_reset_work.work); 338 container_of(work, MPT_ADAPTER, fault_reset_work.work);
339 u32 ioc_raw_state; 339 u32 ioc_raw_state;
340 int rc; 340 int rc;
341 unsigned long flags; 341 unsigned long flags;
342 342
343 if (ioc->ioc_reset_in_progress || !ioc->active) 343 if (ioc->ioc_reset_in_progress || !ioc->active)
344 goto out; 344 goto out;
345 345
346 ioc_raw_state = mpt_GetIocState(ioc, 0); 346 ioc_raw_state = mpt_GetIocState(ioc, 0);
347 if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) { 347 if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
348 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state (%04xh)!!!\n", 348 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state (%04xh)!!!\n",
349 ioc->name, ioc_raw_state & MPI_DOORBELL_DATA_MASK); 349 ioc->name, ioc_raw_state & MPI_DOORBELL_DATA_MASK);
350 printk(MYIOC_s_WARN_FMT "Issuing HardReset from %s!!\n", 350 printk(MYIOC_s_WARN_FMT "Issuing HardReset from %s!!\n",
351 ioc->name, __func__); 351 ioc->name, __func__);
352 rc = mpt_HardResetHandler(ioc, CAN_SLEEP); 352 rc = mpt_HardResetHandler(ioc, CAN_SLEEP);
353 printk(MYIOC_s_WARN_FMT "%s: HardReset: %s\n", ioc->name, 353 printk(MYIOC_s_WARN_FMT "%s: HardReset: %s\n", ioc->name,
354 __func__, (rc == 0) ? "success" : "failed"); 354 __func__, (rc == 0) ? "success" : "failed");
355 ioc_raw_state = mpt_GetIocState(ioc, 0); 355 ioc_raw_state = mpt_GetIocState(ioc, 0);
356 if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) 356 if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT)
357 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state after " 357 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state after "
358 "reset (%04xh)\n", ioc->name, ioc_raw_state & 358 "reset (%04xh)\n", ioc->name, ioc_raw_state &
359 MPI_DOORBELL_DATA_MASK); 359 MPI_DOORBELL_DATA_MASK);
360 } else if (ioc->bus_type == SAS && ioc->sas_discovery_quiesce_io) { 360 } else if (ioc->bus_type == SAS && ioc->sas_discovery_quiesce_io) {
361 if ((mpt_is_discovery_complete(ioc))) { 361 if ((mpt_is_discovery_complete(ioc))) {
362 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "clearing " 362 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "clearing "
363 "discovery_quiesce_io flag\n", ioc->name)); 363 "discovery_quiesce_io flag\n", ioc->name));
364 ioc->sas_discovery_quiesce_io = 0; 364 ioc->sas_discovery_quiesce_io = 0;
365 } 365 }
366 } 366 }
367 367
368 out: 368 out:
369 /* 369 /*
370 * Take turns polling alternate controller 370 * Take turns polling alternate controller
371 */ 371 */
372 if (ioc->alt_ioc) 372 if (ioc->alt_ioc)
373 ioc = ioc->alt_ioc; 373 ioc = ioc->alt_ioc;
374 374
375 /* rearm the timer */ 375 /* rearm the timer */
376 spin_lock_irqsave(&ioc->taskmgmt_lock, flags); 376 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
377 if (ioc->reset_work_q) 377 if (ioc->reset_work_q)
378 queue_delayed_work(ioc->reset_work_q, &ioc->fault_reset_work, 378 queue_delayed_work(ioc->reset_work_q, &ioc->fault_reset_work,
379 msecs_to_jiffies(MPT_POLLING_INTERVAL)); 379 msecs_to_jiffies(MPT_POLLING_INTERVAL));
380 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags); 380 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
381 } 381 }
382 382
383 383
384 /* 384 /*
385 * Process turbo (context) reply... 385 * Process turbo (context) reply...
386 */ 386 */
387 static void 387 static void
388 mpt_turbo_reply(MPT_ADAPTER *ioc, u32 pa) 388 mpt_turbo_reply(MPT_ADAPTER *ioc, u32 pa)
389 { 389 {
390 MPT_FRAME_HDR *mf = NULL; 390 MPT_FRAME_HDR *mf = NULL;
391 MPT_FRAME_HDR *mr = NULL; 391 MPT_FRAME_HDR *mr = NULL;
392 u16 req_idx = 0; 392 u16 req_idx = 0;
393 u8 cb_idx; 393 u8 cb_idx;
394 394
395 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got TURBO reply req_idx=%08x\n", 395 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got TURBO reply req_idx=%08x\n",
396 ioc->name, pa)); 396 ioc->name, pa));
397 397
398 switch (pa >> MPI_CONTEXT_REPLY_TYPE_SHIFT) { 398 switch (pa >> MPI_CONTEXT_REPLY_TYPE_SHIFT) {
399 case MPI_CONTEXT_REPLY_TYPE_SCSI_INIT: 399 case MPI_CONTEXT_REPLY_TYPE_SCSI_INIT:
400 req_idx = pa & 0x0000FFFF; 400 req_idx = pa & 0x0000FFFF;
401 cb_idx = (pa & 0x00FF0000) >> 16; 401 cb_idx = (pa & 0x00FF0000) >> 16;
402 mf = MPT_INDEX_2_MFPTR(ioc, req_idx); 402 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
403 break; 403 break;
404 case MPI_CONTEXT_REPLY_TYPE_LAN: 404 case MPI_CONTEXT_REPLY_TYPE_LAN:
405 cb_idx = mpt_get_cb_idx(MPTLAN_DRIVER); 405 cb_idx = mpt_get_cb_idx(MPTLAN_DRIVER);
406 /* 406 /*
407 * Blind set of mf to NULL here was fatal 407 * Blind set of mf to NULL here was fatal
408 * after lan_reply says "freeme" 408 * after lan_reply says "freeme"
409 * Fix sort of combined with an optimization here; 409 * Fix sort of combined with an optimization here;
410 * added explicit check for case where lan_reply 410 * added explicit check for case where lan_reply
411 * was just returning 1 and doing nothing else. 411 * was just returning 1 and doing nothing else.
412 * For this case skip the callback, but set up 412 * For this case skip the callback, but set up
413 * proper mf value first here:-) 413 * proper mf value first here:-)
414 */ 414 */
415 if ((pa & 0x58000000) == 0x58000000) { 415 if ((pa & 0x58000000) == 0x58000000) {
416 req_idx = pa & 0x0000FFFF; 416 req_idx = pa & 0x0000FFFF;
417 mf = MPT_INDEX_2_MFPTR(ioc, req_idx); 417 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
418 mpt_free_msg_frame(ioc, mf); 418 mpt_free_msg_frame(ioc, mf);
419 mb(); 419 mb();
420 return; 420 return;
421 break; 421 break;
422 } 422 }
423 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa); 423 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
424 break; 424 break;
425 case MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET: 425 case MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET:
426 cb_idx = mpt_get_cb_idx(MPTSTM_DRIVER); 426 cb_idx = mpt_get_cb_idx(MPTSTM_DRIVER);
427 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa); 427 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
428 break; 428 break;
429 default: 429 default:
430 cb_idx = 0; 430 cb_idx = 0;
431 BUG(); 431 BUG();
432 } 432 }
433 433
434 /* Check for (valid) IO callback! */ 434 /* Check for (valid) IO callback! */
435 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS || 435 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
436 MptCallbacks[cb_idx] == NULL) { 436 MptCallbacks[cb_idx] == NULL) {
437 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n", 437 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
438 __func__, ioc->name, cb_idx); 438 __func__, ioc->name, cb_idx);
439 goto out; 439 goto out;
440 } 440 }
441 441
442 if (MptCallbacks[cb_idx](ioc, mf, mr)) 442 if (MptCallbacks[cb_idx](ioc, mf, mr))
443 mpt_free_msg_frame(ioc, mf); 443 mpt_free_msg_frame(ioc, mf);
444 out: 444 out:
445 mb(); 445 mb();
446 } 446 }
447 447
448 static void 448 static void
449 mpt_reply(MPT_ADAPTER *ioc, u32 pa) 449 mpt_reply(MPT_ADAPTER *ioc, u32 pa)
450 { 450 {
451 MPT_FRAME_HDR *mf; 451 MPT_FRAME_HDR *mf;
452 MPT_FRAME_HDR *mr; 452 MPT_FRAME_HDR *mr;
453 u16 req_idx; 453 u16 req_idx;
454 u8 cb_idx; 454 u8 cb_idx;
455 int freeme; 455 int freeme;
456 456
457 u32 reply_dma_low; 457 u32 reply_dma_low;
458 u16 ioc_stat; 458 u16 ioc_stat;
459 459
460 /* non-TURBO reply! Hmmm, something may be up... 460 /* non-TURBO reply! Hmmm, something may be up...
461 * Newest turbo reply mechanism; get address 461 * Newest turbo reply mechanism; get address
462 * via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)! 462 * via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)!
463 */ 463 */
464 464
465 /* Map DMA address of reply header to cpu address. 465 /* Map DMA address of reply header to cpu address.
466 * pa is 32 bits - but the dma address may be 32 or 64 bits 466 * pa is 32 bits - but the dma address may be 32 or 64 bits
467 * get offset based only only the low addresses 467 * get offset based only only the low addresses
468 */ 468 */
469 469
470 reply_dma_low = (pa <<= 1); 470 reply_dma_low = (pa <<= 1);
471 mr = (MPT_FRAME_HDR *)((u8 *)ioc->reply_frames + 471 mr = (MPT_FRAME_HDR *)((u8 *)ioc->reply_frames +
472 (reply_dma_low - ioc->reply_frames_low_dma)); 472 (reply_dma_low - ioc->reply_frames_low_dma));
473 473
474 req_idx = le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx); 474 req_idx = le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx);
475 cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx; 475 cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx;
476 mf = MPT_INDEX_2_MFPTR(ioc, req_idx); 476 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
477 477
478 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got non-TURBO reply=%p req_idx=%x cb_idx=%x Function=%x\n", 478 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got non-TURBO reply=%p req_idx=%x cb_idx=%x Function=%x\n",
479 ioc->name, mr, req_idx, cb_idx, mr->u.hdr.Function)); 479 ioc->name, mr, req_idx, cb_idx, mr->u.hdr.Function));
480 DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mr); 480 DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mr);
481 481
482 /* Check/log IOC log info 482 /* Check/log IOC log info
483 */ 483 */
484 ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus); 484 ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus);
485 if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) { 485 if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
486 u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo); 486 u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
487 if (ioc->bus_type == FC) 487 if (ioc->bus_type == FC)
488 mpt_fc_log_info(ioc, log_info); 488 mpt_fc_log_info(ioc, log_info);
489 else if (ioc->bus_type == SPI) 489 else if (ioc->bus_type == SPI)
490 mpt_spi_log_info(ioc, log_info); 490 mpt_spi_log_info(ioc, log_info);
491 else if (ioc->bus_type == SAS) 491 else if (ioc->bus_type == SAS)
492 mpt_sas_log_info(ioc, log_info); 492 mpt_sas_log_info(ioc, log_info);
493 } 493 }
494 494
495 if (ioc_stat & MPI_IOCSTATUS_MASK) 495 if (ioc_stat & MPI_IOCSTATUS_MASK)
496 mpt_iocstatus_info(ioc, (u32)ioc_stat, mf); 496 mpt_iocstatus_info(ioc, (u32)ioc_stat, mf);
497 497
498 /* Check for (valid) IO callback! */ 498 /* Check for (valid) IO callback! */
499 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS || 499 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
500 MptCallbacks[cb_idx] == NULL) { 500 MptCallbacks[cb_idx] == NULL) {
501 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n", 501 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
502 __func__, ioc->name, cb_idx); 502 __func__, ioc->name, cb_idx);
503 freeme = 0; 503 freeme = 0;
504 goto out; 504 goto out;
505 } 505 }
506 506
507 freeme = MptCallbacks[cb_idx](ioc, mf, mr); 507 freeme = MptCallbacks[cb_idx](ioc, mf, mr);
508 508
509 out: 509 out:
510 /* Flush (non-TURBO) reply with a WRITE! */ 510 /* Flush (non-TURBO) reply with a WRITE! */
511 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, pa); 511 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, pa);
512 512
513 if (freeme) 513 if (freeme)
514 mpt_free_msg_frame(ioc, mf); 514 mpt_free_msg_frame(ioc, mf);
515 mb(); 515 mb();
516 } 516 }
517 517
518 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 518 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
519 /** 519 /**
520 * mpt_interrupt - MPT adapter (IOC) specific interrupt handler. 520 * mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
521 * @irq: irq number (not used) 521 * @irq: irq number (not used)
522 * @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure 522 * @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure
523 * 523 *
524 * This routine is registered via the request_irq() kernel API call, 524 * This routine is registered via the request_irq() kernel API call,
525 * and handles all interrupts generated from a specific MPT adapter 525 * and handles all interrupts generated from a specific MPT adapter
526 * (also referred to as a IO Controller or IOC). 526 * (also referred to as a IO Controller or IOC).
527 * This routine must clear the interrupt from the adapter and does 527 * This routine must clear the interrupt from the adapter and does
528 * so by reading the reply FIFO. Multiple replies may be processed 528 * so by reading the reply FIFO. Multiple replies may be processed
529 * per single call to this routine. 529 * per single call to this routine.
530 * 530 *
531 * This routine handles register-level access of the adapter but 531 * This routine handles register-level access of the adapter but
532 * dispatches (calls) a protocol-specific callback routine to handle 532 * dispatches (calls) a protocol-specific callback routine to handle
533 * the protocol-specific details of the MPT request completion. 533 * the protocol-specific details of the MPT request completion.
534 */ 534 */
535 static irqreturn_t 535 static irqreturn_t
536 mpt_interrupt(int irq, void *bus_id) 536 mpt_interrupt(int irq, void *bus_id)
537 { 537 {
538 MPT_ADAPTER *ioc = bus_id; 538 MPT_ADAPTER *ioc = bus_id;
539 u32 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo); 539 u32 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
540 540
541 if (pa == 0xFFFFFFFF) 541 if (pa == 0xFFFFFFFF)
542 return IRQ_NONE; 542 return IRQ_NONE;
543 543
544 /* 544 /*
545 * Drain the reply FIFO! 545 * Drain the reply FIFO!
546 */ 546 */
547 do { 547 do {
548 if (pa & MPI_ADDRESS_REPLY_A_BIT) 548 if (pa & MPI_ADDRESS_REPLY_A_BIT)
549 mpt_reply(ioc, pa); 549 mpt_reply(ioc, pa);
550 else 550 else
551 mpt_turbo_reply(ioc, pa); 551 mpt_turbo_reply(ioc, pa);
552 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo); 552 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
553 } while (pa != 0xFFFFFFFF); 553 } while (pa != 0xFFFFFFFF);
554 554
555 return IRQ_HANDLED; 555 return IRQ_HANDLED;
556 } 556 }
557 557
558 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 558 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
559 /** 559 /**
560 * mptbase_reply - MPT base driver's callback routine 560 * mptbase_reply - MPT base driver's callback routine
561 * @ioc: Pointer to MPT_ADAPTER structure 561 * @ioc: Pointer to MPT_ADAPTER structure
562 * @req: Pointer to original MPT request frame 562 * @req: Pointer to original MPT request frame
563 * @reply: Pointer to MPT reply frame (NULL if TurboReply) 563 * @reply: Pointer to MPT reply frame (NULL if TurboReply)
564 * 564 *
565 * MPT base driver's callback routine; all base driver 565 * MPT base driver's callback routine; all base driver
566 * "internal" request/reply processing is routed here. 566 * "internal" request/reply processing is routed here.
567 * Currently used for EventNotification and EventAck handling. 567 * Currently used for EventNotification and EventAck handling.
568 * 568 *
569 * Returns 1 indicating original alloc'd request frame ptr 569 * Returns 1 indicating original alloc'd request frame ptr
570 * should be freed, or 0 if it shouldn't. 570 * should be freed, or 0 if it shouldn't.
571 */ 571 */
572 static int 572 static int
573 mptbase_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply) 573 mptbase_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply)
574 { 574 {
575 EventNotificationReply_t *pEventReply; 575 EventNotificationReply_t *pEventReply;
576 u8 event; 576 u8 event;
577 int evHandlers; 577 int evHandlers;
578 int freereq = 1; 578 int freereq = 1;
579 579
580 switch (reply->u.hdr.Function) { 580 switch (reply->u.hdr.Function) {
581 case MPI_FUNCTION_EVENT_NOTIFICATION: 581 case MPI_FUNCTION_EVENT_NOTIFICATION:
582 pEventReply = (EventNotificationReply_t *)reply; 582 pEventReply = (EventNotificationReply_t *)reply;
583 evHandlers = 0; 583 evHandlers = 0;
584 ProcessEventNotification(ioc, pEventReply, &evHandlers); 584 ProcessEventNotification(ioc, pEventReply, &evHandlers);
585 event = le32_to_cpu(pEventReply->Event) & 0xFF; 585 event = le32_to_cpu(pEventReply->Event) & 0xFF;
586 if (pEventReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY) 586 if (pEventReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)
587 freereq = 0; 587 freereq = 0;
588 if (event != MPI_EVENT_EVENT_CHANGE) 588 if (event != MPI_EVENT_EVENT_CHANGE)
589 break; 589 break;
590 case MPI_FUNCTION_CONFIG: 590 case MPI_FUNCTION_CONFIG:
591 case MPI_FUNCTION_SAS_IO_UNIT_CONTROL: 591 case MPI_FUNCTION_SAS_IO_UNIT_CONTROL:
592 ioc->mptbase_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD; 592 ioc->mptbase_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
593 if (reply) { 593 if (reply) {
594 ioc->mptbase_cmds.status |= MPT_MGMT_STATUS_RF_VALID; 594 ioc->mptbase_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
595 memcpy(ioc->mptbase_cmds.reply, reply, 595 memcpy(ioc->mptbase_cmds.reply, reply,
596 min(MPT_DEFAULT_FRAME_SIZE, 596 min(MPT_DEFAULT_FRAME_SIZE,
597 4 * reply->u.reply.MsgLength)); 597 4 * reply->u.reply.MsgLength));
598 } 598 }
599 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_PENDING) { 599 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_PENDING) {
600 ioc->mptbase_cmds.status &= ~MPT_MGMT_STATUS_PENDING; 600 ioc->mptbase_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
601 complete(&ioc->mptbase_cmds.done); 601 complete(&ioc->mptbase_cmds.done);
602 } else 602 } else
603 freereq = 0; 603 freereq = 0;
604 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_FREE_MF) 604 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_FREE_MF)
605 freereq = 1; 605 freereq = 1;
606 break; 606 break;
607 case MPI_FUNCTION_EVENT_ACK: 607 case MPI_FUNCTION_EVENT_ACK:
608 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT 608 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
609 "EventAck reply received\n", ioc->name)); 609 "EventAck reply received\n", ioc->name));
610 break; 610 break;
611 default: 611 default:
612 printk(MYIOC_s_ERR_FMT 612 printk(MYIOC_s_ERR_FMT
613 "Unexpected msg function (=%02Xh) reply received!\n", 613 "Unexpected msg function (=%02Xh) reply received!\n",
614 ioc->name, reply->u.hdr.Function); 614 ioc->name, reply->u.hdr.Function);
615 break; 615 break;
616 } 616 }
617 617
618 /* 618 /*
619 * Conditionally tell caller to free the original 619 * Conditionally tell caller to free the original
620 * EventNotification/EventAck/unexpected request frame! 620 * EventNotification/EventAck/unexpected request frame!
621 */ 621 */
622 return freereq; 622 return freereq;
623 } 623 }
624 624
625 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 625 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
626 /** 626 /**
627 * mpt_register - Register protocol-specific main callback handler. 627 * mpt_register - Register protocol-specific main callback handler.
628 * @cbfunc: callback function pointer 628 * @cbfunc: callback function pointer
629 * @dclass: Protocol driver's class (%MPT_DRIVER_CLASS enum value) 629 * @dclass: Protocol driver's class (%MPT_DRIVER_CLASS enum value)
630 * 630 *
631 * This routine is called by a protocol-specific driver (SCSI host, 631 * This routine is called by a protocol-specific driver (SCSI host,
632 * LAN, SCSI target) to register its reply callback routine. Each 632 * LAN, SCSI target) to register its reply callback routine. Each
633 * protocol-specific driver must do this before it will be able to 633 * protocol-specific driver must do this before it will be able to
634 * use any IOC resources, such as obtaining request frames. 634 * use any IOC resources, such as obtaining request frames.
635 * 635 *
636 * NOTES: The SCSI protocol driver currently calls this routine thrice 636 * NOTES: The SCSI protocol driver currently calls this routine thrice
637 * in order to register separate callbacks; one for "normal" SCSI IO; 637 * in order to register separate callbacks; one for "normal" SCSI IO;
638 * one for MptScsiTaskMgmt requests; one for Scan/DV requests. 638 * one for MptScsiTaskMgmt requests; one for Scan/DV requests.
639 * 639 *
640 * Returns u8 valued "handle" in the range (and S.O.D. order) 640 * Returns u8 valued "handle" in the range (and S.O.D. order)
641 * {N,...,7,6,5,...,1} if successful. 641 * {N,...,7,6,5,...,1} if successful.
642 * A return value of MPT_MAX_PROTOCOL_DRIVERS (including zero!) should be 642 * A return value of MPT_MAX_PROTOCOL_DRIVERS (including zero!) should be
643 * considered an error by the caller. 643 * considered an error by the caller.
644 */ 644 */
645 u8 645 u8
646 mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass) 646 mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass)
647 { 647 {
648 u8 cb_idx; 648 u8 cb_idx;
649 last_drv_idx = MPT_MAX_PROTOCOL_DRIVERS; 649 last_drv_idx = MPT_MAX_PROTOCOL_DRIVERS;
650 650
651 /* 651 /*
652 * Search for empty callback slot in this order: {N,...,7,6,5,...,1} 652 * Search for empty callback slot in this order: {N,...,7,6,5,...,1}
653 * (slot/handle 0 is reserved!) 653 * (slot/handle 0 is reserved!)
654 */ 654 */
655 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) { 655 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
656 if (MptCallbacks[cb_idx] == NULL) { 656 if (MptCallbacks[cb_idx] == NULL) {
657 MptCallbacks[cb_idx] = cbfunc; 657 MptCallbacks[cb_idx] = cbfunc;
658 MptDriverClass[cb_idx] = dclass; 658 MptDriverClass[cb_idx] = dclass;
659 MptEvHandlers[cb_idx] = NULL; 659 MptEvHandlers[cb_idx] = NULL;
660 last_drv_idx = cb_idx; 660 last_drv_idx = cb_idx;
661 break; 661 break;
662 } 662 }
663 } 663 }
664 664
665 return last_drv_idx; 665 return last_drv_idx;
666 } 666 }
667 667
668 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 668 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
669 /** 669 /**
670 * mpt_deregister - Deregister a protocol drivers resources. 670 * mpt_deregister - Deregister a protocol drivers resources.
671 * @cb_idx: previously registered callback handle 671 * @cb_idx: previously registered callback handle
672 * 672 *
673 * Each protocol-specific driver should call this routine when its 673 * Each protocol-specific driver should call this routine when its
674 * module is unloaded. 674 * module is unloaded.
675 */ 675 */
676 void 676 void
677 mpt_deregister(u8 cb_idx) 677 mpt_deregister(u8 cb_idx)
678 { 678 {
679 if (cb_idx && (cb_idx < MPT_MAX_PROTOCOL_DRIVERS)) { 679 if (cb_idx && (cb_idx < MPT_MAX_PROTOCOL_DRIVERS)) {
680 MptCallbacks[cb_idx] = NULL; 680 MptCallbacks[cb_idx] = NULL;
681 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER; 681 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
682 MptEvHandlers[cb_idx] = NULL; 682 MptEvHandlers[cb_idx] = NULL;
683 683
684 last_drv_idx++; 684 last_drv_idx++;
685 } 685 }
686 } 686 }
687 687
688 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 688 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
689 /** 689 /**
690 * mpt_event_register - Register protocol-specific event callback handler. 690 * mpt_event_register - Register protocol-specific event callback handler.
691 * @cb_idx: previously registered (via mpt_register) callback handle 691 * @cb_idx: previously registered (via mpt_register) callback handle
692 * @ev_cbfunc: callback function 692 * @ev_cbfunc: callback function
693 * 693 *
694 * This routine can be called by one or more protocol-specific drivers 694 * This routine can be called by one or more protocol-specific drivers
695 * if/when they choose to be notified of MPT events. 695 * if/when they choose to be notified of MPT events.
696 * 696 *
697 * Returns 0 for success. 697 * Returns 0 for success.
698 */ 698 */
699 int 699 int
700 mpt_event_register(u8 cb_idx, MPT_EVHANDLER ev_cbfunc) 700 mpt_event_register(u8 cb_idx, MPT_EVHANDLER ev_cbfunc)
701 { 701 {
702 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) 702 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
703 return -1; 703 return -1;
704 704
705 MptEvHandlers[cb_idx] = ev_cbfunc; 705 MptEvHandlers[cb_idx] = ev_cbfunc;
706 return 0; 706 return 0;
707 } 707 }
708 708
709 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 709 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
710 /** 710 /**
711 * mpt_event_deregister - Deregister protocol-specific event callback handler 711 * mpt_event_deregister - Deregister protocol-specific event callback handler
712 * @cb_idx: previously registered callback handle 712 * @cb_idx: previously registered callback handle
713 * 713 *
714 * Each protocol-specific driver should call this routine 714 * Each protocol-specific driver should call this routine
715 * when it does not (or can no longer) handle events, 715 * when it does not (or can no longer) handle events,
716 * or when its module is unloaded. 716 * or when its module is unloaded.
717 */ 717 */
718 void 718 void
719 mpt_event_deregister(u8 cb_idx) 719 mpt_event_deregister(u8 cb_idx)
720 { 720 {
721 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) 721 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
722 return; 722 return;
723 723
724 MptEvHandlers[cb_idx] = NULL; 724 MptEvHandlers[cb_idx] = NULL;
725 } 725 }
726 726
727 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 727 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
728 /** 728 /**
729 * mpt_reset_register - Register protocol-specific IOC reset handler. 729 * mpt_reset_register - Register protocol-specific IOC reset handler.
730 * @cb_idx: previously registered (via mpt_register) callback handle 730 * @cb_idx: previously registered (via mpt_register) callback handle
731 * @reset_func: reset function 731 * @reset_func: reset function
732 * 732 *
733 * This routine can be called by one or more protocol-specific drivers 733 * This routine can be called by one or more protocol-specific drivers
734 * if/when they choose to be notified of IOC resets. 734 * if/when they choose to be notified of IOC resets.
735 * 735 *
736 * Returns 0 for success. 736 * Returns 0 for success.
737 */ 737 */
738 int 738 int
739 mpt_reset_register(u8 cb_idx, MPT_RESETHANDLER reset_func) 739 mpt_reset_register(u8 cb_idx, MPT_RESETHANDLER reset_func)
740 { 740 {
741 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) 741 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
742 return -1; 742 return -1;
743 743
744 MptResetHandlers[cb_idx] = reset_func; 744 MptResetHandlers[cb_idx] = reset_func;
745 return 0; 745 return 0;
746 } 746 }
747 747
748 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 748 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
749 /** 749 /**
750 * mpt_reset_deregister - Deregister protocol-specific IOC reset handler. 750 * mpt_reset_deregister - Deregister protocol-specific IOC reset handler.
751 * @cb_idx: previously registered callback handle 751 * @cb_idx: previously registered callback handle
752 * 752 *
753 * Each protocol-specific driver should call this routine 753 * Each protocol-specific driver should call this routine
754 * when it does not (or can no longer) handle IOC reset handling, 754 * when it does not (or can no longer) handle IOC reset handling,
755 * or when its module is unloaded. 755 * or when its module is unloaded.
756 */ 756 */
757 void 757 void
758 mpt_reset_deregister(u8 cb_idx) 758 mpt_reset_deregister(u8 cb_idx)
759 { 759 {
760 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) 760 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
761 return; 761 return;
762 762
763 MptResetHandlers[cb_idx] = NULL; 763 MptResetHandlers[cb_idx] = NULL;
764 } 764 }
765 765
766 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 766 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
767 /** 767 /**
768 * mpt_device_driver_register - Register device driver hooks 768 * mpt_device_driver_register - Register device driver hooks
769 * @dd_cbfunc: driver callbacks struct 769 * @dd_cbfunc: driver callbacks struct
770 * @cb_idx: MPT protocol driver index 770 * @cb_idx: MPT protocol driver index
771 */ 771 */
772 int 772 int
773 mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, u8 cb_idx) 773 mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, u8 cb_idx)
774 { 774 {
775 MPT_ADAPTER *ioc; 775 MPT_ADAPTER *ioc;
776 const struct pci_device_id *id; 776 const struct pci_device_id *id;
777 777
778 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) 778 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
779 return -EINVAL; 779 return -EINVAL;
780 780
781 MptDeviceDriverHandlers[cb_idx] = dd_cbfunc; 781 MptDeviceDriverHandlers[cb_idx] = dd_cbfunc;
782 782
783 /* call per pci device probe entry point */ 783 /* call per pci device probe entry point */
784 list_for_each_entry(ioc, &ioc_list, list) { 784 list_for_each_entry(ioc, &ioc_list, list) {
785 id = ioc->pcidev->driver ? 785 id = ioc->pcidev->driver ?
786 ioc->pcidev->driver->id_table : NULL; 786 ioc->pcidev->driver->id_table : NULL;
787 if (dd_cbfunc->probe) 787 if (dd_cbfunc->probe)
788 dd_cbfunc->probe(ioc->pcidev, id); 788 dd_cbfunc->probe(ioc->pcidev, id);
789 } 789 }
790 790
791 return 0; 791 return 0;
792 } 792 }
793 793
794 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 794 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
795 /** 795 /**
796 * mpt_device_driver_deregister - DeRegister device driver hooks 796 * mpt_device_driver_deregister - DeRegister device driver hooks
797 * @cb_idx: MPT protocol driver index 797 * @cb_idx: MPT protocol driver index
798 */ 798 */
799 void 799 void
800 mpt_device_driver_deregister(u8 cb_idx) 800 mpt_device_driver_deregister(u8 cb_idx)
801 { 801 {
802 struct mpt_pci_driver *dd_cbfunc; 802 struct mpt_pci_driver *dd_cbfunc;
803 MPT_ADAPTER *ioc; 803 MPT_ADAPTER *ioc;
804 804
805 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) 805 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
806 return; 806 return;
807 807
808 dd_cbfunc = MptDeviceDriverHandlers[cb_idx]; 808 dd_cbfunc = MptDeviceDriverHandlers[cb_idx];
809 809
810 list_for_each_entry(ioc, &ioc_list, list) { 810 list_for_each_entry(ioc, &ioc_list, list) {
811 if (dd_cbfunc->remove) 811 if (dd_cbfunc->remove)
812 dd_cbfunc->remove(ioc->pcidev); 812 dd_cbfunc->remove(ioc->pcidev);
813 } 813 }
814 814
815 MptDeviceDriverHandlers[cb_idx] = NULL; 815 MptDeviceDriverHandlers[cb_idx] = NULL;
816 } 816 }
817 817
818 818
819 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 819 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
820 /** 820 /**
821 * mpt_get_msg_frame - Obtain an MPT request frame from the pool 821 * mpt_get_msg_frame - Obtain an MPT request frame from the pool
822 * @cb_idx: Handle of registered MPT protocol driver 822 * @cb_idx: Handle of registered MPT protocol driver
823 * @ioc: Pointer to MPT adapter structure 823 * @ioc: Pointer to MPT adapter structure
824 * 824 *
825 * Obtain an MPT request frame from the pool (of 1024) that are 825 * Obtain an MPT request frame from the pool (of 1024) that are
826 * allocated per MPT adapter. 826 * allocated per MPT adapter.
827 * 827 *
828 * Returns pointer to a MPT request frame or %NULL if none are available 828 * Returns pointer to a MPT request frame or %NULL if none are available
829 * or IOC is not active. 829 * or IOC is not active.
830 */ 830 */
831 MPT_FRAME_HDR* 831 MPT_FRAME_HDR*
832 mpt_get_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc) 832 mpt_get_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc)
833 { 833 {
834 MPT_FRAME_HDR *mf; 834 MPT_FRAME_HDR *mf;
835 unsigned long flags; 835 unsigned long flags;
836 u16 req_idx; /* Request index */ 836 u16 req_idx; /* Request index */
837 837
838 /* validate handle and ioc identifier */ 838 /* validate handle and ioc identifier */
839 839
840 #ifdef MFCNT 840 #ifdef MFCNT
841 if (!ioc->active) 841 if (!ioc->active)
842 printk(MYIOC_s_WARN_FMT "IOC Not Active! mpt_get_msg_frame " 842 printk(MYIOC_s_WARN_FMT "IOC Not Active! mpt_get_msg_frame "
843 "returning NULL!\n", ioc->name); 843 "returning NULL!\n", ioc->name);
844 #endif 844 #endif
845 845
846 /* If interrupts are not attached, do not return a request frame */ 846 /* If interrupts are not attached, do not return a request frame */
847 if (!ioc->active) 847 if (!ioc->active)
848 return NULL; 848 return NULL;
849 849
850 spin_lock_irqsave(&ioc->FreeQlock, flags); 850 spin_lock_irqsave(&ioc->FreeQlock, flags);
851 if (!list_empty(&ioc->FreeQ)) { 851 if (!list_empty(&ioc->FreeQ)) {
852 int req_offset; 852 int req_offset;
853 853
854 mf = list_entry(ioc->FreeQ.next, MPT_FRAME_HDR, 854 mf = list_entry(ioc->FreeQ.next, MPT_FRAME_HDR,
855 u.frame.linkage.list); 855 u.frame.linkage.list);
856 list_del(&mf->u.frame.linkage.list); 856 list_del(&mf->u.frame.linkage.list);
857 mf->u.frame.linkage.arg1 = 0; 857 mf->u.frame.linkage.arg1 = 0;
858 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx; /* byte */ 858 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx; /* byte */
859 req_offset = (u8 *)mf - (u8 *)ioc->req_frames; 859 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
860 /* u16! */ 860 /* u16! */
861 req_idx = req_offset / ioc->req_sz; 861 req_idx = req_offset / ioc->req_sz;
862 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx); 862 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
863 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0; 863 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
864 /* Default, will be changed if necessary in SG generation */ 864 /* Default, will be changed if necessary in SG generation */
865 ioc->RequestNB[req_idx] = ioc->NB_for_64_byte_frame; 865 ioc->RequestNB[req_idx] = ioc->NB_for_64_byte_frame;
866 #ifdef MFCNT 866 #ifdef MFCNT
867 ioc->mfcnt++; 867 ioc->mfcnt++;
868 #endif 868 #endif
869 } 869 }
870 else 870 else
871 mf = NULL; 871 mf = NULL;
872 spin_unlock_irqrestore(&ioc->FreeQlock, flags); 872 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
873 873
874 #ifdef MFCNT 874 #ifdef MFCNT
875 if (mf == NULL) 875 if (mf == NULL)
876 printk(MYIOC_s_WARN_FMT "IOC Active. No free Msg Frames! " 876 printk(MYIOC_s_WARN_FMT "IOC Active. No free Msg Frames! "
877 "Count 0x%x Max 0x%x\n", ioc->name, ioc->mfcnt, 877 "Count 0x%x Max 0x%x\n", ioc->name, ioc->mfcnt,
878 ioc->req_depth); 878 ioc->req_depth);
879 mfcounter++; 879 mfcounter++;
880 if (mfcounter == PRINT_MF_COUNT) 880 if (mfcounter == PRINT_MF_COUNT)
881 printk(MYIOC_s_INFO_FMT "MF Count 0x%x Max 0x%x \n", ioc->name, 881 printk(MYIOC_s_INFO_FMT "MF Count 0x%x Max 0x%x \n", ioc->name,
882 ioc->mfcnt, ioc->req_depth); 882 ioc->mfcnt, ioc->req_depth);
883 #endif 883 #endif
884 884
885 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_get_msg_frame(%d,%d), got mf=%p\n", 885 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_get_msg_frame(%d,%d), got mf=%p\n",
886 ioc->name, cb_idx, ioc->id, mf)); 886 ioc->name, cb_idx, ioc->id, mf));
887 return mf; 887 return mf;
888 } 888 }
889 889
890 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 890 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
891 /** 891 /**
892 * mpt_put_msg_frame - Send a protocol-specific MPT request frame to an IOC 892 * mpt_put_msg_frame - Send a protocol-specific MPT request frame to an IOC
893 * @cb_idx: Handle of registered MPT protocol driver 893 * @cb_idx: Handle of registered MPT protocol driver
894 * @ioc: Pointer to MPT adapter structure 894 * @ioc: Pointer to MPT adapter structure
895 * @mf: Pointer to MPT request frame 895 * @mf: Pointer to MPT request frame
896 * 896 *
897 * This routine posts an MPT request frame to the request post FIFO of a 897 * This routine posts an MPT request frame to the request post FIFO of a
898 * specific MPT adapter. 898 * specific MPT adapter.
899 */ 899 */
900 void 900 void
901 mpt_put_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf) 901 mpt_put_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
902 { 902 {
903 u32 mf_dma_addr; 903 u32 mf_dma_addr;
904 int req_offset; 904 int req_offset;
905 u16 req_idx; /* Request index */ 905 u16 req_idx; /* Request index */
906 906
907 /* ensure values are reset properly! */ 907 /* ensure values are reset properly! */
908 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx; /* byte */ 908 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx; /* byte */
909 req_offset = (u8 *)mf - (u8 *)ioc->req_frames; 909 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
910 /* u16! */ 910 /* u16! */
911 req_idx = req_offset / ioc->req_sz; 911 req_idx = req_offset / ioc->req_sz;
912 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx); 912 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
913 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0; 913 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
914 914
915 DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf); 915 DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf);
916 916
917 mf_dma_addr = (ioc->req_frames_low_dma + req_offset) | ioc->RequestNB[req_idx]; 917 mf_dma_addr = (ioc->req_frames_low_dma + req_offset) | ioc->RequestNB[req_idx];
918 dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d " 918 dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d "
919 "RequestNB=%x\n", ioc->name, mf_dma_addr, req_idx, 919 "RequestNB=%x\n", ioc->name, mf_dma_addr, req_idx,
920 ioc->RequestNB[req_idx])); 920 ioc->RequestNB[req_idx]));
921 CHIPREG_WRITE32(&ioc->chip->RequestFifo, mf_dma_addr); 921 CHIPREG_WRITE32(&ioc->chip->RequestFifo, mf_dma_addr);
922 } 922 }
923 923
924 /** 924 /**
925 * mpt_put_msg_frame_hi_pri - Send a hi-pri protocol-specific MPT request frame 925 * mpt_put_msg_frame_hi_pri - Send a hi-pri protocol-specific MPT request frame
926 * @cb_idx: Handle of registered MPT protocol driver 926 * @cb_idx: Handle of registered MPT protocol driver
927 * @ioc: Pointer to MPT adapter structure 927 * @ioc: Pointer to MPT adapter structure
928 * @mf: Pointer to MPT request frame 928 * @mf: Pointer to MPT request frame
929 * 929 *
930 * Send a protocol-specific MPT request frame to an IOC using 930 * Send a protocol-specific MPT request frame to an IOC using
931 * hi-priority request queue. 931 * hi-priority request queue.
932 * 932 *
933 * This routine posts an MPT request frame to the request post FIFO of a 933 * This routine posts an MPT request frame to the request post FIFO of a
934 * specific MPT adapter. 934 * specific MPT adapter.
935 **/ 935 **/
936 void 936 void
937 mpt_put_msg_frame_hi_pri(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf) 937 mpt_put_msg_frame_hi_pri(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
938 { 938 {
939 u32 mf_dma_addr; 939 u32 mf_dma_addr;
940 int req_offset; 940 int req_offset;
941 u16 req_idx; /* Request index */ 941 u16 req_idx; /* Request index */
942 942
943 /* ensure values are reset properly! */ 943 /* ensure values are reset properly! */
944 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx; 944 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;
945 req_offset = (u8 *)mf - (u8 *)ioc->req_frames; 945 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
946 req_idx = req_offset / ioc->req_sz; 946 req_idx = req_offset / ioc->req_sz;
947 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx); 947 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
948 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0; 948 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
949 949
950 DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf); 950 DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf);
951 951
952 mf_dma_addr = (ioc->req_frames_low_dma + req_offset); 952 mf_dma_addr = (ioc->req_frames_low_dma + req_offset);
953 dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d\n", 953 dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d\n",
954 ioc->name, mf_dma_addr, req_idx)); 954 ioc->name, mf_dma_addr, req_idx));
955 CHIPREG_WRITE32(&ioc->chip->RequestHiPriFifo, mf_dma_addr); 955 CHIPREG_WRITE32(&ioc->chip->RequestHiPriFifo, mf_dma_addr);
956 } 956 }
957 957
958 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 958 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
959 /** 959 /**
960 * mpt_free_msg_frame - Place MPT request frame back on FreeQ. 960 * mpt_free_msg_frame - Place MPT request frame back on FreeQ.
961 * @ioc: Pointer to MPT adapter structure 961 * @ioc: Pointer to MPT adapter structure
962 * @mf: Pointer to MPT request frame 962 * @mf: Pointer to MPT request frame
963 * 963 *
964 * This routine places a MPT request frame back on the MPT adapter's 964 * This routine places a MPT request frame back on the MPT adapter's
965 * FreeQ. 965 * FreeQ.
966 */ 966 */
967 void 967 void
968 mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf) 968 mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
969 { 969 {
970 unsigned long flags; 970 unsigned long flags;
971 971
972 /* Put Request back on FreeQ! */ 972 /* Put Request back on FreeQ! */
973 spin_lock_irqsave(&ioc->FreeQlock, flags); 973 spin_lock_irqsave(&ioc->FreeQlock, flags);
974 if (cpu_to_le32(mf->u.frame.linkage.arg1) == 0xdeadbeaf) 974 if (cpu_to_le32(mf->u.frame.linkage.arg1) == 0xdeadbeaf)
975 goto out; 975 goto out;
976 /* signature to know if this mf is freed */ 976 /* signature to know if this mf is freed */
977 mf->u.frame.linkage.arg1 = cpu_to_le32(0xdeadbeaf); 977 mf->u.frame.linkage.arg1 = cpu_to_le32(0xdeadbeaf);
978 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ); 978 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
979 #ifdef MFCNT 979 #ifdef MFCNT
980 ioc->mfcnt--; 980 ioc->mfcnt--;
981 #endif 981 #endif
982 out: 982 out:
983 spin_unlock_irqrestore(&ioc->FreeQlock, flags); 983 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
984 } 984 }
985 985
986 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 986 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
987 /** 987 /**
988 * mpt_add_sge - Place a simple 32 bit SGE at address pAddr. 988 * mpt_add_sge - Place a simple 32 bit SGE at address pAddr.
989 * @pAddr: virtual address for SGE 989 * @pAddr: virtual address for SGE
990 * @flagslength: SGE flags and data transfer length 990 * @flagslength: SGE flags and data transfer length
991 * @dma_addr: Physical address 991 * @dma_addr: Physical address
992 * 992 *
993 * This routine places a MPT request frame back on the MPT adapter's 993 * This routine places a MPT request frame back on the MPT adapter's
994 * FreeQ. 994 * FreeQ.
995 */ 995 */
996 static void 996 static void
997 mpt_add_sge(void *pAddr, u32 flagslength, dma_addr_t dma_addr) 997 mpt_add_sge(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
998 { 998 {
999 SGESimple32_t *pSge = (SGESimple32_t *) pAddr; 999 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
1000 pSge->FlagsLength = cpu_to_le32(flagslength); 1000 pSge->FlagsLength = cpu_to_le32(flagslength);
1001 pSge->Address = cpu_to_le32(dma_addr); 1001 pSge->Address = cpu_to_le32(dma_addr);
1002 } 1002 }
1003 1003
1004 /** 1004 /**
1005 * mpt_add_sge_64bit - Place a simple 64 bit SGE at address pAddr. 1005 * mpt_add_sge_64bit - Place a simple 64 bit SGE at address pAddr.
1006 * @pAddr: virtual address for SGE 1006 * @pAddr: virtual address for SGE
1007 * @flagslength: SGE flags and data transfer length 1007 * @flagslength: SGE flags and data transfer length
1008 * @dma_addr: Physical address 1008 * @dma_addr: Physical address
1009 * 1009 *
1010 * This routine places a MPT request frame back on the MPT adapter's 1010 * This routine places a MPT request frame back on the MPT adapter's
1011 * FreeQ. 1011 * FreeQ.
1012 **/ 1012 **/
1013 static void 1013 static void
1014 mpt_add_sge_64bit(void *pAddr, u32 flagslength, dma_addr_t dma_addr) 1014 mpt_add_sge_64bit(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
1015 { 1015 {
1016 SGESimple64_t *pSge = (SGESimple64_t *) pAddr; 1016 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
1017 pSge->Address.Low = cpu_to_le32 1017 pSge->Address.Low = cpu_to_le32
1018 (lower_32_bits(dma_addr)); 1018 (lower_32_bits(dma_addr));
1019 pSge->Address.High = cpu_to_le32 1019 pSge->Address.High = cpu_to_le32
1020 (upper_32_bits(dma_addr)); 1020 (upper_32_bits(dma_addr));
1021 pSge->FlagsLength = cpu_to_le32 1021 pSge->FlagsLength = cpu_to_le32
1022 ((flagslength | MPT_SGE_FLAGS_64_BIT_ADDRESSING)); 1022 ((flagslength | MPT_SGE_FLAGS_64_BIT_ADDRESSING));
1023 } 1023 }
1024 1024
1025 /** 1025 /**
1026 * mpt_add_sge_64bit_1078 - Place a simple 64 bit SGE at address pAddr (1078 workaround). 1026 * mpt_add_sge_64bit_1078 - Place a simple 64 bit SGE at address pAddr (1078 workaround).
1027 * @pAddr: virtual address for SGE 1027 * @pAddr: virtual address for SGE
1028 * @flagslength: SGE flags and data transfer length 1028 * @flagslength: SGE flags and data transfer length
1029 * @dma_addr: Physical address 1029 * @dma_addr: Physical address
1030 * 1030 *
1031 * This routine places a MPT request frame back on the MPT adapter's 1031 * This routine places a MPT request frame back on the MPT adapter's
1032 * FreeQ. 1032 * FreeQ.
1033 **/ 1033 **/
1034 static void 1034 static void
1035 mpt_add_sge_64bit_1078(void *pAddr, u32 flagslength, dma_addr_t dma_addr) 1035 mpt_add_sge_64bit_1078(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
1036 { 1036 {
1037 SGESimple64_t *pSge = (SGESimple64_t *) pAddr; 1037 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
1038 u32 tmp; 1038 u32 tmp;
1039 1039
1040 pSge->Address.Low = cpu_to_le32 1040 pSge->Address.Low = cpu_to_le32
1041 (lower_32_bits(dma_addr)); 1041 (lower_32_bits(dma_addr));
1042 tmp = (u32)(upper_32_bits(dma_addr)); 1042 tmp = (u32)(upper_32_bits(dma_addr));
1043 1043
1044 /* 1044 /*
1045 * 1078 errata workaround for the 36GB limitation 1045 * 1078 errata workaround for the 36GB limitation
1046 */ 1046 */
1047 if ((((u64)dma_addr + MPI_SGE_LENGTH(flagslength)) >> 32) == 9) { 1047 if ((((u64)dma_addr + MPI_SGE_LENGTH(flagslength)) >> 32) == 9) {
1048 flagslength |= 1048 flagslength |=
1049 MPI_SGE_SET_FLAGS(MPI_SGE_FLAGS_LOCAL_ADDRESS); 1049 MPI_SGE_SET_FLAGS(MPI_SGE_FLAGS_LOCAL_ADDRESS);
1050 tmp |= (1<<31); 1050 tmp |= (1<<31);
1051 if (mpt_debug_level & MPT_DEBUG_36GB_MEM) 1051 if (mpt_debug_level & MPT_DEBUG_36GB_MEM)
1052 printk(KERN_DEBUG "1078 P0M2 addressing for " 1052 printk(KERN_DEBUG "1078 P0M2 addressing for "
1053 "addr = 0x%llx len = %d\n", 1053 "addr = 0x%llx len = %d\n",
1054 (unsigned long long)dma_addr, 1054 (unsigned long long)dma_addr,
1055 MPI_SGE_LENGTH(flagslength)); 1055 MPI_SGE_LENGTH(flagslength));
1056 } 1056 }
1057 1057
1058 pSge->Address.High = cpu_to_le32(tmp); 1058 pSge->Address.High = cpu_to_le32(tmp);
1059 pSge->FlagsLength = cpu_to_le32( 1059 pSge->FlagsLength = cpu_to_le32(
1060 (flagslength | MPT_SGE_FLAGS_64_BIT_ADDRESSING)); 1060 (flagslength | MPT_SGE_FLAGS_64_BIT_ADDRESSING));
1061 } 1061 }
1062 1062
1063 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1063 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1064 /** 1064 /**
1065 * mpt_add_chain - Place a 32 bit chain SGE at address pAddr. 1065 * mpt_add_chain - Place a 32 bit chain SGE at address pAddr.
1066 * @pAddr: virtual address for SGE 1066 * @pAddr: virtual address for SGE
1067 * @next: nextChainOffset value (u32's) 1067 * @next: nextChainOffset value (u32's)
1068 * @length: length of next SGL segment 1068 * @length: length of next SGL segment
1069 * @dma_addr: Physical address 1069 * @dma_addr: Physical address
1070 * 1070 *
1071 */ 1071 */
1072 static void 1072 static void
1073 mpt_add_chain(void *pAddr, u8 next, u16 length, dma_addr_t dma_addr) 1073 mpt_add_chain(void *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
1074 { 1074 {
1075 SGEChain32_t *pChain = (SGEChain32_t *) pAddr; 1075 SGEChain32_t *pChain = (SGEChain32_t *) pAddr;
1076 pChain->Length = cpu_to_le16(length); 1076 pChain->Length = cpu_to_le16(length);
1077 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT; 1077 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT;
1078 pChain->NextChainOffset = next; 1078 pChain->NextChainOffset = next;
1079 pChain->Address = cpu_to_le32(dma_addr); 1079 pChain->Address = cpu_to_le32(dma_addr);
1080 } 1080 }
1081 1081
1082 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1082 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1083 /** 1083 /**
1084 * mpt_add_chain_64bit - Place a 64 bit chain SGE at address pAddr. 1084 * mpt_add_chain_64bit - Place a 64 bit chain SGE at address pAddr.
1085 * @pAddr: virtual address for SGE 1085 * @pAddr: virtual address for SGE
1086 * @next: nextChainOffset value (u32's) 1086 * @next: nextChainOffset value (u32's)
1087 * @length: length of next SGL segment 1087 * @length: length of next SGL segment
1088 * @dma_addr: Physical address 1088 * @dma_addr: Physical address
1089 * 1089 *
1090 */ 1090 */
1091 static void 1091 static void
1092 mpt_add_chain_64bit(void *pAddr, u8 next, u16 length, dma_addr_t dma_addr) 1092 mpt_add_chain_64bit(void *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
1093 { 1093 {
1094 SGEChain64_t *pChain = (SGEChain64_t *) pAddr; 1094 SGEChain64_t *pChain = (SGEChain64_t *) pAddr;
1095 u32 tmp = dma_addr & 0xFFFFFFFF; 1095 u32 tmp = dma_addr & 0xFFFFFFFF;
1096 1096
1097 pChain->Length = cpu_to_le16(length); 1097 pChain->Length = cpu_to_le16(length);
1098 pChain->Flags = (MPI_SGE_FLAGS_CHAIN_ELEMENT | 1098 pChain->Flags = (MPI_SGE_FLAGS_CHAIN_ELEMENT |
1099 MPI_SGE_FLAGS_64_BIT_ADDRESSING); 1099 MPI_SGE_FLAGS_64_BIT_ADDRESSING);
1100 1100
1101 pChain->NextChainOffset = next; 1101 pChain->NextChainOffset = next;
1102 1102
1103 pChain->Address.Low = cpu_to_le32(tmp); 1103 pChain->Address.Low = cpu_to_le32(tmp);
1104 tmp = (u32)(upper_32_bits(dma_addr)); 1104 tmp = (u32)(upper_32_bits(dma_addr));
1105 pChain->Address.High = cpu_to_le32(tmp); 1105 pChain->Address.High = cpu_to_le32(tmp);
1106 } 1106 }
1107 1107
1108 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1108 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1109 /** 1109 /**
1110 * mpt_send_handshake_request - Send MPT request via doorbell handshake method. 1110 * mpt_send_handshake_request - Send MPT request via doorbell handshake method.
1111 * @cb_idx: Handle of registered MPT protocol driver 1111 * @cb_idx: Handle of registered MPT protocol driver
1112 * @ioc: Pointer to MPT adapter structure 1112 * @ioc: Pointer to MPT adapter structure
1113 * @reqBytes: Size of the request in bytes 1113 * @reqBytes: Size of the request in bytes
1114 * @req: Pointer to MPT request frame 1114 * @req: Pointer to MPT request frame
1115 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay. 1115 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1116 * 1116 *
1117 * This routine is used exclusively to send MptScsiTaskMgmt 1117 * This routine is used exclusively to send MptScsiTaskMgmt
1118 * requests since they are required to be sent via doorbell handshake. 1118 * requests since they are required to be sent via doorbell handshake.
1119 * 1119 *
1120 * NOTE: It is the callers responsibility to byte-swap fields in the 1120 * NOTE: It is the callers responsibility to byte-swap fields in the
1121 * request which are greater than 1 byte in size. 1121 * request which are greater than 1 byte in size.
1122 * 1122 *
1123 * Returns 0 for success, non-zero for failure. 1123 * Returns 0 for success, non-zero for failure.
1124 */ 1124 */
1125 int 1125 int
1126 mpt_send_handshake_request(u8 cb_idx, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag) 1126 mpt_send_handshake_request(u8 cb_idx, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag)
1127 { 1127 {
1128 int r = 0; 1128 int r = 0;
1129 u8 *req_as_bytes; 1129 u8 *req_as_bytes;
1130 int ii; 1130 int ii;
1131 1131
1132 /* State is known to be good upon entering 1132 /* State is known to be good upon entering
1133 * this function so issue the bus reset 1133 * this function so issue the bus reset
1134 * request. 1134 * request.
1135 */ 1135 */
1136 1136
1137 /* 1137 /*
1138 * Emulate what mpt_put_msg_frame() does /wrt to sanity 1138 * Emulate what mpt_put_msg_frame() does /wrt to sanity
1139 * setting cb_idx/req_idx. But ONLY if this request 1139 * setting cb_idx/req_idx. But ONLY if this request
1140 * is in proper (pre-alloc'd) request buffer range... 1140 * is in proper (pre-alloc'd) request buffer range...
1141 */ 1141 */
1142 ii = MFPTR_2_MPT_INDEX(ioc,(MPT_FRAME_HDR*)req); 1142 ii = MFPTR_2_MPT_INDEX(ioc,(MPT_FRAME_HDR*)req);
1143 if (reqBytes >= 12 && ii >= 0 && ii < ioc->req_depth) { 1143 if (reqBytes >= 12 && ii >= 0 && ii < ioc->req_depth) {
1144 MPT_FRAME_HDR *mf = (MPT_FRAME_HDR*)req; 1144 MPT_FRAME_HDR *mf = (MPT_FRAME_HDR*)req;
1145 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(ii); 1145 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(ii);
1146 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx; 1146 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;
1147 } 1147 }
1148 1148
1149 /* Make sure there are no doorbells */ 1149 /* Make sure there are no doorbells */
1150 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); 1150 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1151 1151
1152 CHIPREG_WRITE32(&ioc->chip->Doorbell, 1152 CHIPREG_WRITE32(&ioc->chip->Doorbell,
1153 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) | 1153 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
1154 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT))); 1154 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
1155 1155
1156 /* Wait for IOC doorbell int */ 1156 /* Wait for IOC doorbell int */
1157 if ((ii = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) { 1157 if ((ii = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) {
1158 return ii; 1158 return ii;
1159 } 1159 }
1160 1160
1161 /* Read doorbell and check for active bit */ 1161 /* Read doorbell and check for active bit */
1162 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE)) 1162 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
1163 return -5; 1163 return -5;
1164 1164
1165 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_send_handshake_request start, WaitCnt=%d\n", 1165 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_send_handshake_request start, WaitCnt=%d\n",
1166 ioc->name, ii)); 1166 ioc->name, ii));
1167 1167
1168 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); 1168 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1169 1169
1170 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) { 1170 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1171 return -2; 1171 return -2;
1172 } 1172 }
1173 1173
1174 /* Send request via doorbell handshake */ 1174 /* Send request via doorbell handshake */
1175 req_as_bytes = (u8 *) req; 1175 req_as_bytes = (u8 *) req;
1176 for (ii = 0; ii < reqBytes/4; ii++) { 1176 for (ii = 0; ii < reqBytes/4; ii++) {
1177 u32 word; 1177 u32 word;
1178 1178
1179 word = ((req_as_bytes[(ii*4) + 0] << 0) | 1179 word = ((req_as_bytes[(ii*4) + 0] << 0) |
1180 (req_as_bytes[(ii*4) + 1] << 8) | 1180 (req_as_bytes[(ii*4) + 1] << 8) |
1181 (req_as_bytes[(ii*4) + 2] << 16) | 1181 (req_as_bytes[(ii*4) + 2] << 16) |
1182 (req_as_bytes[(ii*4) + 3] << 24)); 1182 (req_as_bytes[(ii*4) + 3] << 24));
1183 CHIPREG_WRITE32(&ioc->chip->Doorbell, word); 1183 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
1184 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) { 1184 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1185 r = -3; 1185 r = -3;
1186 break; 1186 break;
1187 } 1187 }
1188 } 1188 }
1189 1189
1190 if (r >= 0 && WaitForDoorbellInt(ioc, 10, sleepFlag) >= 0) 1190 if (r >= 0 && WaitForDoorbellInt(ioc, 10, sleepFlag) >= 0)
1191 r = 0; 1191 r = 0;
1192 else 1192 else
1193 r = -4; 1193 r = -4;
1194 1194
1195 /* Make sure there are no doorbells */ 1195 /* Make sure there are no doorbells */
1196 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); 1196 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1197 1197
1198 return r; 1198 return r;
1199 } 1199 }
1200 1200
1201 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1201 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1202 /** 1202 /**
1203 * mpt_host_page_access_control - control the IOC's Host Page Buffer access 1203 * mpt_host_page_access_control - control the IOC's Host Page Buffer access
1204 * @ioc: Pointer to MPT adapter structure 1204 * @ioc: Pointer to MPT adapter structure
1205 * @access_control_value: define bits below 1205 * @access_control_value: define bits below
1206 * @sleepFlag: Specifies whether the process can sleep 1206 * @sleepFlag: Specifies whether the process can sleep
1207 * 1207 *
1208 * Provides mechanism for the host driver to control the IOC's 1208 * Provides mechanism for the host driver to control the IOC's
1209 * Host Page Buffer access. 1209 * Host Page Buffer access.
1210 * 1210 *
1211 * Access Control Value - bits[15:12] 1211 * Access Control Value - bits[15:12]
1212 * 0h Reserved 1212 * 0h Reserved
1213 * 1h Enable Access { MPI_DB_HPBAC_ENABLE_ACCESS } 1213 * 1h Enable Access { MPI_DB_HPBAC_ENABLE_ACCESS }
1214 * 2h Disable Access { MPI_DB_HPBAC_DISABLE_ACCESS } 1214 * 2h Disable Access { MPI_DB_HPBAC_DISABLE_ACCESS }
1215 * 3h Free Buffer { MPI_DB_HPBAC_FREE_BUFFER } 1215 * 3h Free Buffer { MPI_DB_HPBAC_FREE_BUFFER }
1216 * 1216 *
1217 * Returns 0 for success, non-zero for failure. 1217 * Returns 0 for success, non-zero for failure.
1218 */ 1218 */
1219 1219
1220 static int 1220 static int
1221 mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag) 1221 mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag)
1222 { 1222 {
1223 int r = 0; 1223 int r = 0;
1224 1224
1225 /* return if in use */ 1225 /* return if in use */
1226 if (CHIPREG_READ32(&ioc->chip->Doorbell) 1226 if (CHIPREG_READ32(&ioc->chip->Doorbell)
1227 & MPI_DOORBELL_ACTIVE) 1227 & MPI_DOORBELL_ACTIVE)
1228 return -1; 1228 return -1;
1229 1229
1230 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); 1230 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1231 1231
1232 CHIPREG_WRITE32(&ioc->chip->Doorbell, 1232 CHIPREG_WRITE32(&ioc->chip->Doorbell,
1233 ((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL 1233 ((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL
1234 <<MPI_DOORBELL_FUNCTION_SHIFT) | 1234 <<MPI_DOORBELL_FUNCTION_SHIFT) |
1235 (access_control_value<<12))); 1235 (access_control_value<<12)));
1236 1236
1237 /* Wait for IOC to clear Doorbell Status bit */ 1237 /* Wait for IOC to clear Doorbell Status bit */
1238 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) { 1238 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1239 return -2; 1239 return -2;
1240 }else 1240 }else
1241 return 0; 1241 return 0;
1242 } 1242 }
1243 1243
1244 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1244 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1245 /** 1245 /**
1246 * mpt_host_page_alloc - allocate system memory for the fw 1246 * mpt_host_page_alloc - allocate system memory for the fw
1247 * @ioc: Pointer to pointer to IOC adapter 1247 * @ioc: Pointer to pointer to IOC adapter
1248 * @ioc_init: Pointer to ioc init config page 1248 * @ioc_init: Pointer to ioc init config page
1249 * 1249 *
1250 * If we already allocated memory in past, then resend the same pointer. 1250 * If we already allocated memory in past, then resend the same pointer.
1251 * Returns 0 for success, non-zero for failure. 1251 * Returns 0 for success, non-zero for failure.
1252 */ 1252 */
1253 static int 1253 static int
1254 mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init) 1254 mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init)
1255 { 1255 {
1256 char *psge; 1256 char *psge;
1257 int flags_length; 1257 int flags_length;
1258 u32 host_page_buffer_sz=0; 1258 u32 host_page_buffer_sz=0;
1259 1259
1260 if(!ioc->HostPageBuffer) { 1260 if(!ioc->HostPageBuffer) {
1261 1261
1262 host_page_buffer_sz = 1262 host_page_buffer_sz =
1263 le32_to_cpu(ioc->facts.HostPageBufferSGE.FlagsLength) & 0xFFFFFF; 1263 le32_to_cpu(ioc->facts.HostPageBufferSGE.FlagsLength) & 0xFFFFFF;
1264 1264
1265 if(!host_page_buffer_sz) 1265 if(!host_page_buffer_sz)
1266 return 0; /* fw doesn't need any host buffers */ 1266 return 0; /* fw doesn't need any host buffers */
1267 1267
1268 /* spin till we get enough memory */ 1268 /* spin till we get enough memory */
1269 while(host_page_buffer_sz > 0) { 1269 while(host_page_buffer_sz > 0) {
1270 1270
1271 if((ioc->HostPageBuffer = pci_alloc_consistent( 1271 if((ioc->HostPageBuffer = pci_alloc_consistent(
1272 ioc->pcidev, 1272 ioc->pcidev,
1273 host_page_buffer_sz, 1273 host_page_buffer_sz,
1274 &ioc->HostPageBuffer_dma)) != NULL) { 1274 &ioc->HostPageBuffer_dma)) != NULL) {
1275 1275
1276 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT 1276 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1277 "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n", 1277 "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
1278 ioc->name, ioc->HostPageBuffer, 1278 ioc->name, ioc->HostPageBuffer,
1279 (u32)ioc->HostPageBuffer_dma, 1279 (u32)ioc->HostPageBuffer_dma,
1280 host_page_buffer_sz)); 1280 host_page_buffer_sz));
1281 ioc->alloc_total += host_page_buffer_sz; 1281 ioc->alloc_total += host_page_buffer_sz;
1282 ioc->HostPageBuffer_sz = host_page_buffer_sz; 1282 ioc->HostPageBuffer_sz = host_page_buffer_sz;
1283 break; 1283 break;
1284 } 1284 }
1285 1285
1286 host_page_buffer_sz -= (4*1024); 1286 host_page_buffer_sz -= (4*1024);
1287 } 1287 }
1288 } 1288 }
1289 1289
1290 if(!ioc->HostPageBuffer) { 1290 if(!ioc->HostPageBuffer) {
1291 printk(MYIOC_s_ERR_FMT 1291 printk(MYIOC_s_ERR_FMT
1292 "Failed to alloc memory for host_page_buffer!\n", 1292 "Failed to alloc memory for host_page_buffer!\n",
1293 ioc->name); 1293 ioc->name);
1294 return -999; 1294 return -999;
1295 } 1295 }
1296 1296
1297 psge = (char *)&ioc_init->HostPageBufferSGE; 1297 psge = (char *)&ioc_init->HostPageBufferSGE;
1298 flags_length = MPI_SGE_FLAGS_SIMPLE_ELEMENT | 1298 flags_length = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
1299 MPI_SGE_FLAGS_SYSTEM_ADDRESS | 1299 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
1300 MPI_SGE_FLAGS_HOST_TO_IOC | 1300 MPI_SGE_FLAGS_HOST_TO_IOC |
1301 MPI_SGE_FLAGS_END_OF_BUFFER; 1301 MPI_SGE_FLAGS_END_OF_BUFFER;
1302 flags_length = flags_length << MPI_SGE_FLAGS_SHIFT; 1302 flags_length = flags_length << MPI_SGE_FLAGS_SHIFT;
1303 flags_length |= ioc->HostPageBuffer_sz; 1303 flags_length |= ioc->HostPageBuffer_sz;
1304 ioc->add_sge(psge, flags_length, ioc->HostPageBuffer_dma); 1304 ioc->add_sge(psge, flags_length, ioc->HostPageBuffer_dma);
1305 ioc->facts.HostPageBufferSGE = ioc_init->HostPageBufferSGE; 1305 ioc->facts.HostPageBufferSGE = ioc_init->HostPageBufferSGE;
1306 1306
1307 return 0; 1307 return 0;
1308 } 1308 }
1309 1309
1310 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1310 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1311 /** 1311 /**
1312 * mpt_verify_adapter - Given IOC identifier, set pointer to its adapter structure. 1312 * mpt_verify_adapter - Given IOC identifier, set pointer to its adapter structure.
1313 * @iocid: IOC unique identifier (integer) 1313 * @iocid: IOC unique identifier (integer)
1314 * @iocpp: Pointer to pointer to IOC adapter 1314 * @iocpp: Pointer to pointer to IOC adapter
1315 * 1315 *
1316 * Given a unique IOC identifier, set pointer to the associated MPT 1316 * Given a unique IOC identifier, set pointer to the associated MPT
1317 * adapter structure. 1317 * adapter structure.
1318 * 1318 *
1319 * Returns iocid and sets iocpp if iocid is found. 1319 * Returns iocid and sets iocpp if iocid is found.
1320 * Returns -1 if iocid is not found. 1320 * Returns -1 if iocid is not found.
1321 */ 1321 */
1322 int 1322 int
1323 mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp) 1323 mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
1324 { 1324 {
1325 MPT_ADAPTER *ioc; 1325 MPT_ADAPTER *ioc;
1326 1326
1327 list_for_each_entry(ioc,&ioc_list,list) { 1327 list_for_each_entry(ioc,&ioc_list,list) {
1328 if (ioc->id == iocid) { 1328 if (ioc->id == iocid) {
1329 *iocpp =ioc; 1329 *iocpp =ioc;
1330 return iocid; 1330 return iocid;
1331 } 1331 }
1332 } 1332 }
1333 1333
1334 *iocpp = NULL; 1334 *iocpp = NULL;
1335 return -1; 1335 return -1;
1336 } 1336 }
1337 1337
1338 /** 1338 /**
1339 * mpt_get_product_name - returns product string 1339 * mpt_get_product_name - returns product string
1340 * @vendor: pci vendor id 1340 * @vendor: pci vendor id
1341 * @device: pci device id 1341 * @device: pci device id
1342 * @revision: pci revision id 1342 * @revision: pci revision id
1343 * @prod_name: string returned 1343 * @prod_name: string returned
1344 * 1344 *
1345 * Returns product string displayed when driver loads, 1345 * Returns product string displayed when driver loads,
1346 * in /proc/mpt/summary and /sysfs/class/scsi_host/host<X>/version_product 1346 * in /proc/mpt/summary and /sysfs/class/scsi_host/host<X>/version_product
1347 * 1347 *
1348 **/ 1348 **/
1349 static void 1349 static void
1350 mpt_get_product_name(u16 vendor, u16 device, u8 revision, char *prod_name) 1350 mpt_get_product_name(u16 vendor, u16 device, u8 revision, char *prod_name)
1351 { 1351 {
1352 char *product_str = NULL; 1352 char *product_str = NULL;
1353 1353
1354 if (vendor == PCI_VENDOR_ID_BROCADE) { 1354 if (vendor == PCI_VENDOR_ID_BROCADE) {
1355 switch (device) 1355 switch (device)
1356 { 1356 {
1357 case MPI_MANUFACTPAGE_DEVICEID_FC949E: 1357 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1358 switch (revision) 1358 switch (revision)
1359 { 1359 {
1360 case 0x00: 1360 case 0x00:
1361 product_str = "BRE040 A0"; 1361 product_str = "BRE040 A0";
1362 break; 1362 break;
1363 case 0x01: 1363 case 0x01:
1364 product_str = "BRE040 A1"; 1364 product_str = "BRE040 A1";
1365 break; 1365 break;
1366 default: 1366 default:
1367 product_str = "BRE040"; 1367 product_str = "BRE040";
1368 break; 1368 break;
1369 } 1369 }
1370 break; 1370 break;
1371 } 1371 }
1372 goto out; 1372 goto out;
1373 } 1373 }
1374 1374
1375 switch (device) 1375 switch (device)
1376 { 1376 {
1377 case MPI_MANUFACTPAGE_DEVICEID_FC909: 1377 case MPI_MANUFACTPAGE_DEVICEID_FC909:
1378 product_str = "LSIFC909 B1"; 1378 product_str = "LSIFC909 B1";
1379 break; 1379 break;
1380 case MPI_MANUFACTPAGE_DEVICEID_FC919: 1380 case MPI_MANUFACTPAGE_DEVICEID_FC919:
1381 product_str = "LSIFC919 B0"; 1381 product_str = "LSIFC919 B0";
1382 break; 1382 break;
1383 case MPI_MANUFACTPAGE_DEVICEID_FC929: 1383 case MPI_MANUFACTPAGE_DEVICEID_FC929:
1384 product_str = "LSIFC929 B0"; 1384 product_str = "LSIFC929 B0";
1385 break; 1385 break;
1386 case MPI_MANUFACTPAGE_DEVICEID_FC919X: 1386 case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1387 if (revision < 0x80) 1387 if (revision < 0x80)
1388 product_str = "LSIFC919X A0"; 1388 product_str = "LSIFC919X A0";
1389 else 1389 else
1390 product_str = "LSIFC919XL A1"; 1390 product_str = "LSIFC919XL A1";
1391 break; 1391 break;
1392 case MPI_MANUFACTPAGE_DEVICEID_FC929X: 1392 case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1393 if (revision < 0x80) 1393 if (revision < 0x80)
1394 product_str = "LSIFC929X A0"; 1394 product_str = "LSIFC929X A0";
1395 else 1395 else
1396 product_str = "LSIFC929XL A1"; 1396 product_str = "LSIFC929XL A1";
1397 break; 1397 break;
1398 case MPI_MANUFACTPAGE_DEVICEID_FC939X: 1398 case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1399 product_str = "LSIFC939X A1"; 1399 product_str = "LSIFC939X A1";
1400 break; 1400 break;
1401 case MPI_MANUFACTPAGE_DEVICEID_FC949X: 1401 case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1402 product_str = "LSIFC949X A1"; 1402 product_str = "LSIFC949X A1";
1403 break; 1403 break;
1404 case MPI_MANUFACTPAGE_DEVICEID_FC949E: 1404 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1405 switch (revision) 1405 switch (revision)
1406 { 1406 {
1407 case 0x00: 1407 case 0x00:
1408 product_str = "LSIFC949E A0"; 1408 product_str = "LSIFC949E A0";
1409 break; 1409 break;
1410 case 0x01: 1410 case 0x01:
1411 product_str = "LSIFC949E A1"; 1411 product_str = "LSIFC949E A1";
1412 break; 1412 break;
1413 default: 1413 default:
1414 product_str = "LSIFC949E"; 1414 product_str = "LSIFC949E";
1415 break; 1415 break;
1416 } 1416 }
1417 break; 1417 break;
1418 case MPI_MANUFACTPAGE_DEVID_53C1030: 1418 case MPI_MANUFACTPAGE_DEVID_53C1030:
1419 switch (revision) 1419 switch (revision)
1420 { 1420 {
1421 case 0x00: 1421 case 0x00:
1422 product_str = "LSI53C1030 A0"; 1422 product_str = "LSI53C1030 A0";
1423 break; 1423 break;
1424 case 0x01: 1424 case 0x01:
1425 product_str = "LSI53C1030 B0"; 1425 product_str = "LSI53C1030 B0";
1426 break; 1426 break;
1427 case 0x03: 1427 case 0x03:
1428 product_str = "LSI53C1030 B1"; 1428 product_str = "LSI53C1030 B1";
1429 break; 1429 break;
1430 case 0x07: 1430 case 0x07:
1431 product_str = "LSI53C1030 B2"; 1431 product_str = "LSI53C1030 B2";
1432 break; 1432 break;
1433 case 0x08: 1433 case 0x08:
1434 product_str = "LSI53C1030 C0"; 1434 product_str = "LSI53C1030 C0";
1435 break; 1435 break;
1436 case 0x80: 1436 case 0x80:
1437 product_str = "LSI53C1030T A0"; 1437 product_str = "LSI53C1030T A0";
1438 break; 1438 break;
1439 case 0x83: 1439 case 0x83:
1440 product_str = "LSI53C1030T A2"; 1440 product_str = "LSI53C1030T A2";
1441 break; 1441 break;
1442 case 0x87: 1442 case 0x87:
1443 product_str = "LSI53C1030T A3"; 1443 product_str = "LSI53C1030T A3";
1444 break; 1444 break;
1445 case 0xc1: 1445 case 0xc1:
1446 product_str = "LSI53C1020A A1"; 1446 product_str = "LSI53C1020A A1";
1447 break; 1447 break;
1448 default: 1448 default:
1449 product_str = "LSI53C1030"; 1449 product_str = "LSI53C1030";
1450 break; 1450 break;
1451 } 1451 }
1452 break; 1452 break;
1453 case MPI_MANUFACTPAGE_DEVID_1030_53C1035: 1453 case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1454 switch (revision) 1454 switch (revision)
1455 { 1455 {
1456 case 0x03: 1456 case 0x03:
1457 product_str = "LSI53C1035 A2"; 1457 product_str = "LSI53C1035 A2";
1458 break; 1458 break;
1459 case 0x04: 1459 case 0x04:
1460 product_str = "LSI53C1035 B0"; 1460 product_str = "LSI53C1035 B0";
1461 break; 1461 break;
1462 default: 1462 default:
1463 product_str = "LSI53C1035"; 1463 product_str = "LSI53C1035";
1464 break; 1464 break;
1465 } 1465 }
1466 break; 1466 break;
1467 case MPI_MANUFACTPAGE_DEVID_SAS1064: 1467 case MPI_MANUFACTPAGE_DEVID_SAS1064:
1468 switch (revision) 1468 switch (revision)
1469 { 1469 {
1470 case 0x00: 1470 case 0x00:
1471 product_str = "LSISAS1064 A1"; 1471 product_str = "LSISAS1064 A1";
1472 break; 1472 break;
1473 case 0x01: 1473 case 0x01:
1474 product_str = "LSISAS1064 A2"; 1474 product_str = "LSISAS1064 A2";
1475 break; 1475 break;
1476 case 0x02: 1476 case 0x02:
1477 product_str = "LSISAS1064 A3"; 1477 product_str = "LSISAS1064 A3";
1478 break; 1478 break;
1479 case 0x03: 1479 case 0x03:
1480 product_str = "LSISAS1064 A4"; 1480 product_str = "LSISAS1064 A4";
1481 break; 1481 break;
1482 default: 1482 default:
1483 product_str = "LSISAS1064"; 1483 product_str = "LSISAS1064";
1484 break; 1484 break;
1485 } 1485 }
1486 break; 1486 break;
1487 case MPI_MANUFACTPAGE_DEVID_SAS1064E: 1487 case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1488 switch (revision) 1488 switch (revision)
1489 { 1489 {
1490 case 0x00: 1490 case 0x00:
1491 product_str = "LSISAS1064E A0"; 1491 product_str = "LSISAS1064E A0";
1492 break; 1492 break;
1493 case 0x01: 1493 case 0x01:
1494 product_str = "LSISAS1064E B0"; 1494 product_str = "LSISAS1064E B0";
1495 break; 1495 break;
1496 case 0x02: 1496 case 0x02:
1497 product_str = "LSISAS1064E B1"; 1497 product_str = "LSISAS1064E B1";
1498 break; 1498 break;
1499 case 0x04: 1499 case 0x04:
1500 product_str = "LSISAS1064E B2"; 1500 product_str = "LSISAS1064E B2";
1501 break; 1501 break;
1502 case 0x08: 1502 case 0x08:
1503 product_str = "LSISAS1064E B3"; 1503 product_str = "LSISAS1064E B3";
1504 break; 1504 break;
1505 default: 1505 default:
1506 product_str = "LSISAS1064E"; 1506 product_str = "LSISAS1064E";
1507 break; 1507 break;
1508 } 1508 }
1509 break; 1509 break;
1510 case MPI_MANUFACTPAGE_DEVID_SAS1068: 1510 case MPI_MANUFACTPAGE_DEVID_SAS1068:
1511 switch (revision) 1511 switch (revision)
1512 { 1512 {
1513 case 0x00: 1513 case 0x00:
1514 product_str = "LSISAS1068 A0"; 1514 product_str = "LSISAS1068 A0";
1515 break; 1515 break;
1516 case 0x01: 1516 case 0x01:
1517 product_str = "LSISAS1068 B0"; 1517 product_str = "LSISAS1068 B0";
1518 break; 1518 break;
1519 case 0x02: 1519 case 0x02:
1520 product_str = "LSISAS1068 B1"; 1520 product_str = "LSISAS1068 B1";
1521 break; 1521 break;
1522 default: 1522 default:
1523 product_str = "LSISAS1068"; 1523 product_str = "LSISAS1068";
1524 break; 1524 break;
1525 } 1525 }
1526 break; 1526 break;
1527 case MPI_MANUFACTPAGE_DEVID_SAS1068E: 1527 case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1528 switch (revision) 1528 switch (revision)
1529 { 1529 {
1530 case 0x00: 1530 case 0x00:
1531 product_str = "LSISAS1068E A0"; 1531 product_str = "LSISAS1068E A0";
1532 break; 1532 break;
1533 case 0x01: 1533 case 0x01:
1534 product_str = "LSISAS1068E B0"; 1534 product_str = "LSISAS1068E B0";
1535 break; 1535 break;
1536 case 0x02: 1536 case 0x02:
1537 product_str = "LSISAS1068E B1"; 1537 product_str = "LSISAS1068E B1";
1538 break; 1538 break;
1539 case 0x04: 1539 case 0x04:
1540 product_str = "LSISAS1068E B2"; 1540 product_str = "LSISAS1068E B2";
1541 break; 1541 break;
1542 case 0x08: 1542 case 0x08:
1543 product_str = "LSISAS1068E B3"; 1543 product_str = "LSISAS1068E B3";
1544 break; 1544 break;
1545 default: 1545 default:
1546 product_str = "LSISAS1068E"; 1546 product_str = "LSISAS1068E";
1547 break; 1547 break;
1548 } 1548 }
1549 break; 1549 break;
1550 case MPI_MANUFACTPAGE_DEVID_SAS1078: 1550 case MPI_MANUFACTPAGE_DEVID_SAS1078:
1551 switch (revision) 1551 switch (revision)
1552 { 1552 {
1553 case 0x00: 1553 case 0x00:
1554 product_str = "LSISAS1078 A0"; 1554 product_str = "LSISAS1078 A0";
1555 break; 1555 break;
1556 case 0x01: 1556 case 0x01:
1557 product_str = "LSISAS1078 B0"; 1557 product_str = "LSISAS1078 B0";
1558 break; 1558 break;
1559 case 0x02: 1559 case 0x02:
1560 product_str = "LSISAS1078 C0"; 1560 product_str = "LSISAS1078 C0";
1561 break; 1561 break;
1562 case 0x03: 1562 case 0x03:
1563 product_str = "LSISAS1078 C1"; 1563 product_str = "LSISAS1078 C1";
1564 break; 1564 break;
1565 case 0x04: 1565 case 0x04:
1566 product_str = "LSISAS1078 C2"; 1566 product_str = "LSISAS1078 C2";
1567 break; 1567 break;
1568 default: 1568 default:
1569 product_str = "LSISAS1078"; 1569 product_str = "LSISAS1078";
1570 break; 1570 break;
1571 } 1571 }
1572 break; 1572 break;
1573 } 1573 }
1574 1574
1575 out: 1575 out:
1576 if (product_str) 1576 if (product_str)
1577 sprintf(prod_name, "%s", product_str); 1577 sprintf(prod_name, "%s", product_str);
1578 } 1578 }
1579 1579
1580 /** 1580 /**
1581 * mpt_mapresources - map in memory mapped io 1581 * mpt_mapresources - map in memory mapped io
1582 * @ioc: Pointer to pointer to IOC adapter 1582 * @ioc: Pointer to pointer to IOC adapter
1583 * 1583 *
1584 **/ 1584 **/
1585 static int 1585 static int
1586 mpt_mapresources(MPT_ADAPTER *ioc) 1586 mpt_mapresources(MPT_ADAPTER *ioc)
1587 { 1587 {
1588 u8 __iomem *mem; 1588 u8 __iomem *mem;
1589 int ii; 1589 int ii;
1590 unsigned long mem_phys; 1590 unsigned long mem_phys;
1591 unsigned long port; 1591 unsigned long port;
1592 u32 msize; 1592 u32 msize;
1593 u32 psize; 1593 u32 psize;
1594 u8 revision; 1594 u8 revision;
1595 int r = -ENODEV; 1595 int r = -ENODEV;
1596 struct pci_dev *pdev; 1596 struct pci_dev *pdev;
1597 1597
1598 pdev = ioc->pcidev; 1598 pdev = ioc->pcidev;
1599 ioc->bars = pci_select_bars(pdev, IORESOURCE_MEM); 1599 ioc->bars = pci_select_bars(pdev, IORESOURCE_MEM);
1600 if (pci_enable_device_mem(pdev)) { 1600 if (pci_enable_device_mem(pdev)) {
1601 printk(MYIOC_s_ERR_FMT "pci_enable_device_mem() " 1601 printk(MYIOC_s_ERR_FMT "pci_enable_device_mem() "
1602 "failed\n", ioc->name); 1602 "failed\n", ioc->name);
1603 return r; 1603 return r;
1604 } 1604 }
1605 if (pci_request_selected_regions(pdev, ioc->bars, "mpt")) { 1605 if (pci_request_selected_regions(pdev, ioc->bars, "mpt")) {
1606 printk(MYIOC_s_ERR_FMT "pci_request_selected_regions() with " 1606 printk(MYIOC_s_ERR_FMT "pci_request_selected_regions() with "
1607 "MEM failed\n", ioc->name); 1607 "MEM failed\n", ioc->name);
1608 return r; 1608 return r;
1609 } 1609 }
1610 1610
1611 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision); 1611 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1612 1612
1613 if (sizeof(dma_addr_t) > 4) { 1613 if (sizeof(dma_addr_t) > 4) {
1614 const uint64_t required_mask = dma_get_required_mask 1614 const uint64_t required_mask = dma_get_required_mask
1615 (&pdev->dev); 1615 (&pdev->dev);
1616 if (required_mask > DMA_BIT_MASK(32) 1616 if (required_mask > DMA_BIT_MASK(32)
1617 && !pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) 1617 && !pci_set_dma_mask(pdev, DMA_BIT_MASK(64))
1618 && !pci_set_consistent_dma_mask(pdev, 1618 && !pci_set_consistent_dma_mask(pdev,
1619 DMA_BIT_MASK(64))) { 1619 DMA_BIT_MASK(64))) {
1620 ioc->dma_mask = DMA_BIT_MASK(64); 1620 ioc->dma_mask = DMA_BIT_MASK(64);
1621 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT 1621 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1622 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n", 1622 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1623 ioc->name)); 1623 ioc->name));
1624 } else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) 1624 } else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
1625 && !pci_set_consistent_dma_mask(pdev, 1625 && !pci_set_consistent_dma_mask(pdev,
1626 DMA_BIT_MASK(32))) { 1626 DMA_BIT_MASK(32))) {
1627 ioc->dma_mask = DMA_BIT_MASK(32); 1627 ioc->dma_mask = DMA_BIT_MASK(32);
1628 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT 1628 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1629 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n", 1629 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1630 ioc->name)); 1630 ioc->name));
1631 } else { 1631 } else {
1632 printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n", 1632 printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n",
1633 ioc->name, pci_name(pdev)); 1633 ioc->name, pci_name(pdev));
1634 return r; 1634 return r;
1635 } 1635 }
1636 } else { 1636 } else {
1637 if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) 1637 if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
1638 && !pci_set_consistent_dma_mask(pdev, 1638 && !pci_set_consistent_dma_mask(pdev,
1639 DMA_BIT_MASK(32))) { 1639 DMA_BIT_MASK(32))) {
1640 ioc->dma_mask = DMA_BIT_MASK(32); 1640 ioc->dma_mask = DMA_BIT_MASK(32);
1641 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT 1641 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1642 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n", 1642 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1643 ioc->name)); 1643 ioc->name));
1644 } else { 1644 } else {
1645 printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n", 1645 printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n",
1646 ioc->name, pci_name(pdev)); 1646 ioc->name, pci_name(pdev));
1647 return r; 1647 return r;
1648 } 1648 }
1649 } 1649 }
1650 1650
1651 mem_phys = msize = 0; 1651 mem_phys = msize = 0;
1652 port = psize = 0; 1652 port = psize = 0;
1653 for (ii = 0; ii < DEVICE_COUNT_RESOURCE; ii++) { 1653 for (ii = 0; ii < DEVICE_COUNT_RESOURCE; ii++) {
1654 if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) { 1654 if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
1655 if (psize) 1655 if (psize)
1656 continue; 1656 continue;
1657 /* Get I/O space! */ 1657 /* Get I/O space! */
1658 port = pci_resource_start(pdev, ii); 1658 port = pci_resource_start(pdev, ii);
1659 psize = pci_resource_len(pdev, ii); 1659 psize = pci_resource_len(pdev, ii);
1660 } else { 1660 } else {
1661 if (msize) 1661 if (msize)
1662 continue; 1662 continue;
1663 /* Get memmap */ 1663 /* Get memmap */
1664 mem_phys = pci_resource_start(pdev, ii); 1664 mem_phys = pci_resource_start(pdev, ii);
1665 msize = pci_resource_len(pdev, ii); 1665 msize = pci_resource_len(pdev, ii);
1666 } 1666 }
1667 } 1667 }
1668 ioc->mem_size = msize; 1668 ioc->mem_size = msize;
1669 1669
1670 mem = NULL; 1670 mem = NULL;
1671 /* Get logical ptr for PciMem0 space */ 1671 /* Get logical ptr for PciMem0 space */
1672 /*mem = ioremap(mem_phys, msize);*/ 1672 /*mem = ioremap(mem_phys, msize);*/
1673 mem = ioremap(mem_phys, msize); 1673 mem = ioremap(mem_phys, msize);
1674 if (mem == NULL) { 1674 if (mem == NULL) {
1675 printk(MYIOC_s_ERR_FMT ": ERROR - Unable to map adapter" 1675 printk(MYIOC_s_ERR_FMT ": ERROR - Unable to map adapter"
1676 " memory!\n", ioc->name); 1676 " memory!\n", ioc->name);
1677 return -EINVAL; 1677 return -EINVAL;
1678 } 1678 }
1679 ioc->memmap = mem; 1679 ioc->memmap = mem;
1680 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "mem = %p, mem_phys = %lx\n", 1680 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "mem = %p, mem_phys = %lx\n",
1681 ioc->name, mem, mem_phys)); 1681 ioc->name, mem, mem_phys));
1682 1682
1683 ioc->mem_phys = mem_phys; 1683 ioc->mem_phys = mem_phys;
1684 ioc->chip = (SYSIF_REGS __iomem *)mem; 1684 ioc->chip = (SYSIF_REGS __iomem *)mem;
1685 1685
1686 /* Save Port IO values in case we need to do downloadboot */ 1686 /* Save Port IO values in case we need to do downloadboot */
1687 ioc->pio_mem_phys = port; 1687 ioc->pio_mem_phys = port;
1688 ioc->pio_chip = (SYSIF_REGS __iomem *)port; 1688 ioc->pio_chip = (SYSIF_REGS __iomem *)port;
1689 1689
1690 return 0; 1690 return 0;
1691 } 1691 }
1692 1692
1693 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1693 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1694 /** 1694 /**
1695 * mpt_attach - Install a PCI intelligent MPT adapter. 1695 * mpt_attach - Install a PCI intelligent MPT adapter.
1696 * @pdev: Pointer to pci_dev structure 1696 * @pdev: Pointer to pci_dev structure
1697 * @id: PCI device ID information 1697 * @id: PCI device ID information
1698 * 1698 *
1699 * This routine performs all the steps necessary to bring the IOC of 1699 * This routine performs all the steps necessary to bring the IOC of
1700 * a MPT adapter to a OPERATIONAL state. This includes registering 1700 * a MPT adapter to a OPERATIONAL state. This includes registering
1701 * memory regions, registering the interrupt, and allocating request 1701 * memory regions, registering the interrupt, and allocating request
1702 * and reply memory pools. 1702 * and reply memory pools.
1703 * 1703 *
1704 * This routine also pre-fetches the LAN MAC address of a Fibre Channel 1704 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1705 * MPT adapter. 1705 * MPT adapter.
1706 * 1706 *
1707 * Returns 0 for success, non-zero for failure. 1707 * Returns 0 for success, non-zero for failure.
1708 * 1708 *
1709 * TODO: Add support for polled controllers 1709 * TODO: Add support for polled controllers
1710 */ 1710 */
1711 int 1711 int
1712 mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) 1712 mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1713 { 1713 {
1714 MPT_ADAPTER *ioc; 1714 MPT_ADAPTER *ioc;
1715 u8 cb_idx; 1715 u8 cb_idx;
1716 int r = -ENODEV; 1716 int r = -ENODEV;
1717 u8 revision; 1717 u8 revision;
1718 u8 pcixcmd; 1718 u8 pcixcmd;
1719 static int mpt_ids = 0; 1719 static int mpt_ids = 0;
1720 #ifdef CONFIG_PROC_FS 1720 #ifdef CONFIG_PROC_FS
1721 struct proc_dir_entry *dent, *ent; 1721 struct proc_dir_entry *dent, *ent;
1722 #endif 1722 #endif
1723 1723
1724 ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC); 1724 ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
1725 if (ioc == NULL) { 1725 if (ioc == NULL) {
1726 printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n"); 1726 printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
1727 return -ENOMEM; 1727 return -ENOMEM;
1728 } 1728 }
1729 1729
1730 ioc->id = mpt_ids++; 1730 ioc->id = mpt_ids++;
1731 sprintf(ioc->name, "ioc%d", ioc->id); 1731 sprintf(ioc->name, "ioc%d", ioc->id);
1732 dinitprintk(ioc, printk(KERN_WARNING MYNAM ": mpt_adapter_install\n")); 1732 dinitprintk(ioc, printk(KERN_WARNING MYNAM ": mpt_adapter_install\n"));
1733 1733
1734 /* 1734 /*
1735 * set initial debug level 1735 * set initial debug level
1736 * (refer to mptdebug.h) 1736 * (refer to mptdebug.h)
1737 * 1737 *
1738 */ 1738 */
1739 ioc->debug_level = mpt_debug_level; 1739 ioc->debug_level = mpt_debug_level;
1740 if (mpt_debug_level) 1740 if (mpt_debug_level)
1741 printk(KERN_INFO "mpt_debug_level=%xh\n", mpt_debug_level); 1741 printk(KERN_INFO "mpt_debug_level=%xh\n", mpt_debug_level);
1742 1742
1743 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": mpt_adapter_install\n", ioc->name)); 1743 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": mpt_adapter_install\n", ioc->name));
1744 1744
1745 ioc->pcidev = pdev; 1745 ioc->pcidev = pdev;
1746 if (mpt_mapresources(ioc)) { 1746 if (mpt_mapresources(ioc)) {
1747 kfree(ioc); 1747 kfree(ioc);
1748 return r; 1748 return r;
1749 } 1749 }
1750 1750
1751 /* 1751 /*
1752 * Setting up proper handlers for scatter gather handling 1752 * Setting up proper handlers for scatter gather handling
1753 */ 1753 */
1754 if (ioc->dma_mask == DMA_BIT_MASK(64)) { 1754 if (ioc->dma_mask == DMA_BIT_MASK(64)) {
1755 if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) 1755 if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078)
1756 ioc->add_sge = &mpt_add_sge_64bit_1078; 1756 ioc->add_sge = &mpt_add_sge_64bit_1078;
1757 else 1757 else
1758 ioc->add_sge = &mpt_add_sge_64bit; 1758 ioc->add_sge = &mpt_add_sge_64bit;
1759 ioc->add_chain = &mpt_add_chain_64bit; 1759 ioc->add_chain = &mpt_add_chain_64bit;
1760 ioc->sg_addr_size = 8; 1760 ioc->sg_addr_size = 8;
1761 } else { 1761 } else {
1762 ioc->add_sge = &mpt_add_sge; 1762 ioc->add_sge = &mpt_add_sge;
1763 ioc->add_chain = &mpt_add_chain; 1763 ioc->add_chain = &mpt_add_chain;
1764 ioc->sg_addr_size = 4; 1764 ioc->sg_addr_size = 4;
1765 } 1765 }
1766 ioc->SGE_size = sizeof(u32) + ioc->sg_addr_size; 1766 ioc->SGE_size = sizeof(u32) + ioc->sg_addr_size;
1767 1767
1768 ioc->alloc_total = sizeof(MPT_ADAPTER); 1768 ioc->alloc_total = sizeof(MPT_ADAPTER);
1769 ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */ 1769 ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */
1770 ioc->reply_sz = MPT_REPLY_FRAME_SIZE; 1770 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
1771 1771
1772 ioc->pcidev = pdev; 1772 ioc->pcidev = pdev;
1773 1773
1774 spin_lock_init(&ioc->taskmgmt_lock); 1774 spin_lock_init(&ioc->taskmgmt_lock);
1775 mutex_init(&ioc->internal_cmds.mutex); 1775 mutex_init(&ioc->internal_cmds.mutex);
1776 init_completion(&ioc->internal_cmds.done); 1776 init_completion(&ioc->internal_cmds.done);
1777 mutex_init(&ioc->mptbase_cmds.mutex); 1777 mutex_init(&ioc->mptbase_cmds.mutex);
1778 init_completion(&ioc->mptbase_cmds.done); 1778 init_completion(&ioc->mptbase_cmds.done);
1779 mutex_init(&ioc->taskmgmt_cmds.mutex); 1779 mutex_init(&ioc->taskmgmt_cmds.mutex);
1780 init_completion(&ioc->taskmgmt_cmds.done); 1780 init_completion(&ioc->taskmgmt_cmds.done);
1781 1781
1782 /* Initialize the event logging. 1782 /* Initialize the event logging.
1783 */ 1783 */
1784 ioc->eventTypes = 0; /* None */ 1784 ioc->eventTypes = 0; /* None */
1785 ioc->eventContext = 0; 1785 ioc->eventContext = 0;
1786 ioc->eventLogSize = 0; 1786 ioc->eventLogSize = 0;
1787 ioc->events = NULL; 1787 ioc->events = NULL;
1788 1788
1789 #ifdef MFCNT 1789 #ifdef MFCNT
1790 ioc->mfcnt = 0; 1790 ioc->mfcnt = 0;
1791 #endif 1791 #endif
1792 1792
1793 ioc->sh = NULL; 1793 ioc->sh = NULL;
1794 ioc->cached_fw = NULL; 1794 ioc->cached_fw = NULL;
1795 1795
1796 /* Initilize SCSI Config Data structure 1796 /* Initilize SCSI Config Data structure
1797 */ 1797 */
1798 memset(&ioc->spi_data, 0, sizeof(SpiCfgData)); 1798 memset(&ioc->spi_data, 0, sizeof(SpiCfgData));
1799 1799
1800 /* Initialize the fc rport list head. 1800 /* Initialize the fc rport list head.
1801 */ 1801 */
1802 INIT_LIST_HEAD(&ioc->fc_rports); 1802 INIT_LIST_HEAD(&ioc->fc_rports);
1803 1803
1804 /* Find lookup slot. */ 1804 /* Find lookup slot. */
1805 INIT_LIST_HEAD(&ioc->list); 1805 INIT_LIST_HEAD(&ioc->list);
1806 1806
1807 1807
1808 /* Initialize workqueue */ 1808 /* Initialize workqueue */
1809 INIT_DELAYED_WORK(&ioc->fault_reset_work, mpt_fault_reset_work); 1809 INIT_DELAYED_WORK(&ioc->fault_reset_work, mpt_fault_reset_work);
1810 1810
1811 snprintf(ioc->reset_work_q_name, MPT_KOBJ_NAME_LEN, 1811 snprintf(ioc->reset_work_q_name, MPT_KOBJ_NAME_LEN,
1812 "mpt_poll_%d", ioc->id); 1812 "mpt_poll_%d", ioc->id);
1813 ioc->reset_work_q = 1813 ioc->reset_work_q =
1814 create_singlethread_workqueue(ioc->reset_work_q_name); 1814 create_singlethread_workqueue(ioc->reset_work_q_name);
1815 if (!ioc->reset_work_q) { 1815 if (!ioc->reset_work_q) {
1816 printk(MYIOC_s_ERR_FMT "Insufficient memory to add adapter!\n", 1816 printk(MYIOC_s_ERR_FMT "Insufficient memory to add adapter!\n",
1817 ioc->name); 1817 ioc->name);
1818 pci_release_selected_regions(pdev, ioc->bars); 1818 pci_release_selected_regions(pdev, ioc->bars);
1819 kfree(ioc); 1819 kfree(ioc);
1820 return -ENOMEM; 1820 return -ENOMEM;
1821 } 1821 }
1822 1822
1823 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "facts @ %p, pfacts[0] @ %p\n", 1823 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "facts @ %p, pfacts[0] @ %p\n",
1824 ioc->name, &ioc->facts, &ioc->pfacts[0])); 1824 ioc->name, &ioc->facts, &ioc->pfacts[0]));
1825 1825
1826 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision); 1826 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1827 mpt_get_product_name(pdev->vendor, pdev->device, revision, ioc->prod_name); 1827 mpt_get_product_name(pdev->vendor, pdev->device, revision, ioc->prod_name);
1828 1828
1829 switch (pdev->device) 1829 switch (pdev->device)
1830 { 1830 {
1831 case MPI_MANUFACTPAGE_DEVICEID_FC939X: 1831 case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1832 case MPI_MANUFACTPAGE_DEVICEID_FC949X: 1832 case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1833 ioc->errata_flag_1064 = 1; 1833 ioc->errata_flag_1064 = 1;
1834 case MPI_MANUFACTPAGE_DEVICEID_FC909: 1834 case MPI_MANUFACTPAGE_DEVICEID_FC909:
1835 case MPI_MANUFACTPAGE_DEVICEID_FC929: 1835 case MPI_MANUFACTPAGE_DEVICEID_FC929:
1836 case MPI_MANUFACTPAGE_DEVICEID_FC919: 1836 case MPI_MANUFACTPAGE_DEVICEID_FC919:
1837 case MPI_MANUFACTPAGE_DEVICEID_FC949E: 1837 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1838 ioc->bus_type = FC; 1838 ioc->bus_type = FC;
1839 break; 1839 break;
1840 1840
1841 case MPI_MANUFACTPAGE_DEVICEID_FC929X: 1841 case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1842 if (revision < XL_929) { 1842 if (revision < XL_929) {
1843 /* 929X Chip Fix. Set Split transactions level 1843 /* 929X Chip Fix. Set Split transactions level
1844 * for PCIX. Set MOST bits to zero. 1844 * for PCIX. Set MOST bits to zero.
1845 */ 1845 */
1846 pci_read_config_byte(pdev, 0x6a, &pcixcmd); 1846 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1847 pcixcmd &= 0x8F; 1847 pcixcmd &= 0x8F;
1848 pci_write_config_byte(pdev, 0x6a, pcixcmd); 1848 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1849 } else { 1849 } else {
1850 /* 929XL Chip Fix. Set MMRBC to 0x08. 1850 /* 929XL Chip Fix. Set MMRBC to 0x08.
1851 */ 1851 */
1852 pci_read_config_byte(pdev, 0x6a, &pcixcmd); 1852 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1853 pcixcmd |= 0x08; 1853 pcixcmd |= 0x08;
1854 pci_write_config_byte(pdev, 0x6a, pcixcmd); 1854 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1855 } 1855 }
1856 ioc->bus_type = FC; 1856 ioc->bus_type = FC;
1857 break; 1857 break;
1858 1858
1859 case MPI_MANUFACTPAGE_DEVICEID_FC919X: 1859 case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1860 /* 919X Chip Fix. Set Split transactions level 1860 /* 919X Chip Fix. Set Split transactions level
1861 * for PCIX. Set MOST bits to zero. 1861 * for PCIX. Set MOST bits to zero.
1862 */ 1862 */
1863 pci_read_config_byte(pdev, 0x6a, &pcixcmd); 1863 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1864 pcixcmd &= 0x8F; 1864 pcixcmd &= 0x8F;
1865 pci_write_config_byte(pdev, 0x6a, pcixcmd); 1865 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1866 ioc->bus_type = FC; 1866 ioc->bus_type = FC;
1867 break; 1867 break;
1868 1868
1869 case MPI_MANUFACTPAGE_DEVID_53C1030: 1869 case MPI_MANUFACTPAGE_DEVID_53C1030:
1870 /* 1030 Chip Fix. Disable Split transactions 1870 /* 1030 Chip Fix. Disable Split transactions
1871 * for PCIX. Set MOST bits to zero if Rev < C0( = 8). 1871 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1872 */ 1872 */
1873 if (revision < C0_1030) { 1873 if (revision < C0_1030) {
1874 pci_read_config_byte(pdev, 0x6a, &pcixcmd); 1874 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1875 pcixcmd &= 0x8F; 1875 pcixcmd &= 0x8F;
1876 pci_write_config_byte(pdev, 0x6a, pcixcmd); 1876 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1877 } 1877 }
1878 1878
1879 case MPI_MANUFACTPAGE_DEVID_1030_53C1035: 1879 case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1880 ioc->bus_type = SPI; 1880 ioc->bus_type = SPI;
1881 break; 1881 break;
1882 1882
1883 case MPI_MANUFACTPAGE_DEVID_SAS1064: 1883 case MPI_MANUFACTPAGE_DEVID_SAS1064:
1884 case MPI_MANUFACTPAGE_DEVID_SAS1068: 1884 case MPI_MANUFACTPAGE_DEVID_SAS1068:
1885 ioc->errata_flag_1064 = 1; 1885 ioc->errata_flag_1064 = 1;
1886 ioc->bus_type = SAS; 1886 ioc->bus_type = SAS;
1887 break; 1887 break;
1888 1888
1889 case MPI_MANUFACTPAGE_DEVID_SAS1064E: 1889 case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1890 case MPI_MANUFACTPAGE_DEVID_SAS1068E: 1890 case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1891 case MPI_MANUFACTPAGE_DEVID_SAS1078: 1891 case MPI_MANUFACTPAGE_DEVID_SAS1078:
1892 ioc->bus_type = SAS; 1892 ioc->bus_type = SAS;
1893 break; 1893 break;
1894 } 1894 }
1895 1895
1896 1896
1897 switch (ioc->bus_type) { 1897 switch (ioc->bus_type) {
1898 1898
1899 case SAS: 1899 case SAS:
1900 ioc->msi_enable = mpt_msi_enable_sas; 1900 ioc->msi_enable = mpt_msi_enable_sas;
1901 break; 1901 break;
1902 1902
1903 case SPI: 1903 case SPI:
1904 ioc->msi_enable = mpt_msi_enable_spi; 1904 ioc->msi_enable = mpt_msi_enable_spi;
1905 break; 1905 break;
1906 1906
1907 case FC: 1907 case FC:
1908 ioc->msi_enable = mpt_msi_enable_fc; 1908 ioc->msi_enable = mpt_msi_enable_fc;
1909 break; 1909 break;
1910 1910
1911 default: 1911 default:
1912 ioc->msi_enable = 0; 1912 ioc->msi_enable = 0;
1913 break; 1913 break;
1914 } 1914 }
1915 if (ioc->errata_flag_1064) 1915 if (ioc->errata_flag_1064)
1916 pci_disable_io_access(pdev); 1916 pci_disable_io_access(pdev);
1917 1917
1918 spin_lock_init(&ioc->FreeQlock); 1918 spin_lock_init(&ioc->FreeQlock);
1919 1919
1920 /* Disable all! */ 1920 /* Disable all! */
1921 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF); 1921 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1922 ioc->active = 0; 1922 ioc->active = 0;
1923 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); 1923 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1924 1924
1925 /* Set IOC ptr in the pcidev's driver data. */ 1925 /* Set IOC ptr in the pcidev's driver data. */
1926 pci_set_drvdata(ioc->pcidev, ioc); 1926 pci_set_drvdata(ioc->pcidev, ioc);
1927 1927
1928 /* Set lookup ptr. */ 1928 /* Set lookup ptr. */
1929 list_add_tail(&ioc->list, &ioc_list); 1929 list_add_tail(&ioc->list, &ioc_list);
1930 1930
1931 /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets. 1931 /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1932 */ 1932 */
1933 mpt_detect_bound_ports(ioc, pdev); 1933 mpt_detect_bound_ports(ioc, pdev);
1934 1934
1935 INIT_LIST_HEAD(&ioc->fw_event_list); 1935 INIT_LIST_HEAD(&ioc->fw_event_list);
1936 spin_lock_init(&ioc->fw_event_lock); 1936 spin_lock_init(&ioc->fw_event_lock);
1937 snprintf(ioc->fw_event_q_name, MPT_KOBJ_NAME_LEN, "mpt/%d", ioc->id); 1937 snprintf(ioc->fw_event_q_name, MPT_KOBJ_NAME_LEN, "mpt/%d", ioc->id);
1938 ioc->fw_event_q = create_singlethread_workqueue(ioc->fw_event_q_name); 1938 ioc->fw_event_q = create_singlethread_workqueue(ioc->fw_event_q_name);
1939 1939
1940 if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP, 1940 if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
1941 CAN_SLEEP)) != 0){ 1941 CAN_SLEEP)) != 0){
1942 printk(MYIOC_s_ERR_FMT "didn't initialize properly! (%d)\n", 1942 printk(MYIOC_s_ERR_FMT "didn't initialize properly! (%d)\n",
1943 ioc->name, r); 1943 ioc->name, r);
1944 1944
1945 list_del(&ioc->list); 1945 list_del(&ioc->list);
1946 if (ioc->alt_ioc) 1946 if (ioc->alt_ioc)
1947 ioc->alt_ioc->alt_ioc = NULL; 1947 ioc->alt_ioc->alt_ioc = NULL;
1948 iounmap(ioc->memmap); 1948 iounmap(ioc->memmap);
1949 if (r != -5) 1949 if (r != -5)
1950 pci_release_selected_regions(pdev, ioc->bars); 1950 pci_release_selected_regions(pdev, ioc->bars);
1951 1951
1952 destroy_workqueue(ioc->reset_work_q); 1952 destroy_workqueue(ioc->reset_work_q);
1953 ioc->reset_work_q = NULL; 1953 ioc->reset_work_q = NULL;
1954 1954
1955 kfree(ioc); 1955 kfree(ioc);
1956 pci_set_drvdata(pdev, NULL); 1956 pci_set_drvdata(pdev, NULL);
1957 return r; 1957 return r;
1958 } 1958 }
1959 1959
1960 /* call per device driver probe entry point */ 1960 /* call per device driver probe entry point */
1961 for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) { 1961 for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
1962 if(MptDeviceDriverHandlers[cb_idx] && 1962 if(MptDeviceDriverHandlers[cb_idx] &&
1963 MptDeviceDriverHandlers[cb_idx]->probe) { 1963 MptDeviceDriverHandlers[cb_idx]->probe) {
1964 MptDeviceDriverHandlers[cb_idx]->probe(pdev,id); 1964 MptDeviceDriverHandlers[cb_idx]->probe(pdev,id);
1965 } 1965 }
1966 } 1966 }
1967 1967
1968 #ifdef CONFIG_PROC_FS 1968 #ifdef CONFIG_PROC_FS
1969 /* 1969 /*
1970 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter. 1970 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
1971 */ 1971 */
1972 dent = proc_mkdir(ioc->name, mpt_proc_root_dir); 1972 dent = proc_mkdir(ioc->name, mpt_proc_root_dir);
1973 if (dent) { 1973 if (dent) {
1974 ent = create_proc_entry("info", S_IFREG|S_IRUGO, dent); 1974 ent = create_proc_entry("info", S_IFREG|S_IRUGO, dent);
1975 if (ent) { 1975 if (ent) {
1976 ent->read_proc = procmpt_iocinfo_read; 1976 ent->read_proc = procmpt_iocinfo_read;
1977 ent->data = ioc; 1977 ent->data = ioc;
1978 } 1978 }
1979 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, dent); 1979 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, dent);
1980 if (ent) { 1980 if (ent) {
1981 ent->read_proc = procmpt_summary_read; 1981 ent->read_proc = procmpt_summary_read;
1982 ent->data = ioc; 1982 ent->data = ioc;
1983 } 1983 }
1984 } 1984 }
1985 #endif 1985 #endif
1986 1986
1987 if (!ioc->alt_ioc) 1987 if (!ioc->alt_ioc)
1988 queue_delayed_work(ioc->reset_work_q, &ioc->fault_reset_work, 1988 queue_delayed_work(ioc->reset_work_q, &ioc->fault_reset_work,
1989 msecs_to_jiffies(MPT_POLLING_INTERVAL)); 1989 msecs_to_jiffies(MPT_POLLING_INTERVAL));
1990 1990
1991 return 0; 1991 return 0;
1992 } 1992 }
1993 1993
1994 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1994 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1995 /** 1995 /**
1996 * mpt_detach - Remove a PCI intelligent MPT adapter. 1996 * mpt_detach - Remove a PCI intelligent MPT adapter.
1997 * @pdev: Pointer to pci_dev structure 1997 * @pdev: Pointer to pci_dev structure
1998 */ 1998 */
1999 1999
2000 void 2000 void
2001 mpt_detach(struct pci_dev *pdev) 2001 mpt_detach(struct pci_dev *pdev)
2002 { 2002 {
2003 MPT_ADAPTER *ioc = pci_get_drvdata(pdev); 2003 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2004 char pname[32]; 2004 char pname[32];
2005 u8 cb_idx; 2005 u8 cb_idx;
2006 unsigned long flags; 2006 unsigned long flags;
2007 struct workqueue_struct *wq; 2007 struct workqueue_struct *wq;
2008 2008
2009 /* 2009 /*
2010 * Stop polling ioc for fault condition 2010 * Stop polling ioc for fault condition
2011 */ 2011 */
2012 spin_lock_irqsave(&ioc->taskmgmt_lock, flags); 2012 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
2013 wq = ioc->reset_work_q; 2013 wq = ioc->reset_work_q;
2014 ioc->reset_work_q = NULL; 2014 ioc->reset_work_q = NULL;
2015 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags); 2015 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2016 cancel_delayed_work(&ioc->fault_reset_work); 2016 cancel_delayed_work(&ioc->fault_reset_work);
2017 destroy_workqueue(wq); 2017 destroy_workqueue(wq);
2018 2018
2019 spin_lock_irqsave(&ioc->fw_event_lock, flags); 2019 spin_lock_irqsave(&ioc->fw_event_lock, flags);
2020 wq = ioc->fw_event_q; 2020 wq = ioc->fw_event_q;
2021 ioc->fw_event_q = NULL; 2021 ioc->fw_event_q = NULL;
2022 spin_unlock_irqrestore(&ioc->fw_event_lock, flags); 2022 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
2023 destroy_workqueue(wq); 2023 destroy_workqueue(wq);
2024 2024
2025 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name); 2025 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
2026 remove_proc_entry(pname, NULL); 2026 remove_proc_entry(pname, NULL);
2027 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name); 2027 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name);
2028 remove_proc_entry(pname, NULL); 2028 remove_proc_entry(pname, NULL);
2029 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name); 2029 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
2030 remove_proc_entry(pname, NULL); 2030 remove_proc_entry(pname, NULL);
2031 2031
2032 /* call per device driver remove entry point */ 2032 /* call per device driver remove entry point */
2033 for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) { 2033 for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
2034 if(MptDeviceDriverHandlers[cb_idx] && 2034 if(MptDeviceDriverHandlers[cb_idx] &&
2035 MptDeviceDriverHandlers[cb_idx]->remove) { 2035 MptDeviceDriverHandlers[cb_idx]->remove) {
2036 MptDeviceDriverHandlers[cb_idx]->remove(pdev); 2036 MptDeviceDriverHandlers[cb_idx]->remove(pdev);
2037 } 2037 }
2038 } 2038 }
2039 2039
2040 /* Disable interrupts! */ 2040 /* Disable interrupts! */
2041 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF); 2041 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2042 2042
2043 ioc->active = 0; 2043 ioc->active = 0;
2044 synchronize_irq(pdev->irq); 2044 synchronize_irq(pdev->irq);
2045 2045
2046 /* Clear any lingering interrupt */ 2046 /* Clear any lingering interrupt */
2047 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); 2047 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2048 2048
2049 CHIPREG_READ32(&ioc->chip->IntStatus); 2049 CHIPREG_READ32(&ioc->chip->IntStatus);
2050 2050
2051 mpt_adapter_dispose(ioc); 2051 mpt_adapter_dispose(ioc);
2052 2052
2053 pci_set_drvdata(pdev, NULL); 2053 pci_set_drvdata(pdev, NULL);
2054 } 2054 }
2055 2055
2056 /************************************************************************** 2056 /**************************************************************************
2057 * Power Management 2057 * Power Management
2058 */ 2058 */
2059 #ifdef CONFIG_PM 2059 #ifdef CONFIG_PM
2060 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2060 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2061 /** 2061 /**
2062 * mpt_suspend - Fusion MPT base driver suspend routine. 2062 * mpt_suspend - Fusion MPT base driver suspend routine.
2063 * @pdev: Pointer to pci_dev structure 2063 * @pdev: Pointer to pci_dev structure
2064 * @state: new state to enter 2064 * @state: new state to enter
2065 */ 2065 */
2066 int 2066 int
2067 mpt_suspend(struct pci_dev *pdev, pm_message_t state) 2067 mpt_suspend(struct pci_dev *pdev, pm_message_t state)
2068 { 2068 {
2069 u32 device_state; 2069 u32 device_state;
2070 MPT_ADAPTER *ioc = pci_get_drvdata(pdev); 2070 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2071 2071
2072 device_state = pci_choose_state(pdev, state); 2072 device_state = pci_choose_state(pdev, state);
2073 printk(MYIOC_s_INFO_FMT "pci-suspend: pdev=0x%p, slot=%s, Entering " 2073 printk(MYIOC_s_INFO_FMT "pci-suspend: pdev=0x%p, slot=%s, Entering "
2074 "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev), 2074 "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev),
2075 device_state); 2075 device_state);
2076 2076
2077 /* put ioc into READY_STATE */ 2077 /* put ioc into READY_STATE */
2078 if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) { 2078 if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
2079 printk(MYIOC_s_ERR_FMT 2079 printk(MYIOC_s_ERR_FMT
2080 "pci-suspend: IOC msg unit reset failed!\n", ioc->name); 2080 "pci-suspend: IOC msg unit reset failed!\n", ioc->name);
2081 } 2081 }
2082 2082
2083 /* disable interrupts */ 2083 /* disable interrupts */
2084 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF); 2084 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2085 ioc->active = 0; 2085 ioc->active = 0;
2086 2086
2087 /* Clear any lingering interrupt */ 2087 /* Clear any lingering interrupt */
2088 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); 2088 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2089 2089
2090 free_irq(ioc->pci_irq, ioc); 2090 free_irq(ioc->pci_irq, ioc);
2091 if (ioc->msi_enable) 2091 if (ioc->msi_enable)
2092 pci_disable_msi(ioc->pcidev); 2092 pci_disable_msi(ioc->pcidev);
2093 ioc->pci_irq = -1; 2093 ioc->pci_irq = -1;
2094 pci_save_state(pdev); 2094 pci_save_state(pdev);
2095 pci_disable_device(pdev); 2095 pci_disable_device(pdev);
2096 pci_release_selected_regions(pdev, ioc->bars); 2096 pci_release_selected_regions(pdev, ioc->bars);
2097 pci_set_power_state(pdev, device_state); 2097 pci_set_power_state(pdev, device_state);
2098 return 0; 2098 return 0;
2099 } 2099 }
2100 2100
2101 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2101 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2102 /** 2102 /**
2103 * mpt_resume - Fusion MPT base driver resume routine. 2103 * mpt_resume - Fusion MPT base driver resume routine.
2104 * @pdev: Pointer to pci_dev structure 2104 * @pdev: Pointer to pci_dev structure
2105 */ 2105 */
2106 int 2106 int
2107 mpt_resume(struct pci_dev *pdev) 2107 mpt_resume(struct pci_dev *pdev)
2108 { 2108 {
2109 MPT_ADAPTER *ioc = pci_get_drvdata(pdev); 2109 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2110 u32 device_state = pdev->current_state; 2110 u32 device_state = pdev->current_state;
2111 int recovery_state; 2111 int recovery_state;
2112 int err; 2112 int err;
2113 2113
2114 printk(MYIOC_s_INFO_FMT "pci-resume: pdev=0x%p, slot=%s, Previous " 2114 printk(MYIOC_s_INFO_FMT "pci-resume: pdev=0x%p, slot=%s, Previous "
2115 "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev), 2115 "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev),
2116 device_state); 2116 device_state);
2117 2117
2118 pci_set_power_state(pdev, PCI_D0); 2118 pci_set_power_state(pdev, PCI_D0);
2119 pci_enable_wake(pdev, PCI_D0, 0); 2119 pci_enable_wake(pdev, PCI_D0, 0);
2120 pci_restore_state(pdev); 2120 pci_restore_state(pdev);
2121 ioc->pcidev = pdev; 2121 ioc->pcidev = pdev;
2122 err = mpt_mapresources(ioc); 2122 err = mpt_mapresources(ioc);
2123 if (err) 2123 if (err)
2124 return err; 2124 return err;
2125 2125
2126 if (ioc->dma_mask == DMA_BIT_MASK(64)) { 2126 if (ioc->dma_mask == DMA_BIT_MASK(64)) {
2127 if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) 2127 if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078)
2128 ioc->add_sge = &mpt_add_sge_64bit_1078; 2128 ioc->add_sge = &mpt_add_sge_64bit_1078;
2129 else 2129 else
2130 ioc->add_sge = &mpt_add_sge_64bit; 2130 ioc->add_sge = &mpt_add_sge_64bit;
2131 ioc->add_chain = &mpt_add_chain_64bit; 2131 ioc->add_chain = &mpt_add_chain_64bit;
2132 ioc->sg_addr_size = 8; 2132 ioc->sg_addr_size = 8;
2133 } else { 2133 } else {
2134 2134
2135 ioc->add_sge = &mpt_add_sge; 2135 ioc->add_sge = &mpt_add_sge;
2136 ioc->add_chain = &mpt_add_chain; 2136 ioc->add_chain = &mpt_add_chain;
2137 ioc->sg_addr_size = 4; 2137 ioc->sg_addr_size = 4;
2138 } 2138 }
2139 ioc->SGE_size = sizeof(u32) + ioc->sg_addr_size; 2139 ioc->SGE_size = sizeof(u32) + ioc->sg_addr_size;
2140 2140
2141 printk(MYIOC_s_INFO_FMT "pci-resume: ioc-state=0x%x,doorbell=0x%x\n", 2141 printk(MYIOC_s_INFO_FMT "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
2142 ioc->name, (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT), 2142 ioc->name, (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
2143 CHIPREG_READ32(&ioc->chip->Doorbell)); 2143 CHIPREG_READ32(&ioc->chip->Doorbell));
2144 2144
2145 /* 2145 /*
2146 * Errata workaround for SAS pci express: 2146 * Errata workaround for SAS pci express:
2147 * Upon returning to the D0 state, the contents of the doorbell will be 2147 * Upon returning to the D0 state, the contents of the doorbell will be
2148 * stale data, and this will incorrectly signal to the host driver that 2148 * stale data, and this will incorrectly signal to the host driver that
2149 * the firmware is ready to process mpt commands. The workaround is 2149 * the firmware is ready to process mpt commands. The workaround is
2150 * to issue a diagnostic reset. 2150 * to issue a diagnostic reset.
2151 */ 2151 */
2152 if (ioc->bus_type == SAS && (pdev->device == 2152 if (ioc->bus_type == SAS && (pdev->device ==
2153 MPI_MANUFACTPAGE_DEVID_SAS1068E || pdev->device == 2153 MPI_MANUFACTPAGE_DEVID_SAS1068E || pdev->device ==
2154 MPI_MANUFACTPAGE_DEVID_SAS1064E)) { 2154 MPI_MANUFACTPAGE_DEVID_SAS1064E)) {
2155 if (KickStart(ioc, 1, CAN_SLEEP) < 0) { 2155 if (KickStart(ioc, 1, CAN_SLEEP) < 0) {
2156 printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover\n", 2156 printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover\n",
2157 ioc->name); 2157 ioc->name);
2158 goto out; 2158 goto out;
2159 } 2159 }
2160 } 2160 }
2161 2161
2162 /* bring ioc to operational state */ 2162 /* bring ioc to operational state */
2163 printk(MYIOC_s_INFO_FMT "Sending mpt_do_ioc_recovery\n", ioc->name); 2163 printk(MYIOC_s_INFO_FMT "Sending mpt_do_ioc_recovery\n", ioc->name);
2164 recovery_state = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP, 2164 recovery_state = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
2165 CAN_SLEEP); 2165 CAN_SLEEP);
2166 if (recovery_state != 0) 2166 if (recovery_state != 0)
2167 printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover, " 2167 printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover, "
2168 "error:[%x]\n", ioc->name, recovery_state); 2168 "error:[%x]\n", ioc->name, recovery_state);
2169 else 2169 else
2170 printk(MYIOC_s_INFO_FMT 2170 printk(MYIOC_s_INFO_FMT
2171 "pci-resume: success\n", ioc->name); 2171 "pci-resume: success\n", ioc->name);
2172 out: 2172 out:
2173 return 0; 2173 return 0;
2174 2174
2175 } 2175 }
2176 #endif 2176 #endif
2177 2177
2178 static int 2178 static int
2179 mpt_signal_reset(u8 index, MPT_ADAPTER *ioc, int reset_phase) 2179 mpt_signal_reset(u8 index, MPT_ADAPTER *ioc, int reset_phase)
2180 { 2180 {
2181 if ((MptDriverClass[index] == MPTSPI_DRIVER && 2181 if ((MptDriverClass[index] == MPTSPI_DRIVER &&
2182 ioc->bus_type != SPI) || 2182 ioc->bus_type != SPI) ||
2183 (MptDriverClass[index] == MPTFC_DRIVER && 2183 (MptDriverClass[index] == MPTFC_DRIVER &&
2184 ioc->bus_type != FC) || 2184 ioc->bus_type != FC) ||
2185 (MptDriverClass[index] == MPTSAS_DRIVER && 2185 (MptDriverClass[index] == MPTSAS_DRIVER &&
2186 ioc->bus_type != SAS)) 2186 ioc->bus_type != SAS))
2187 /* make sure we only call the relevant reset handler 2187 /* make sure we only call the relevant reset handler
2188 * for the bus */ 2188 * for the bus */
2189 return 0; 2189 return 0;
2190 return (MptResetHandlers[index])(ioc, reset_phase); 2190 return (MptResetHandlers[index])(ioc, reset_phase);
2191 } 2191 }
2192 2192
2193 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2193 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2194 /** 2194 /**
2195 * mpt_do_ioc_recovery - Initialize or recover MPT adapter. 2195 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
2196 * @ioc: Pointer to MPT adapter structure 2196 * @ioc: Pointer to MPT adapter structure
2197 * @reason: Event word / reason 2197 * @reason: Event word / reason
2198 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay. 2198 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
2199 * 2199 *
2200 * This routine performs all the steps necessary to bring the IOC 2200 * This routine performs all the steps necessary to bring the IOC
2201 * to a OPERATIONAL state. 2201 * to a OPERATIONAL state.
2202 * 2202 *
2203 * This routine also pre-fetches the LAN MAC address of a Fibre Channel 2203 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
2204 * MPT adapter. 2204 * MPT adapter.
2205 * 2205 *
2206 * Returns: 2206 * Returns:
2207 * 0 for success 2207 * 0 for success
2208 * -1 if failed to get board READY 2208 * -1 if failed to get board READY
2209 * -2 if READY but IOCFacts Failed 2209 * -2 if READY but IOCFacts Failed
2210 * -3 if READY but PrimeIOCFifos Failed 2210 * -3 if READY but PrimeIOCFifos Failed
2211 * -4 if READY but IOCInit Failed 2211 * -4 if READY but IOCInit Failed
2212 * -5 if failed to enable_device and/or request_selected_regions 2212 * -5 if failed to enable_device and/or request_selected_regions
2213 * -6 if failed to upload firmware 2213 * -6 if failed to upload firmware
2214 */ 2214 */
2215 static int 2215 static int
2216 mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag) 2216 mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
2217 { 2217 {
2218 int hard_reset_done = 0; 2218 int hard_reset_done = 0;
2219 int alt_ioc_ready = 0; 2219 int alt_ioc_ready = 0;
2220 int hard; 2220 int hard;
2221 int rc=0; 2221 int rc=0;
2222 int ii; 2222 int ii;
2223 int ret = 0; 2223 int ret = 0;
2224 int reset_alt_ioc_active = 0; 2224 int reset_alt_ioc_active = 0;
2225 int irq_allocated = 0; 2225 int irq_allocated = 0;
2226 u8 *a; 2226 u8 *a;
2227 2227
2228 printk(MYIOC_s_INFO_FMT "Initiating %s\n", ioc->name, 2228 printk(MYIOC_s_INFO_FMT "Initiating %s\n", ioc->name,
2229 reason == MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery"); 2229 reason == MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
2230 2230
2231 /* Disable reply interrupts (also blocks FreeQ) */ 2231 /* Disable reply interrupts (also blocks FreeQ) */
2232 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF); 2232 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2233 ioc->active = 0; 2233 ioc->active = 0;
2234 2234
2235 if (ioc->alt_ioc) { 2235 if (ioc->alt_ioc) {
2236 if (ioc->alt_ioc->active || 2236 if (ioc->alt_ioc->active ||
2237 reason == MPT_HOSTEVENT_IOC_RECOVER) { 2237 reason == MPT_HOSTEVENT_IOC_RECOVER) {
2238 reset_alt_ioc_active = 1; 2238 reset_alt_ioc_active = 1;
2239 /* Disable alt-IOC's reply interrupts 2239 /* Disable alt-IOC's reply interrupts
2240 * (and FreeQ) for a bit 2240 * (and FreeQ) for a bit
2241 **/ 2241 **/
2242 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 2242 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask,
2243 0xFFFFFFFF); 2243 0xFFFFFFFF);
2244 ioc->alt_ioc->active = 0; 2244 ioc->alt_ioc->active = 0;
2245 } 2245 }
2246 } 2246 }
2247 2247
2248 hard = 1; 2248 hard = 1;
2249 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) 2249 if (reason == MPT_HOSTEVENT_IOC_BRINGUP)
2250 hard = 0; 2250 hard = 0;
2251 2251
2252 if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) { 2252 if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {
2253 if (hard_reset_done == -4) { 2253 if (hard_reset_done == -4) {
2254 printk(MYIOC_s_WARN_FMT "Owned by PEER..skipping!\n", 2254 printk(MYIOC_s_WARN_FMT "Owned by PEER..skipping!\n",
2255 ioc->name); 2255 ioc->name);
2256 2256
2257 if (reset_alt_ioc_active && ioc->alt_ioc) { 2257 if (reset_alt_ioc_active && ioc->alt_ioc) {
2258 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */ 2258 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
2259 dprintk(ioc, printk(MYIOC_s_INFO_FMT 2259 dprintk(ioc, printk(MYIOC_s_INFO_FMT
2260 "alt_ioc reply irq re-enabled\n", ioc->alt_ioc->name)); 2260 "alt_ioc reply irq re-enabled\n", ioc->alt_ioc->name));
2261 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM); 2261 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
2262 ioc->alt_ioc->active = 1; 2262 ioc->alt_ioc->active = 1;
2263 } 2263 }
2264 2264
2265 } else { 2265 } else {
2266 printk(MYIOC_s_WARN_FMT 2266 printk(MYIOC_s_WARN_FMT
2267 "NOT READY WARNING!\n", ioc->name); 2267 "NOT READY WARNING!\n", ioc->name);
2268 } 2268 }
2269 ret = -1; 2269 ret = -1;
2270 goto out; 2270 goto out;
2271 } 2271 }
2272 2272
2273 /* hard_reset_done = 0 if a soft reset was performed 2273 /* hard_reset_done = 0 if a soft reset was performed
2274 * and 1 if a hard reset was performed. 2274 * and 1 if a hard reset was performed.
2275 */ 2275 */
2276 if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) { 2276 if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
2277 if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0) 2277 if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
2278 alt_ioc_ready = 1; 2278 alt_ioc_ready = 1;
2279 else 2279 else
2280 printk(MYIOC_s_WARN_FMT 2280 printk(MYIOC_s_WARN_FMT
2281 ": alt-ioc Not ready WARNING!\n", 2281 ": alt-ioc Not ready WARNING!\n",
2282 ioc->alt_ioc->name); 2282 ioc->alt_ioc->name);
2283 } 2283 }
2284 2284
2285 for (ii=0; ii<5; ii++) { 2285 for (ii=0; ii<5; ii++) {
2286 /* Get IOC facts! Allow 5 retries */ 2286 /* Get IOC facts! Allow 5 retries */
2287 if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0) 2287 if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0)
2288 break; 2288 break;
2289 } 2289 }
2290 2290
2291 2291
2292 if (ii == 5) { 2292 if (ii == 5) {
2293 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT 2293 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2294 "Retry IocFacts failed rc=%x\n", ioc->name, rc)); 2294 "Retry IocFacts failed rc=%x\n", ioc->name, rc));
2295 ret = -2; 2295 ret = -2;
2296 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) { 2296 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2297 MptDisplayIocCapabilities(ioc); 2297 MptDisplayIocCapabilities(ioc);
2298 } 2298 }
2299 2299
2300 if (alt_ioc_ready) { 2300 if (alt_ioc_ready) {
2301 if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) { 2301 if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
2302 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT 2302 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2303 "Initial Alt IocFacts failed rc=%x\n", 2303 "Initial Alt IocFacts failed rc=%x\n",
2304 ioc->name, rc)); 2304 ioc->name, rc));
2305 /* Retry - alt IOC was initialized once 2305 /* Retry - alt IOC was initialized once
2306 */ 2306 */
2307 rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason); 2307 rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
2308 } 2308 }
2309 if (rc) { 2309 if (rc) {
2310 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT 2310 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2311 "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc)); 2311 "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc));
2312 alt_ioc_ready = 0; 2312 alt_ioc_ready = 0;
2313 reset_alt_ioc_active = 0; 2313 reset_alt_ioc_active = 0;
2314 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) { 2314 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2315 MptDisplayIocCapabilities(ioc->alt_ioc); 2315 MptDisplayIocCapabilities(ioc->alt_ioc);
2316 } 2316 }
2317 } 2317 }
2318 2318
2319 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP) && 2319 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP) &&
2320 (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)) { 2320 (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)) {
2321 pci_release_selected_regions(ioc->pcidev, ioc->bars); 2321 pci_release_selected_regions(ioc->pcidev, ioc->bars);
2322 ioc->bars = pci_select_bars(ioc->pcidev, IORESOURCE_MEM | 2322 ioc->bars = pci_select_bars(ioc->pcidev, IORESOURCE_MEM |
2323 IORESOURCE_IO); 2323 IORESOURCE_IO);
2324 if (pci_enable_device(ioc->pcidev)) 2324 if (pci_enable_device(ioc->pcidev))
2325 return -5; 2325 return -5;
2326 if (pci_request_selected_regions(ioc->pcidev, ioc->bars, 2326 if (pci_request_selected_regions(ioc->pcidev, ioc->bars,
2327 "mpt")) 2327 "mpt"))
2328 return -5; 2328 return -5;
2329 } 2329 }
2330 2330
2331 /* 2331 /*
2332 * Device is reset now. It must have de-asserted the interrupt line 2332 * Device is reset now. It must have de-asserted the interrupt line
2333 * (if it was asserted) and it should be safe to register for the 2333 * (if it was asserted) and it should be safe to register for the
2334 * interrupt now. 2334 * interrupt now.
2335 */ 2335 */
2336 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) { 2336 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2337 ioc->pci_irq = -1; 2337 ioc->pci_irq = -1;
2338 if (ioc->pcidev->irq) { 2338 if (ioc->pcidev->irq) {
2339 if (ioc->msi_enable && !pci_enable_msi(ioc->pcidev)) 2339 if (ioc->msi_enable && !pci_enable_msi(ioc->pcidev))
2340 printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n", 2340 printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n",
2341 ioc->name); 2341 ioc->name);
2342 else 2342 else
2343 ioc->msi_enable = 0; 2343 ioc->msi_enable = 0;
2344 rc = request_irq(ioc->pcidev->irq, mpt_interrupt, 2344 rc = request_irq(ioc->pcidev->irq, mpt_interrupt,
2345 IRQF_SHARED, ioc->name, ioc); 2345 IRQF_SHARED, ioc->name, ioc);
2346 if (rc < 0) { 2346 if (rc < 0) {
2347 printk(MYIOC_s_ERR_FMT "Unable to allocate " 2347 printk(MYIOC_s_ERR_FMT "Unable to allocate "
2348 "interrupt %d!\n", 2348 "interrupt %d!\n",
2349 ioc->name, ioc->pcidev->irq); 2349 ioc->name, ioc->pcidev->irq);
2350 if (ioc->msi_enable) 2350 if (ioc->msi_enable)
2351 pci_disable_msi(ioc->pcidev); 2351 pci_disable_msi(ioc->pcidev);
2352 ret = -EBUSY; 2352 ret = -EBUSY;
2353 goto out; 2353 goto out;
2354 } 2354 }
2355 irq_allocated = 1; 2355 irq_allocated = 1;
2356 ioc->pci_irq = ioc->pcidev->irq; 2356 ioc->pci_irq = ioc->pcidev->irq;
2357 pci_set_master(ioc->pcidev); /* ?? */ 2357 pci_set_master(ioc->pcidev); /* ?? */
2358 pci_set_drvdata(ioc->pcidev, ioc); 2358 pci_set_drvdata(ioc->pcidev, ioc);
2359 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT 2359 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2360 "installed at interrupt %d\n", ioc->name, 2360 "installed at interrupt %d\n", ioc->name,
2361 ioc->pcidev->irq)); 2361 ioc->pcidev->irq));
2362 } 2362 }
2363 } 2363 }
2364 2364
2365 /* Prime reply & request queues! 2365 /* Prime reply & request queues!
2366 * (mucho alloc's) Must be done prior to 2366 * (mucho alloc's) Must be done prior to
2367 * init as upper addresses are needed for init. 2367 * init as upper addresses are needed for init.
2368 * If fails, continue with alt-ioc processing 2368 * If fails, continue with alt-ioc processing
2369 */ 2369 */
2370 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "PrimeIocFifos\n", 2370 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "PrimeIocFifos\n",
2371 ioc->name)); 2371 ioc->name));
2372 if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0)) 2372 if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0))
2373 ret = -3; 2373 ret = -3;
2374 2374
2375 /* May need to check/upload firmware & data here! 2375 /* May need to check/upload firmware & data here!
2376 * If fails, continue with alt-ioc processing 2376 * If fails, continue with alt-ioc processing
2377 */ 2377 */
2378 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "SendIocInit\n", 2378 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "SendIocInit\n",
2379 ioc->name)); 2379 ioc->name));
2380 if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0)) 2380 if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0))
2381 ret = -4; 2381 ret = -4;
2382 // NEW! 2382 // NEW!
2383 if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) { 2383 if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
2384 printk(MYIOC_s_WARN_FMT 2384 printk(MYIOC_s_WARN_FMT
2385 ": alt-ioc (%d) FIFO mgmt alloc WARNING!\n", 2385 ": alt-ioc (%d) FIFO mgmt alloc WARNING!\n",
2386 ioc->alt_ioc->name, rc); 2386 ioc->alt_ioc->name, rc);
2387 alt_ioc_ready = 0; 2387 alt_ioc_ready = 0;
2388 reset_alt_ioc_active = 0; 2388 reset_alt_ioc_active = 0;
2389 } 2389 }
2390 2390
2391 if (alt_ioc_ready) { 2391 if (alt_ioc_ready) {
2392 if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) { 2392 if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
2393 alt_ioc_ready = 0; 2393 alt_ioc_ready = 0;
2394 reset_alt_ioc_active = 0; 2394 reset_alt_ioc_active = 0;
2395 printk(MYIOC_s_WARN_FMT 2395 printk(MYIOC_s_WARN_FMT
2396 ": alt-ioc: (%d) init failure WARNING!\n", 2396 ": alt-ioc: (%d) init failure WARNING!\n",
2397 ioc->alt_ioc->name, rc); 2397 ioc->alt_ioc->name, rc);
2398 } 2398 }
2399 } 2399 }
2400 2400
2401 if (reason == MPT_HOSTEVENT_IOC_BRINGUP){ 2401 if (reason == MPT_HOSTEVENT_IOC_BRINGUP){
2402 if (ioc->upload_fw) { 2402 if (ioc->upload_fw) {
2403 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT 2403 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2404 "firmware upload required!\n", ioc->name)); 2404 "firmware upload required!\n", ioc->name));
2405 2405
2406 /* Controller is not operational, cannot do upload 2406 /* Controller is not operational, cannot do upload
2407 */ 2407 */
2408 if (ret == 0) { 2408 if (ret == 0) {
2409 rc = mpt_do_upload(ioc, sleepFlag); 2409 rc = mpt_do_upload(ioc, sleepFlag);
2410 if (rc == 0) { 2410 if (rc == 0) {
2411 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) { 2411 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
2412 /* 2412 /*
2413 * Maintain only one pointer to FW memory 2413 * Maintain only one pointer to FW memory
2414 * so there will not be two attempt to 2414 * so there will not be two attempt to
2415 * downloadboot onboard dual function 2415 * downloadboot onboard dual function
2416 * chips (mpt_adapter_disable, 2416 * chips (mpt_adapter_disable,
2417 * mpt_diag_reset) 2417 * mpt_diag_reset)
2418 */ 2418 */
2419 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT 2419 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2420 "mpt_upload: alt_%s has cached_fw=%p \n", 2420 "mpt_upload: alt_%s has cached_fw=%p \n",
2421 ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw)); 2421 ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));
2422 ioc->cached_fw = NULL; 2422 ioc->cached_fw = NULL;
2423 } 2423 }
2424 } else { 2424 } else {
2425 printk(MYIOC_s_WARN_FMT 2425 printk(MYIOC_s_WARN_FMT
2426 "firmware upload failure!\n", ioc->name); 2426 "firmware upload failure!\n", ioc->name);
2427 ret = -6; 2427 ret = -6;
2428 } 2428 }
2429 } 2429 }
2430 } 2430 }
2431 } 2431 }
2432 2432
2433 /* Enable MPT base driver management of EventNotification 2433 /* Enable MPT base driver management of EventNotification
2434 * and EventAck handling. 2434 * and EventAck handling.
2435 */ 2435 */
2436 if ((ret == 0) && (!ioc->facts.EventState)) { 2436 if ((ret == 0) && (!ioc->facts.EventState)) {
2437 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT 2437 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2438 "SendEventNotification\n", 2438 "SendEventNotification\n",
2439 ioc->name)); 2439 ioc->name));
2440 ret = SendEventNotification(ioc, 1, sleepFlag); /* 1=Enable */ 2440 ret = SendEventNotification(ioc, 1, sleepFlag); /* 1=Enable */
2441 } 2441 }
2442 2442
2443 if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState) 2443 if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
2444 rc = SendEventNotification(ioc->alt_ioc, 1, sleepFlag); 2444 rc = SendEventNotification(ioc->alt_ioc, 1, sleepFlag);
2445 2445
2446 if (ret == 0) { 2446 if (ret == 0) {
2447 /* Enable! (reply interrupt) */ 2447 /* Enable! (reply interrupt) */
2448 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM); 2448 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
2449 ioc->active = 1; 2449 ioc->active = 1;
2450 } 2450 }
2451 if (rc == 0) { /* alt ioc */ 2451 if (rc == 0) { /* alt ioc */
2452 if (reset_alt_ioc_active && ioc->alt_ioc) { 2452 if (reset_alt_ioc_active && ioc->alt_ioc) {
2453 /* (re)Enable alt-IOC! (reply interrupt) */ 2453 /* (re)Enable alt-IOC! (reply interrupt) */
2454 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "alt-ioc" 2454 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "alt-ioc"
2455 "reply irq re-enabled\n", 2455 "reply irq re-enabled\n",
2456 ioc->alt_ioc->name)); 2456 ioc->alt_ioc->name));
2457 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 2457 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask,
2458 MPI_HIM_DIM); 2458 MPI_HIM_DIM);
2459 ioc->alt_ioc->active = 1; 2459 ioc->alt_ioc->active = 1;
2460 } 2460 }
2461 } 2461 }
2462 2462
2463 2463
2464 /* Add additional "reason" check before call to GetLanConfigPages 2464 /* Add additional "reason" check before call to GetLanConfigPages
2465 * (combined with GetIoUnitPage2 call). This prevents a somewhat 2465 * (combined with GetIoUnitPage2 call). This prevents a somewhat
2466 * recursive scenario; GetLanConfigPages times out, timer expired 2466 * recursive scenario; GetLanConfigPages times out, timer expired
2467 * routine calls HardResetHandler, which calls into here again, 2467 * routine calls HardResetHandler, which calls into here again,
2468 * and we try GetLanConfigPages again... 2468 * and we try GetLanConfigPages again...
2469 */ 2469 */
2470 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) { 2470 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2471 2471
2472 /* 2472 /*
2473 * Initalize link list for inactive raid volumes. 2473 * Initalize link list for inactive raid volumes.
2474 */ 2474 */
2475 mutex_init(&ioc->raid_data.inactive_list_mutex); 2475 mutex_init(&ioc->raid_data.inactive_list_mutex);
2476 INIT_LIST_HEAD(&ioc->raid_data.inactive_list); 2476 INIT_LIST_HEAD(&ioc->raid_data.inactive_list);
2477 2477
2478 switch (ioc->bus_type) { 2478 switch (ioc->bus_type) {
2479 2479
2480 case SAS: 2480 case SAS:
2481 /* clear persistency table */ 2481 /* clear persistency table */
2482 if(ioc->facts.IOCExceptions & 2482 if(ioc->facts.IOCExceptions &
2483 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) { 2483 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) {
2484 ret = mptbase_sas_persist_operation(ioc, 2484 ret = mptbase_sas_persist_operation(ioc,
2485 MPI_SAS_OP_CLEAR_NOT_PRESENT); 2485 MPI_SAS_OP_CLEAR_NOT_PRESENT);
2486 if(ret != 0) 2486 if(ret != 0)
2487 goto out; 2487 goto out;
2488 } 2488 }
2489 2489
2490 /* Find IM volumes 2490 /* Find IM volumes
2491 */ 2491 */
2492 mpt_findImVolumes(ioc); 2492 mpt_findImVolumes(ioc);
2493 2493
2494 /* Check, and possibly reset, the coalescing value 2494 /* Check, and possibly reset, the coalescing value
2495 */ 2495 */
2496 mpt_read_ioc_pg_1(ioc); 2496 mpt_read_ioc_pg_1(ioc);
2497 2497
2498 break; 2498 break;
2499 2499
2500 case FC: 2500 case FC:
2501 if ((ioc->pfacts[0].ProtocolFlags & 2501 if ((ioc->pfacts[0].ProtocolFlags &
2502 MPI_PORTFACTS_PROTOCOL_LAN) && 2502 MPI_PORTFACTS_PROTOCOL_LAN) &&
2503 (ioc->lan_cnfg_page0.Header.PageLength == 0)) { 2503 (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
2504 /* 2504 /*
2505 * Pre-fetch the ports LAN MAC address! 2505 * Pre-fetch the ports LAN MAC address!
2506 * (LANPage1_t stuff) 2506 * (LANPage1_t stuff)
2507 */ 2507 */
2508 (void) GetLanConfigPages(ioc); 2508 (void) GetLanConfigPages(ioc);
2509 a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow; 2509 a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
2510 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT 2510 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2511 "LanAddr = %02X:%02X:%02X" 2511 "LanAddr = %02X:%02X:%02X"
2512 ":%02X:%02X:%02X\n", 2512 ":%02X:%02X:%02X\n",
2513 ioc->name, a[5], a[4], 2513 ioc->name, a[5], a[4],
2514 a[3], a[2], a[1], a[0])); 2514 a[3], a[2], a[1], a[0]));
2515 } 2515 }
2516 break; 2516 break;
2517 2517
2518 case SPI: 2518 case SPI:
2519 /* Get NVRAM and adapter maximums from SPP 0 and 2 2519 /* Get NVRAM and adapter maximums from SPP 0 and 2
2520 */ 2520 */
2521 mpt_GetScsiPortSettings(ioc, 0); 2521 mpt_GetScsiPortSettings(ioc, 0);
2522 2522
2523 /* Get version and length of SDP 1 2523 /* Get version and length of SDP 1
2524 */ 2524 */
2525 mpt_readScsiDevicePageHeaders(ioc, 0); 2525 mpt_readScsiDevicePageHeaders(ioc, 0);
2526 2526
2527 /* Find IM volumes 2527 /* Find IM volumes
2528 */ 2528 */
2529 if (ioc->facts.MsgVersion >= MPI_VERSION_01_02) 2529 if (ioc->facts.MsgVersion >= MPI_VERSION_01_02)
2530 mpt_findImVolumes(ioc); 2530 mpt_findImVolumes(ioc);
2531 2531
2532 /* Check, and possibly reset, the coalescing value 2532 /* Check, and possibly reset, the coalescing value
2533 */ 2533 */
2534 mpt_read_ioc_pg_1(ioc); 2534 mpt_read_ioc_pg_1(ioc);
2535 2535
2536 mpt_read_ioc_pg_4(ioc); 2536 mpt_read_ioc_pg_4(ioc);
2537 2537
2538 break; 2538 break;
2539 } 2539 }
2540 2540
2541 GetIoUnitPage2(ioc); 2541 GetIoUnitPage2(ioc);
2542 mpt_get_manufacturing_pg_0(ioc); 2542 mpt_get_manufacturing_pg_0(ioc);
2543 } 2543 }
2544 2544
2545 out: 2545 out:
2546 if ((ret != 0) && irq_allocated) { 2546 if ((ret != 0) && irq_allocated) {
2547 free_irq(ioc->pci_irq, ioc); 2547 free_irq(ioc->pci_irq, ioc);
2548 if (ioc->msi_enable) 2548 if (ioc->msi_enable)
2549 pci_disable_msi(ioc->pcidev); 2549 pci_disable_msi(ioc->pcidev);
2550 } 2550 }
2551 return ret; 2551 return ret;
2552 } 2552 }
2553 2553
2554 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2554 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2555 /** 2555 /**
2556 * mpt_detect_bound_ports - Search for matching PCI bus/dev_function 2556 * mpt_detect_bound_ports - Search for matching PCI bus/dev_function
2557 * @ioc: Pointer to MPT adapter structure 2557 * @ioc: Pointer to MPT adapter structure
2558 * @pdev: Pointer to (struct pci_dev) structure 2558 * @pdev: Pointer to (struct pci_dev) structure
2559 * 2559 *
2560 * Search for PCI bus/dev_function which matches 2560 * Search for PCI bus/dev_function which matches
2561 * PCI bus/dev_function (+/-1) for newly discovered 929, 2561 * PCI bus/dev_function (+/-1) for newly discovered 929,
2562 * 929X, 1030 or 1035. 2562 * 929X, 1030 or 1035.
2563 * 2563 *
2564 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters 2564 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters
2565 * using alt_ioc pointer fields in their %MPT_ADAPTER structures. 2565 * using alt_ioc pointer fields in their %MPT_ADAPTER structures.
2566 */ 2566 */
2567 static void 2567 static void
2568 mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev) 2568 mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
2569 { 2569 {
2570 struct pci_dev *peer=NULL; 2570 struct pci_dev *peer=NULL;
2571 unsigned int slot = PCI_SLOT(pdev->devfn); 2571 unsigned int slot = PCI_SLOT(pdev->devfn);
2572 unsigned int func = PCI_FUNC(pdev->devfn); 2572 unsigned int func = PCI_FUNC(pdev->devfn);
2573 MPT_ADAPTER *ioc_srch; 2573 MPT_ADAPTER *ioc_srch;
2574 2574
2575 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PCI device %s devfn=%x/%x," 2575 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PCI device %s devfn=%x/%x,"
2576 " searching for devfn match on %x or %x\n", 2576 " searching for devfn match on %x or %x\n",
2577 ioc->name, pci_name(pdev), pdev->bus->number, 2577 ioc->name, pci_name(pdev), pdev->bus->number,
2578 pdev->devfn, func-1, func+1)); 2578 pdev->devfn, func-1, func+1));
2579 2579
2580 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1)); 2580 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1));
2581 if (!peer) { 2581 if (!peer) {
2582 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func+1)); 2582 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func+1));
2583 if (!peer) 2583 if (!peer)
2584 return; 2584 return;
2585 } 2585 }
2586 2586
2587 list_for_each_entry(ioc_srch, &ioc_list, list) { 2587 list_for_each_entry(ioc_srch, &ioc_list, list) {
2588 struct pci_dev *_pcidev = ioc_srch->pcidev; 2588 struct pci_dev *_pcidev = ioc_srch->pcidev;
2589 if (_pcidev == peer) { 2589 if (_pcidev == peer) {
2590 /* Paranoia checks */ 2590 /* Paranoia checks */
2591 if (ioc->alt_ioc != NULL) { 2591 if (ioc->alt_ioc != NULL) {
2592 printk(MYIOC_s_WARN_FMT 2592 printk(MYIOC_s_WARN_FMT
2593 "Oops, already bound (%s <==> %s)!\n", 2593 "Oops, already bound (%s <==> %s)!\n",
2594 ioc->name, ioc->name, ioc->alt_ioc->name); 2594 ioc->name, ioc->name, ioc->alt_ioc->name);
2595 break; 2595 break;
2596 } else if (ioc_srch->alt_ioc != NULL) { 2596 } else if (ioc_srch->alt_ioc != NULL) {
2597 printk(MYIOC_s_WARN_FMT 2597 printk(MYIOC_s_WARN_FMT
2598 "Oops, already bound (%s <==> %s)!\n", 2598 "Oops, already bound (%s <==> %s)!\n",
2599 ioc_srch->name, ioc_srch->name, 2599 ioc_srch->name, ioc_srch->name,
2600 ioc_srch->alt_ioc->name); 2600 ioc_srch->alt_ioc->name);
2601 break; 2601 break;
2602 } 2602 }
2603 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT 2603 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2604 "FOUND! binding %s <==> %s\n", 2604 "FOUND! binding %s <==> %s\n",
2605 ioc->name, ioc->name, ioc_srch->name)); 2605 ioc->name, ioc->name, ioc_srch->name));
2606 ioc_srch->alt_ioc = ioc; 2606 ioc_srch->alt_ioc = ioc;
2607 ioc->alt_ioc = ioc_srch; 2607 ioc->alt_ioc = ioc_srch;
2608 } 2608 }
2609 } 2609 }
2610 pci_dev_put(peer); 2610 pci_dev_put(peer);
2611 } 2611 }
2612 2612
2613 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2613 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2614 /** 2614 /**
2615 * mpt_adapter_disable - Disable misbehaving MPT adapter. 2615 * mpt_adapter_disable - Disable misbehaving MPT adapter.
2616 * @ioc: Pointer to MPT adapter structure 2616 * @ioc: Pointer to MPT adapter structure
2617 */ 2617 */
2618 static void 2618 static void
2619 mpt_adapter_disable(MPT_ADAPTER *ioc) 2619 mpt_adapter_disable(MPT_ADAPTER *ioc)
2620 { 2620 {
2621 int sz; 2621 int sz;
2622 int ret; 2622 int ret;
2623 2623
2624 if (ioc->cached_fw != NULL) { 2624 if (ioc->cached_fw != NULL) {
2625 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT 2625 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2626 "%s: Pushing FW onto adapter\n", __func__, ioc->name)); 2626 "%s: Pushing FW onto adapter\n", __func__, ioc->name));
2627 if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *) 2627 if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)
2628 ioc->cached_fw, CAN_SLEEP)) < 0) { 2628 ioc->cached_fw, CAN_SLEEP)) < 0) {
2629 printk(MYIOC_s_WARN_FMT 2629 printk(MYIOC_s_WARN_FMT
2630 ": firmware downloadboot failure (%d)!\n", 2630 ": firmware downloadboot failure (%d)!\n",
2631 ioc->name, ret); 2631 ioc->name, ret);
2632 } 2632 }
2633 } 2633 }
2634 2634
2635 /* 2635 /*
2636 * Put the controller into ready state (if its not already) 2636 * Put the controller into ready state (if its not already)
2637 */ 2637 */
2638 if (mpt_GetIocState(ioc, 1) != MPI_IOC_STATE_READY) { 2638 if (mpt_GetIocState(ioc, 1) != MPI_IOC_STATE_READY) {
2639 if (!SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, 2639 if (!SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET,
2640 CAN_SLEEP)) { 2640 CAN_SLEEP)) {
2641 if (mpt_GetIocState(ioc, 1) != MPI_IOC_STATE_READY) 2641 if (mpt_GetIocState(ioc, 1) != MPI_IOC_STATE_READY)
2642 printk(MYIOC_s_ERR_FMT "%s: IOC msg unit " 2642 printk(MYIOC_s_ERR_FMT "%s: IOC msg unit "
2643 "reset failed to put ioc in ready state!\n", 2643 "reset failed to put ioc in ready state!\n",
2644 ioc->name, __func__); 2644 ioc->name, __func__);
2645 } else 2645 } else
2646 printk(MYIOC_s_ERR_FMT "%s: IOC msg unit reset " 2646 printk(MYIOC_s_ERR_FMT "%s: IOC msg unit reset "
2647 "failed!\n", ioc->name, __func__); 2647 "failed!\n", ioc->name, __func__);
2648 } 2648 }
2649 2649
2650 2650
2651 /* Disable adapter interrupts! */ 2651 /* Disable adapter interrupts! */
2652 synchronize_irq(ioc->pcidev->irq); 2652 synchronize_irq(ioc->pcidev->irq);
2653 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF); 2653 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2654 ioc->active = 0; 2654 ioc->active = 0;
2655 2655
2656 /* Clear any lingering interrupt */ 2656 /* Clear any lingering interrupt */
2657 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); 2657 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2658 CHIPREG_READ32(&ioc->chip->IntStatus); 2658 CHIPREG_READ32(&ioc->chip->IntStatus);
2659 2659
2660 if (ioc->alloc != NULL) { 2660 if (ioc->alloc != NULL) {
2661 sz = ioc->alloc_sz; 2661 sz = ioc->alloc_sz;
2662 dexitprintk(ioc, printk(MYIOC_s_INFO_FMT "free @ %p, sz=%d bytes\n", 2662 dexitprintk(ioc, printk(MYIOC_s_INFO_FMT "free @ %p, sz=%d bytes\n",
2663 ioc->name, ioc->alloc, ioc->alloc_sz)); 2663 ioc->name, ioc->alloc, ioc->alloc_sz));
2664 pci_free_consistent(ioc->pcidev, sz, 2664 pci_free_consistent(ioc->pcidev, sz,
2665 ioc->alloc, ioc->alloc_dma); 2665 ioc->alloc, ioc->alloc_dma);
2666 ioc->reply_frames = NULL; 2666 ioc->reply_frames = NULL;
2667 ioc->req_frames = NULL; 2667 ioc->req_frames = NULL;
2668 ioc->alloc = NULL; 2668 ioc->alloc = NULL;
2669 ioc->alloc_total -= sz; 2669 ioc->alloc_total -= sz;
2670 } 2670 }
2671 2671
2672 if (ioc->sense_buf_pool != NULL) { 2672 if (ioc->sense_buf_pool != NULL) {
2673 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC); 2673 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
2674 pci_free_consistent(ioc->pcidev, sz, 2674 pci_free_consistent(ioc->pcidev, sz,
2675 ioc->sense_buf_pool, ioc->sense_buf_pool_dma); 2675 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
2676 ioc->sense_buf_pool = NULL; 2676 ioc->sense_buf_pool = NULL;
2677 ioc->alloc_total -= sz; 2677 ioc->alloc_total -= sz;
2678 } 2678 }
2679 2679
2680 if (ioc->events != NULL){ 2680 if (ioc->events != NULL){
2681 sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS); 2681 sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
2682 kfree(ioc->events); 2682 kfree(ioc->events);
2683 ioc->events = NULL; 2683 ioc->events = NULL;
2684 ioc->alloc_total -= sz; 2684 ioc->alloc_total -= sz;
2685 } 2685 }
2686 2686
2687 mpt_free_fw_memory(ioc); 2687 mpt_free_fw_memory(ioc);
2688 2688
2689 kfree(ioc->spi_data.nvram); 2689 kfree(ioc->spi_data.nvram);
2690 mpt_inactive_raid_list_free(ioc); 2690 mpt_inactive_raid_list_free(ioc);
2691 kfree(ioc->raid_data.pIocPg2); 2691 kfree(ioc->raid_data.pIocPg2);
2692 kfree(ioc->raid_data.pIocPg3); 2692 kfree(ioc->raid_data.pIocPg3);
2693 ioc->spi_data.nvram = NULL; 2693 ioc->spi_data.nvram = NULL;
2694 ioc->raid_data.pIocPg3 = NULL; 2694 ioc->raid_data.pIocPg3 = NULL;
2695 2695
2696 if (ioc->spi_data.pIocPg4 != NULL) { 2696 if (ioc->spi_data.pIocPg4 != NULL) {
2697 sz = ioc->spi_data.IocPg4Sz; 2697 sz = ioc->spi_data.IocPg4Sz;
2698 pci_free_consistent(ioc->pcidev, sz, 2698 pci_free_consistent(ioc->pcidev, sz,
2699 ioc->spi_data.pIocPg4, 2699 ioc->spi_data.pIocPg4,
2700 ioc->spi_data.IocPg4_dma); 2700 ioc->spi_data.IocPg4_dma);
2701 ioc->spi_data.pIocPg4 = NULL; 2701 ioc->spi_data.pIocPg4 = NULL;
2702 ioc->alloc_total -= sz; 2702 ioc->alloc_total -= sz;
2703 } 2703 }
2704 2704
2705 if (ioc->ReqToChain != NULL) { 2705 if (ioc->ReqToChain != NULL) {
2706 kfree(ioc->ReqToChain); 2706 kfree(ioc->ReqToChain);
2707 kfree(ioc->RequestNB); 2707 kfree(ioc->RequestNB);
2708 ioc->ReqToChain = NULL; 2708 ioc->ReqToChain = NULL;
2709 } 2709 }
2710 2710
2711 kfree(ioc->ChainToChain); 2711 kfree(ioc->ChainToChain);
2712 ioc->ChainToChain = NULL; 2712 ioc->ChainToChain = NULL;
2713 2713
2714 if (ioc->HostPageBuffer != NULL) { 2714 if (ioc->HostPageBuffer != NULL) {
2715 if((ret = mpt_host_page_access_control(ioc, 2715 if((ret = mpt_host_page_access_control(ioc,
2716 MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) { 2716 MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) {
2717 printk(MYIOC_s_ERR_FMT 2717 printk(MYIOC_s_ERR_FMT
2718 ": %s: host page buffers free failed (%d)!\n", 2718 ": %s: host page buffers free failed (%d)!\n",
2719 ioc->name, __func__, ret); 2719 ioc->name, __func__, ret);
2720 } 2720 }
2721 dexitprintk(ioc, printk(MYIOC_s_DEBUG_FMT 2721 dexitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2722 "HostPageBuffer free @ %p, sz=%d bytes\n", 2722 "HostPageBuffer free @ %p, sz=%d bytes\n",
2723 ioc->name, ioc->HostPageBuffer, 2723 ioc->name, ioc->HostPageBuffer,
2724 ioc->HostPageBuffer_sz)); 2724 ioc->HostPageBuffer_sz));
2725 pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz, 2725 pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz,
2726 ioc->HostPageBuffer, ioc->HostPageBuffer_dma); 2726 ioc->HostPageBuffer, ioc->HostPageBuffer_dma);
2727 ioc->HostPageBuffer = NULL; 2727 ioc->HostPageBuffer = NULL;
2728 ioc->HostPageBuffer_sz = 0; 2728 ioc->HostPageBuffer_sz = 0;
2729 ioc->alloc_total -= ioc->HostPageBuffer_sz; 2729 ioc->alloc_total -= ioc->HostPageBuffer_sz;
2730 } 2730 }
2731 2731
2732 pci_set_drvdata(ioc->pcidev, NULL); 2732 pci_set_drvdata(ioc->pcidev, NULL);
2733 } 2733 }
2734 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2734 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2735 /** 2735 /**
2736 * mpt_adapter_dispose - Free all resources associated with an MPT adapter 2736 * mpt_adapter_dispose - Free all resources associated with an MPT adapter
2737 * @ioc: Pointer to MPT adapter structure 2737 * @ioc: Pointer to MPT adapter structure
2738 * 2738 *
2739 * This routine unregisters h/w resources and frees all alloc'd memory 2739 * This routine unregisters h/w resources and frees all alloc'd memory
2740 * associated with a MPT adapter structure. 2740 * associated with a MPT adapter structure.
2741 */ 2741 */
2742 static void 2742 static void
2743 mpt_adapter_dispose(MPT_ADAPTER *ioc) 2743 mpt_adapter_dispose(MPT_ADAPTER *ioc)
2744 { 2744 {
2745 int sz_first, sz_last; 2745 int sz_first, sz_last;
2746 2746
2747 if (ioc == NULL) 2747 if (ioc == NULL)
2748 return; 2748 return;
2749 2749
2750 sz_first = ioc->alloc_total; 2750 sz_first = ioc->alloc_total;
2751 2751
2752 mpt_adapter_disable(ioc); 2752 mpt_adapter_disable(ioc);
2753 2753
2754 if (ioc->pci_irq != -1) { 2754 if (ioc->pci_irq != -1) {
2755 free_irq(ioc->pci_irq, ioc); 2755 free_irq(ioc->pci_irq, ioc);
2756 if (ioc->msi_enable) 2756 if (ioc->msi_enable)
2757 pci_disable_msi(ioc->pcidev); 2757 pci_disable_msi(ioc->pcidev);
2758 ioc->pci_irq = -1; 2758 ioc->pci_irq = -1;
2759 } 2759 }
2760 2760
2761 if (ioc->memmap != NULL) { 2761 if (ioc->memmap != NULL) {
2762 iounmap(ioc->memmap); 2762 iounmap(ioc->memmap);
2763 ioc->memmap = NULL; 2763 ioc->memmap = NULL;
2764 } 2764 }
2765 2765
2766 pci_disable_device(ioc->pcidev); 2766 pci_disable_device(ioc->pcidev);
2767 pci_release_selected_regions(ioc->pcidev, ioc->bars); 2767 pci_release_selected_regions(ioc->pcidev, ioc->bars);
2768 2768
2769 #if defined(CONFIG_MTRR) && 0 2769 #if defined(CONFIG_MTRR) && 0
2770 if (ioc->mtrr_reg > 0) { 2770 if (ioc->mtrr_reg > 0) {
2771 mtrr_del(ioc->mtrr_reg, 0, 0); 2771 mtrr_del(ioc->mtrr_reg, 0, 0);
2772 dprintk(ioc, printk(MYIOC_s_INFO_FMT "MTRR region de-registered\n", ioc->name)); 2772 dprintk(ioc, printk(MYIOC_s_INFO_FMT "MTRR region de-registered\n", ioc->name));
2773 } 2773 }
2774 #endif 2774 #endif
2775 2775
2776 /* Zap the adapter lookup ptr! */ 2776 /* Zap the adapter lookup ptr! */
2777 list_del(&ioc->list); 2777 list_del(&ioc->list);
2778 2778
2779 sz_last = ioc->alloc_total; 2779 sz_last = ioc->alloc_total;
2780 dprintk(ioc, printk(MYIOC_s_INFO_FMT "free'd %d of %d bytes\n", 2780 dprintk(ioc, printk(MYIOC_s_INFO_FMT "free'd %d of %d bytes\n",
2781 ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first)); 2781 ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
2782 2782
2783 if (ioc->alt_ioc) 2783 if (ioc->alt_ioc)
2784 ioc->alt_ioc->alt_ioc = NULL; 2784 ioc->alt_ioc->alt_ioc = NULL;
2785 2785
2786 kfree(ioc); 2786 kfree(ioc);
2787 } 2787 }
2788 2788
2789 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2789 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2790 /** 2790 /**
2791 * MptDisplayIocCapabilities - Disply IOC's capabilities. 2791 * MptDisplayIocCapabilities - Disply IOC's capabilities.
2792 * @ioc: Pointer to MPT adapter structure 2792 * @ioc: Pointer to MPT adapter structure
2793 */ 2793 */
2794 static void 2794 static void
2795 MptDisplayIocCapabilities(MPT_ADAPTER *ioc) 2795 MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
2796 { 2796 {
2797 int i = 0; 2797 int i = 0;
2798 2798
2799 printk(KERN_INFO "%s: ", ioc->name); 2799 printk(KERN_INFO "%s: ", ioc->name);
2800 if (ioc->prod_name) 2800 if (ioc->prod_name)
2801 printk("%s: ", ioc->prod_name); 2801 printk("%s: ", ioc->prod_name);
2802 printk("Capabilities={"); 2802 printk("Capabilities={");
2803 2803
2804 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) { 2804 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
2805 printk("Initiator"); 2805 printk("Initiator");
2806 i++; 2806 i++;
2807 } 2807 }
2808 2808
2809 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) { 2809 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2810 printk("%sTarget", i ? "," : ""); 2810 printk("%sTarget", i ? "," : "");
2811 i++; 2811 i++;
2812 } 2812 }
2813 2813
2814 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) { 2814 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
2815 printk("%sLAN", i ? "," : ""); 2815 printk("%sLAN", i ? "," : "");
2816 i++; 2816 i++;
2817 } 2817 }
2818 2818
2819 #if 0 2819 #if 0
2820 /* 2820 /*
2821 * This would probably evoke more questions than it's worth 2821 * This would probably evoke more questions than it's worth
2822 */ 2822 */
2823 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) { 2823 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2824 printk("%sLogBusAddr", i ? "," : ""); 2824 printk("%sLogBusAddr", i ? "," : "");
2825 i++; 2825 i++;
2826 } 2826 }
2827 #endif 2827 #endif
2828 2828
2829 printk("}\n"); 2829 printk("}\n");
2830 } 2830 }
2831 2831
2832 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2832 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2833 /** 2833 /**
2834 * MakeIocReady - Get IOC to a READY state, using KickStart if needed. 2834 * MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2835 * @ioc: Pointer to MPT_ADAPTER structure 2835 * @ioc: Pointer to MPT_ADAPTER structure
2836 * @force: Force hard KickStart of IOC 2836 * @force: Force hard KickStart of IOC
2837 * @sleepFlag: Specifies whether the process can sleep 2837 * @sleepFlag: Specifies whether the process can sleep
2838 * 2838 *
2839 * Returns: 2839 * Returns:
2840 * 1 - DIAG reset and READY 2840 * 1 - DIAG reset and READY
2841 * 0 - READY initially OR soft reset and READY 2841 * 0 - READY initially OR soft reset and READY
2842 * -1 - Any failure on KickStart 2842 * -1 - Any failure on KickStart
2843 * -2 - Msg Unit Reset Failed 2843 * -2 - Msg Unit Reset Failed
2844 * -3 - IO Unit Reset Failed 2844 * -3 - IO Unit Reset Failed
2845 * -4 - IOC owned by a PEER 2845 * -4 - IOC owned by a PEER
2846 */ 2846 */
2847 static int 2847 static int
2848 MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag) 2848 MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2849 { 2849 {
2850 u32 ioc_state; 2850 u32 ioc_state;
2851 int statefault = 0; 2851 int statefault = 0;
2852 int cntdn; 2852 int cntdn;
2853 int hard_reset_done = 0; 2853 int hard_reset_done = 0;
2854 int r; 2854 int r;
2855 int ii; 2855 int ii;
2856 int whoinit; 2856 int whoinit;
2857 2857
2858 /* Get current [raw] IOC state */ 2858 /* Get current [raw] IOC state */
2859 ioc_state = mpt_GetIocState(ioc, 0); 2859 ioc_state = mpt_GetIocState(ioc, 0);
2860 dhsprintk(ioc, printk(MYIOC_s_INFO_FMT "MakeIocReady [raw] state=%08x\n", ioc->name, ioc_state)); 2860 dhsprintk(ioc, printk(MYIOC_s_INFO_FMT "MakeIocReady [raw] state=%08x\n", ioc->name, ioc_state));
2861 2861
2862 /* 2862 /*
2863 * Check to see if IOC got left/stuck in doorbell handshake 2863 * Check to see if IOC got left/stuck in doorbell handshake
2864 * grip of death. If so, hard reset the IOC. 2864 * grip of death. If so, hard reset the IOC.
2865 */ 2865 */
2866 if (ioc_state & MPI_DOORBELL_ACTIVE) { 2866 if (ioc_state & MPI_DOORBELL_ACTIVE) {
2867 statefault = 1; 2867 statefault = 1;
2868 printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n", 2868 printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",
2869 ioc->name); 2869 ioc->name);
2870 } 2870 }
2871 2871
2872 /* Is it already READY? */ 2872 /* Is it already READY? */
2873 if (!statefault && 2873 if (!statefault &&
2874 ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)) { 2874 ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)) {
2875 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT 2875 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2876 "IOC is in READY state\n", ioc->name)); 2876 "IOC is in READY state\n", ioc->name));
2877 return 0; 2877 return 0;
2878 } 2878 }
2879 2879
2880 /* 2880 /*
2881 * Check to see if IOC is in FAULT state. 2881 * Check to see if IOC is in FAULT state.
2882 */ 2882 */
2883 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) { 2883 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
2884 statefault = 2; 2884 statefault = 2;
2885 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n", 2885 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n",
2886 ioc->name); 2886 ioc->name);
2887 printk(MYIOC_s_WARN_FMT " FAULT code = %04xh\n", 2887 printk(MYIOC_s_WARN_FMT " FAULT code = %04xh\n",
2888 ioc->name, ioc_state & MPI_DOORBELL_DATA_MASK); 2888 ioc->name, ioc_state & MPI_DOORBELL_DATA_MASK);
2889 } 2889 }
2890 2890
2891 /* 2891 /*
2892 * Hmmm... Did it get left operational? 2892 * Hmmm... Did it get left operational?
2893 */ 2893 */
2894 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) { 2894 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
2895 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOC operational unexpected\n", 2895 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOC operational unexpected\n",
2896 ioc->name)); 2896 ioc->name));
2897 2897
2898 /* Check WhoInit. 2898 /* Check WhoInit.
2899 * If PCI Peer, exit. 2899 * If PCI Peer, exit.
2900 * Else, if no fault conditions are present, issue a MessageUnitReset 2900 * Else, if no fault conditions are present, issue a MessageUnitReset
2901 * Else, fall through to KickStart case 2901 * Else, fall through to KickStart case
2902 */ 2902 */
2903 whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT; 2903 whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
2904 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT 2904 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2905 "whoinit 0x%x statefault %d force %d\n", 2905 "whoinit 0x%x statefault %d force %d\n",
2906 ioc->name, whoinit, statefault, force)); 2906 ioc->name, whoinit, statefault, force));
2907 if (whoinit == MPI_WHOINIT_PCI_PEER) 2907 if (whoinit == MPI_WHOINIT_PCI_PEER)
2908 return -4; 2908 return -4;
2909 else { 2909 else {
2910 if ((statefault == 0 ) && (force == 0)) { 2910 if ((statefault == 0 ) && (force == 0)) {
2911 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0) 2911 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2912 return 0; 2912 return 0;
2913 } 2913 }
2914 statefault = 3; 2914 statefault = 3;
2915 } 2915 }
2916 } 2916 }
2917 2917
2918 hard_reset_done = KickStart(ioc, statefault||force, sleepFlag); 2918 hard_reset_done = KickStart(ioc, statefault||force, sleepFlag);
2919 if (hard_reset_done < 0) 2919 if (hard_reset_done < 0)
2920 return -1; 2920 return -1;
2921 2921
2922 /* 2922 /*
2923 * Loop here waiting for IOC to come READY. 2923 * Loop here waiting for IOC to come READY.
2924 */ 2924 */
2925 ii = 0; 2925 ii = 0;
2926 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 5; /* 5 seconds */ 2926 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 5; /* 5 seconds */
2927 2927
2928 while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) { 2928 while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
2929 if (ioc_state == MPI_IOC_STATE_OPERATIONAL) { 2929 if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
2930 /* 2930 /*
2931 * BIOS or previous driver load left IOC in OP state. 2931 * BIOS or previous driver load left IOC in OP state.
2932 * Reset messaging FIFOs. 2932 * Reset messaging FIFOs.
2933 */ 2933 */
2934 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) { 2934 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) {
2935 printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name); 2935 printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name);
2936 return -2; 2936 return -2;
2937 } 2937 }
2938 } else if (ioc_state == MPI_IOC_STATE_RESET) { 2938 } else if (ioc_state == MPI_IOC_STATE_RESET) {
2939 /* 2939 /*
2940 * Something is wrong. Try to get IOC back 2940 * Something is wrong. Try to get IOC back
2941 * to a known state. 2941 * to a known state.
2942 */ 2942 */
2943 if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) { 2943 if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) {
2944 printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name); 2944 printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name);
2945 return -3; 2945 return -3;
2946 } 2946 }
2947 } 2947 }
2948 2948
2949 ii++; cntdn--; 2949 ii++; cntdn--;
2950 if (!cntdn) { 2950 if (!cntdn) {
2951 printk(MYIOC_s_ERR_FMT 2951 printk(MYIOC_s_ERR_FMT
2952 "Wait IOC_READY state (0x%x) timeout(%d)!\n", 2952 "Wait IOC_READY state (0x%x) timeout(%d)!\n",
2953 ioc->name, ioc_state, (int)((ii+5)/HZ)); 2953 ioc->name, ioc_state, (int)((ii+5)/HZ));
2954 return -ETIME; 2954 return -ETIME;
2955 } 2955 }
2956 2956
2957 if (sleepFlag == CAN_SLEEP) { 2957 if (sleepFlag == CAN_SLEEP) {
2958 msleep(1); 2958 msleep(1);
2959 } else { 2959 } else {
2960 mdelay (1); /* 1 msec delay */ 2960 mdelay (1); /* 1 msec delay */
2961 } 2961 }
2962 2962
2963 } 2963 }
2964 2964
2965 if (statefault < 3) { 2965 if (statefault < 3) {
2966 printk(MYIOC_s_INFO_FMT "Recovered from %s\n", ioc->name, 2966 printk(MYIOC_s_INFO_FMT "Recovered from %s\n", ioc->name,
2967 statefault == 1 ? "stuck handshake" : "IOC FAULT"); 2967 statefault == 1 ? "stuck handshake" : "IOC FAULT");
2968 } 2968 }
2969 2969
2970 return hard_reset_done; 2970 return hard_reset_done;
2971 } 2971 }
2972 2972
2973 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2973 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2974 /** 2974 /**
2975 * mpt_GetIocState - Get the current state of a MPT adapter. 2975 * mpt_GetIocState - Get the current state of a MPT adapter.
2976 * @ioc: Pointer to MPT_ADAPTER structure 2976 * @ioc: Pointer to MPT_ADAPTER structure
2977 * @cooked: Request raw or cooked IOC state 2977 * @cooked: Request raw or cooked IOC state
2978 * 2978 *
2979 * Returns all IOC Doorbell register bits if cooked==0, else just the 2979 * Returns all IOC Doorbell register bits if cooked==0, else just the
2980 * Doorbell bits in MPI_IOC_STATE_MASK. 2980 * Doorbell bits in MPI_IOC_STATE_MASK.
2981 */ 2981 */
2982 u32 2982 u32
2983 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked) 2983 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked)
2984 { 2984 {
2985 u32 s, sc; 2985 u32 s, sc;
2986 2986
2987 /* Get! */ 2987 /* Get! */
2988 s = CHIPREG_READ32(&ioc->chip->Doorbell); 2988 s = CHIPREG_READ32(&ioc->chip->Doorbell);
2989 sc = s & MPI_IOC_STATE_MASK; 2989 sc = s & MPI_IOC_STATE_MASK;
2990 2990
2991 /* Save! */ 2991 /* Save! */
2992 ioc->last_state = sc; 2992 ioc->last_state = sc;
2993 2993
2994 return cooked ? sc : s; 2994 return cooked ? sc : s;
2995 } 2995 }
2996 2996
2997 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2997 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2998 /** 2998 /**
2999 * GetIocFacts - Send IOCFacts request to MPT adapter. 2999 * GetIocFacts - Send IOCFacts request to MPT adapter.
3000 * @ioc: Pointer to MPT_ADAPTER structure 3000 * @ioc: Pointer to MPT_ADAPTER structure
3001 * @sleepFlag: Specifies whether the process can sleep 3001 * @sleepFlag: Specifies whether the process can sleep
3002 * @reason: If recovery, only update facts. 3002 * @reason: If recovery, only update facts.
3003 * 3003 *
3004 * Returns 0 for success, non-zero for failure. 3004 * Returns 0 for success, non-zero for failure.
3005 */ 3005 */
3006 static int 3006 static int
3007 GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason) 3007 GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
3008 { 3008 {
3009 IOCFacts_t get_facts; 3009 IOCFacts_t get_facts;
3010 IOCFactsReply_t *facts; 3010 IOCFactsReply_t *facts;
3011 int r; 3011 int r;
3012 int req_sz; 3012 int req_sz;
3013 int reply_sz; 3013 int reply_sz;
3014 int sz; 3014 int sz;
3015 u32 status, vv; 3015 u32 status, vv;
3016 u8 shiftFactor=1; 3016 u8 shiftFactor=1;
3017 3017
3018 /* IOC *must* NOT be in RESET state! */ 3018 /* IOC *must* NOT be in RESET state! */
3019 if (ioc->last_state == MPI_IOC_STATE_RESET) { 3019 if (ioc->last_state == MPI_IOC_STATE_RESET) {
3020 printk(KERN_ERR MYNAM 3020 printk(KERN_ERR MYNAM
3021 ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n", 3021 ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n",
3022 ioc->name, ioc->last_state); 3022 ioc->name, ioc->last_state);
3023 return -44; 3023 return -44;
3024 } 3024 }
3025 3025
3026 facts = &ioc->facts; 3026 facts = &ioc->facts;
3027 3027
3028 /* Destination (reply area)... */ 3028 /* Destination (reply area)... */
3029 reply_sz = sizeof(*facts); 3029 reply_sz = sizeof(*facts);
3030 memset(facts, 0, reply_sz); 3030 memset(facts, 0, reply_sz);
3031 3031
3032 /* Request area (get_facts on the stack right now!) */ 3032 /* Request area (get_facts on the stack right now!) */
3033 req_sz = sizeof(get_facts); 3033 req_sz = sizeof(get_facts);
3034 memset(&get_facts, 0, req_sz); 3034 memset(&get_facts, 0, req_sz);
3035 3035
3036 get_facts.Function = MPI_FUNCTION_IOC_FACTS; 3036 get_facts.Function = MPI_FUNCTION_IOC_FACTS;
3037 /* Assert: All other get_facts fields are zero! */ 3037 /* Assert: All other get_facts fields are zero! */
3038 3038
3039 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT 3039 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3040 "Sending get IocFacts request req_sz=%d reply_sz=%d\n", 3040 "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
3041 ioc->name, req_sz, reply_sz)); 3041 ioc->name, req_sz, reply_sz));
3042 3042
3043 /* No non-zero fields in the get_facts request are greater than 3043 /* No non-zero fields in the get_facts request are greater than
3044 * 1 byte in size, so we can just fire it off as is. 3044 * 1 byte in size, so we can just fire it off as is.
3045 */ 3045 */
3046 r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts, 3046 r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
3047 reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag); 3047 reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag);
3048 if (r != 0) 3048 if (r != 0)
3049 return r; 3049 return r;
3050 3050
3051 /* 3051 /*
3052 * Now byte swap (GRRR) the necessary fields before any further 3052 * Now byte swap (GRRR) the necessary fields before any further
3053 * inspection of reply contents. 3053 * inspection of reply contents.
3054 * 3054 *
3055 * But need to do some sanity checks on MsgLength (byte) field 3055 * But need to do some sanity checks on MsgLength (byte) field
3056 * to make sure we don't zero IOC's req_sz! 3056 * to make sure we don't zero IOC's req_sz!
3057 */ 3057 */
3058 /* Did we get a valid reply? */ 3058 /* Did we get a valid reply? */
3059 if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) { 3059 if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
3060 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) { 3060 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
3061 /* 3061 /*
3062 * If not been here, done that, save off first WhoInit value 3062 * If not been here, done that, save off first WhoInit value
3063 */ 3063 */
3064 if (ioc->FirstWhoInit == WHOINIT_UNKNOWN) 3064 if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
3065 ioc->FirstWhoInit = facts->WhoInit; 3065 ioc->FirstWhoInit = facts->WhoInit;
3066 } 3066 }
3067 3067
3068 facts->MsgVersion = le16_to_cpu(facts->MsgVersion); 3068 facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
3069 facts->MsgContext = le32_to_cpu(facts->MsgContext); 3069 facts->MsgContext = le32_to_cpu(facts->MsgContext);
3070 facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions); 3070 facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
3071 facts->IOCStatus = le16_to_cpu(facts->IOCStatus); 3071 facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
3072 facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo); 3072 facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
3073 status = le16_to_cpu(facts->IOCStatus) & MPI_IOCSTATUS_MASK; 3073 status = le16_to_cpu(facts->IOCStatus) & MPI_IOCSTATUS_MASK;
3074 /* CHECKME! IOCStatus, IOCLogInfo */ 3074 /* CHECKME! IOCStatus, IOCLogInfo */
3075 3075
3076 facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth); 3076 facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
3077 facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize); 3077 facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);
3078 3078
3079 /* 3079 /*
3080 * FC f/w version changed between 1.1 and 1.2 3080 * FC f/w version changed between 1.1 and 1.2
3081 * Old: u16{Major(4),Minor(4),SubMinor(8)} 3081 * Old: u16{Major(4),Minor(4),SubMinor(8)}
3082 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)} 3082 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
3083 */ 3083 */
3084 if (facts->MsgVersion < MPI_VERSION_01_02) { 3084 if (facts->MsgVersion < MPI_VERSION_01_02) {
3085 /* 3085 /*
3086 * Handle old FC f/w style, convert to new... 3086 * Handle old FC f/w style, convert to new...
3087 */ 3087 */
3088 u16 oldv = le16_to_cpu(facts->Reserved_0101_FWVersion); 3088 u16 oldv = le16_to_cpu(facts->Reserved_0101_FWVersion);
3089 facts->FWVersion.Word = 3089 facts->FWVersion.Word =
3090 ((oldv<<12) & 0xFF000000) | 3090 ((oldv<<12) & 0xFF000000) |
3091 ((oldv<<8) & 0x000FFF00); 3091 ((oldv<<8) & 0x000FFF00);
3092 } else 3092 } else
3093 facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word); 3093 facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
3094 3094
3095 facts->ProductID = le16_to_cpu(facts->ProductID); 3095 facts->ProductID = le16_to_cpu(facts->ProductID);
3096 3096
3097 if ((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK) 3097 if ((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
3098 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI) 3098 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI)
3099 ioc->ir_firmware = 1; 3099 ioc->ir_firmware = 1;
3100 3100
3101 facts->CurrentHostMfaHighAddr = 3101 facts->CurrentHostMfaHighAddr =
3102 le32_to_cpu(facts->CurrentHostMfaHighAddr); 3102 le32_to_cpu(facts->CurrentHostMfaHighAddr);
3103 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits); 3103 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
3104 facts->CurrentSenseBufferHighAddr = 3104 facts->CurrentSenseBufferHighAddr =
3105 le32_to_cpu(facts->CurrentSenseBufferHighAddr); 3105 le32_to_cpu(facts->CurrentSenseBufferHighAddr);
3106 facts->CurReplyFrameSize = 3106 facts->CurReplyFrameSize =
3107 le16_to_cpu(facts->CurReplyFrameSize); 3107 le16_to_cpu(facts->CurReplyFrameSize);
3108 facts->IOCCapabilities = le32_to_cpu(facts->IOCCapabilities); 3108 facts->IOCCapabilities = le32_to_cpu(facts->IOCCapabilities);
3109 3109
3110 /* 3110 /*
3111 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx 3111 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
3112 * Older MPI-1.00.xx struct had 13 dwords, and enlarged 3112 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
3113 * to 14 in MPI-1.01.0x. 3113 * to 14 in MPI-1.01.0x.
3114 */ 3114 */
3115 if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 && 3115 if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
3116 facts->MsgVersion > MPI_VERSION_01_00) { 3116 facts->MsgVersion > MPI_VERSION_01_00) {
3117 facts->FWImageSize = le32_to_cpu(facts->FWImageSize); 3117 facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
3118 } 3118 }
3119 3119
3120 sz = facts->FWImageSize; 3120 sz = facts->FWImageSize;
3121 if ( sz & 0x01 ) 3121 if ( sz & 0x01 )
3122 sz += 1; 3122 sz += 1;
3123 if ( sz & 0x02 ) 3123 if ( sz & 0x02 )
3124 sz += 2; 3124 sz += 2;
3125 facts->FWImageSize = sz; 3125 facts->FWImageSize = sz;
3126 3126
3127 if (!facts->RequestFrameSize) { 3127 if (!facts->RequestFrameSize) {
3128 /* Something is wrong! */ 3128 /* Something is wrong! */
3129 printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n", 3129 printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
3130 ioc->name); 3130 ioc->name);
3131 return -55; 3131 return -55;
3132 } 3132 }
3133 3133
3134 r = sz = facts->BlockSize; 3134 r = sz = facts->BlockSize;
3135 vv = ((63 / (sz * 4)) + 1) & 0x03; 3135 vv = ((63 / (sz * 4)) + 1) & 0x03;
3136 ioc->NB_for_64_byte_frame = vv; 3136 ioc->NB_for_64_byte_frame = vv;
3137 while ( sz ) 3137 while ( sz )
3138 { 3138 {
3139 shiftFactor++; 3139 shiftFactor++;
3140 sz = sz >> 1; 3140 sz = sz >> 1;
3141 } 3141 }
3142 ioc->NBShiftFactor = shiftFactor; 3142 ioc->NBShiftFactor = shiftFactor;
3143 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT 3143 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3144 "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n", 3144 "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
3145 ioc->name, vv, shiftFactor, r)); 3145 ioc->name, vv, shiftFactor, r));
3146 3146
3147 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) { 3147 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
3148 /* 3148 /*
3149 * Set values for this IOC's request & reply frame sizes, 3149 * Set values for this IOC's request & reply frame sizes,
3150 * and request & reply queue depths... 3150 * and request & reply queue depths...
3151 */ 3151 */
3152 ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4); 3152 ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
3153 ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits); 3153 ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
3154 ioc->reply_sz = MPT_REPLY_FRAME_SIZE; 3154 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
3155 ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth); 3155 ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
3156 3156
3157 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "reply_sz=%3d, reply_depth=%4d\n", 3157 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "reply_sz=%3d, reply_depth=%4d\n",
3158 ioc->name, ioc->reply_sz, ioc->reply_depth)); 3158 ioc->name, ioc->reply_sz, ioc->reply_depth));
3159 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "req_sz =%3d, req_depth =%4d\n", 3159 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "req_sz =%3d, req_depth =%4d\n",
3160 ioc->name, ioc->req_sz, ioc->req_depth)); 3160 ioc->name, ioc->req_sz, ioc->req_depth));
3161 3161
3162 /* Get port facts! */ 3162 /* Get port facts! */
3163 if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 ) 3163 if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 )
3164 return r; 3164 return r;
3165 } 3165 }
3166 } else { 3166 } else {
3167 printk(MYIOC_s_ERR_FMT 3167 printk(MYIOC_s_ERR_FMT
3168 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n", 3168 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
3169 ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t, 3169 ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
3170 RequestFrameSize)/sizeof(u32))); 3170 RequestFrameSize)/sizeof(u32)));
3171 return -66; 3171 return -66;
3172 } 3172 }
3173 3173
3174 return 0; 3174 return 0;
3175 } 3175 }
3176 3176
3177 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 3177 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3178 /** 3178 /**
3179 * GetPortFacts - Send PortFacts request to MPT adapter. 3179 * GetPortFacts - Send PortFacts request to MPT adapter.
3180 * @ioc: Pointer to MPT_ADAPTER structure 3180 * @ioc: Pointer to MPT_ADAPTER structure
3181 * @portnum: Port number 3181 * @portnum: Port number
3182 * @sleepFlag: Specifies whether the process can sleep 3182 * @sleepFlag: Specifies whether the process can sleep
3183 * 3183 *
3184 * Returns 0 for success, non-zero for failure. 3184 * Returns 0 for success, non-zero for failure.
3185 */ 3185 */
3186 static int 3186 static int
3187 GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag) 3187 GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
3188 { 3188 {
3189 PortFacts_t get_pfacts; 3189 PortFacts_t get_pfacts;
3190 PortFactsReply_t *pfacts; 3190 PortFactsReply_t *pfacts;
3191 int ii; 3191 int ii;
3192 int req_sz; 3192 int req_sz;
3193 int reply_sz; 3193 int reply_sz;
3194 int max_id; 3194 int max_id;
3195 3195
3196 /* IOC *must* NOT be in RESET state! */ 3196 /* IOC *must* NOT be in RESET state! */
3197 if (ioc->last_state == MPI_IOC_STATE_RESET) { 3197 if (ioc->last_state == MPI_IOC_STATE_RESET) {
3198 printk(MYIOC_s_ERR_FMT "Can't get PortFacts NOT READY! (%08x)\n", 3198 printk(MYIOC_s_ERR_FMT "Can't get PortFacts NOT READY! (%08x)\n",
3199 ioc->name, ioc->last_state ); 3199 ioc->name, ioc->last_state );
3200 return -4; 3200 return -4;
3201 } 3201 }
3202 3202
3203 pfacts = &ioc->pfacts[portnum]; 3203 pfacts = &ioc->pfacts[portnum];
3204 3204
3205 /* Destination (reply area)... */ 3205 /* Destination (reply area)... */
3206 reply_sz = sizeof(*pfacts); 3206 reply_sz = sizeof(*pfacts);
3207 memset(pfacts, 0, reply_sz); 3207 memset(pfacts, 0, reply_sz);
3208 3208
3209 /* Request area (get_pfacts on the stack right now!) */ 3209 /* Request area (get_pfacts on the stack right now!) */
3210 req_sz = sizeof(get_pfacts); 3210 req_sz = sizeof(get_pfacts);
3211 memset(&get_pfacts, 0, req_sz); 3211 memset(&get_pfacts, 0, req_sz);
3212 3212
3213 get_pfacts.Function = MPI_FUNCTION_PORT_FACTS; 3213 get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
3214 get_pfacts.PortNumber = portnum; 3214 get_pfacts.PortNumber = portnum;
3215 /* Assert: All other get_pfacts fields are zero! */ 3215 /* Assert: All other get_pfacts fields are zero! */
3216 3216
3217 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending get PortFacts(%d) request\n", 3217 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending get PortFacts(%d) request\n",
3218 ioc->name, portnum)); 3218 ioc->name, portnum));
3219 3219
3220 /* No non-zero fields in the get_pfacts request are greater than 3220 /* No non-zero fields in the get_pfacts request are greater than
3221 * 1 byte in size, so we can just fire it off as is. 3221 * 1 byte in size, so we can just fire it off as is.
3222 */ 3222 */
3223 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts, 3223 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
3224 reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag); 3224 reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag);
3225 if (ii != 0) 3225 if (ii != 0)
3226 return ii; 3226 return ii;
3227 3227
3228 /* Did we get a valid reply? */ 3228 /* Did we get a valid reply? */
3229 3229
3230 /* Now byte swap the necessary fields in the response. */ 3230 /* Now byte swap the necessary fields in the response. */
3231 pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext); 3231 pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext);
3232 pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus); 3232 pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus);
3233 pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo); 3233 pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo);
3234 pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices); 3234 pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices);
3235 pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID); 3235 pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID);
3236 pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags); 3236 pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags);
3237 pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers); 3237 pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers);
3238 pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs); 3238 pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
3239 pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets); 3239 pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
3240 3240
3241 max_id = (ioc->bus_type == SAS) ? pfacts->PortSCSIID : 3241 max_id = (ioc->bus_type == SAS) ? pfacts->PortSCSIID :
3242 pfacts->MaxDevices; 3242 pfacts->MaxDevices;
3243 ioc->devices_per_bus = (max_id > 255) ? 256 : max_id; 3243 ioc->devices_per_bus = (max_id > 255) ? 256 : max_id;
3244 ioc->number_of_buses = (ioc->devices_per_bus < 256) ? 1 : max_id/256; 3244 ioc->number_of_buses = (ioc->devices_per_bus < 256) ? 1 : max_id/256;
3245 3245
3246 /* 3246 /*
3247 * Place all the devices on channels 3247 * Place all the devices on channels
3248 * 3248 *
3249 * (for debuging) 3249 * (for debuging)
3250 */ 3250 */
3251 if (mpt_channel_mapping) { 3251 if (mpt_channel_mapping) {
3252 ioc->devices_per_bus = 1; 3252 ioc->devices_per_bus = 1;
3253 ioc->number_of_buses = (max_id > 255) ? 255 : max_id; 3253 ioc->number_of_buses = (max_id > 255) ? 255 : max_id;
3254 } 3254 }
3255 3255
3256 return 0; 3256 return 0;
3257 } 3257 }
3258 3258
3259 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 3259 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3260 /** 3260 /**
3261 * SendIocInit - Send IOCInit request to MPT adapter. 3261 * SendIocInit - Send IOCInit request to MPT adapter.
3262 * @ioc: Pointer to MPT_ADAPTER structure 3262 * @ioc: Pointer to MPT_ADAPTER structure
3263 * @sleepFlag: Specifies whether the process can sleep 3263 * @sleepFlag: Specifies whether the process can sleep
3264 * 3264 *
3265 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state. 3265 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
3266 * 3266 *
3267 * Returns 0 for success, non-zero for failure. 3267 * Returns 0 for success, non-zero for failure.
3268 */ 3268 */
3269 static int 3269 static int
3270 SendIocInit(MPT_ADAPTER *ioc, int sleepFlag) 3270 SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
3271 { 3271 {
3272 IOCInit_t ioc_init; 3272 IOCInit_t ioc_init;
3273 MPIDefaultReply_t init_reply; 3273 MPIDefaultReply_t init_reply;
3274 u32 state; 3274 u32 state;
3275 int r; 3275 int r;
3276 int count; 3276 int count;
3277 int cntdn; 3277 int cntdn;
3278 3278
3279 memset(&ioc_init, 0, sizeof(ioc_init)); 3279 memset(&ioc_init, 0, sizeof(ioc_init));
3280 memset(&init_reply, 0, sizeof(init_reply)); 3280 memset(&init_reply, 0, sizeof(init_reply));
3281 3281
3282 ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER; 3282 ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;
3283 ioc_init.Function = MPI_FUNCTION_IOC_INIT; 3283 ioc_init.Function = MPI_FUNCTION_IOC_INIT;
3284 3284
3285 /* If we are in a recovery mode and we uploaded the FW image, 3285 /* If we are in a recovery mode and we uploaded the FW image,
3286 * then this pointer is not NULL. Skip the upload a second time. 3286 * then this pointer is not NULL. Skip the upload a second time.
3287 * Set this flag if cached_fw set for either IOC. 3287 * Set this flag if cached_fw set for either IOC.
3288 */ 3288 */
3289 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT) 3289 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
3290 ioc->upload_fw = 1; 3290 ioc->upload_fw = 1;
3291 else 3291 else
3292 ioc->upload_fw = 0; 3292 ioc->upload_fw = 0;
3293 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "upload_fw %d facts.Flags=%x\n", 3293 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "upload_fw %d facts.Flags=%x\n",
3294 ioc->name, ioc->upload_fw, ioc->facts.Flags)); 3294 ioc->name, ioc->upload_fw, ioc->facts.Flags));
3295 3295
3296 ioc_init.MaxDevices = (U8)ioc->devices_per_bus; 3296 ioc_init.MaxDevices = (U8)ioc->devices_per_bus;
3297 ioc_init.MaxBuses = (U8)ioc->number_of_buses; 3297 ioc_init.MaxBuses = (U8)ioc->number_of_buses;
3298 3298
3299 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "facts.MsgVersion=%x\n", 3299 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "facts.MsgVersion=%x\n",
3300 ioc->name, ioc->facts.MsgVersion)); 3300 ioc->name, ioc->facts.MsgVersion));
3301 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) { 3301 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) {
3302 // set MsgVersion and HeaderVersion host driver was built with 3302 // set MsgVersion and HeaderVersion host driver was built with
3303 ioc_init.MsgVersion = cpu_to_le16(MPI_VERSION); 3303 ioc_init.MsgVersion = cpu_to_le16(MPI_VERSION);
3304 ioc_init.HeaderVersion = cpu_to_le16(MPI_HEADER_VERSION); 3304 ioc_init.HeaderVersion = cpu_to_le16(MPI_HEADER_VERSION);
3305 3305
3306 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT) { 3306 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT) {
3307 ioc_init.HostPageBufferSGE = ioc->facts.HostPageBufferSGE; 3307 ioc_init.HostPageBufferSGE = ioc->facts.HostPageBufferSGE;
3308 } else if(mpt_host_page_alloc(ioc, &ioc_init)) 3308 } else if(mpt_host_page_alloc(ioc, &ioc_init))
3309 return -99; 3309 return -99;
3310 } 3310 }
3311 ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */ 3311 ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */
3312 3312
3313 if (ioc->sg_addr_size == sizeof(u64)) { 3313 if (ioc->sg_addr_size == sizeof(u64)) {
3314 /* Save the upper 32-bits of the request 3314 /* Save the upper 32-bits of the request
3315 * (reply) and sense buffers. 3315 * (reply) and sense buffers.
3316 */ 3316 */
3317 ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32)); 3317 ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32));
3318 ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32)); 3318 ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
3319 } else { 3319 } else {
3320 /* Force 32-bit addressing */ 3320 /* Force 32-bit addressing */
3321 ioc_init.HostMfaHighAddr = cpu_to_le32(0); 3321 ioc_init.HostMfaHighAddr = cpu_to_le32(0);
3322 ioc_init.SenseBufferHighAddr = cpu_to_le32(0); 3322 ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
3323 } 3323 }
3324 3324
3325 ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr; 3325 ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
3326 ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr; 3326 ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
3327 ioc->facts.MaxDevices = ioc_init.MaxDevices; 3327 ioc->facts.MaxDevices = ioc_init.MaxDevices;
3328 ioc->facts.MaxBuses = ioc_init.MaxBuses; 3328 ioc->facts.MaxBuses = ioc_init.MaxBuses;
3329 3329
3330 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOCInit (req @ %p)\n", 3330 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOCInit (req @ %p)\n",
3331 ioc->name, &ioc_init)); 3331 ioc->name, &ioc_init));
3332 3332
3333 r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init, 3333 r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
3334 sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag); 3334 sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
3335 if (r != 0) { 3335 if (r != 0) {
3336 printk(MYIOC_s_ERR_FMT "Sending IOCInit failed(%d)!\n",ioc->name, r); 3336 printk(MYIOC_s_ERR_FMT "Sending IOCInit failed(%d)!\n",ioc->name, r);
3337 return r; 3337 return r;
3338 } 3338 }
3339 3339
3340 /* No need to byte swap the multibyte fields in the reply 3340 /* No need to byte swap the multibyte fields in the reply
3341 * since we don't even look at its contents. 3341 * since we don't even look at its contents.
3342 */ 3342 */
3343 3343
3344 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending PortEnable (req @ %p)\n", 3344 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending PortEnable (req @ %p)\n",
3345 ioc->name, &ioc_init)); 3345 ioc->name, &ioc_init));
3346 3346
3347 if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0) { 3347 if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0) {
3348 printk(MYIOC_s_ERR_FMT "Sending PortEnable failed(%d)!\n",ioc->name, r); 3348 printk(MYIOC_s_ERR_FMT "Sending PortEnable failed(%d)!\n",ioc->name, r);
3349 return r; 3349 return r;
3350 } 3350 }
3351 3351
3352 /* YIKES! SUPER IMPORTANT!!! 3352 /* YIKES! SUPER IMPORTANT!!!
3353 * Poll IocState until _OPERATIONAL while IOC is doing 3353 * Poll IocState until _OPERATIONAL while IOC is doing
3354 * LoopInit and TargetDiscovery! 3354 * LoopInit and TargetDiscovery!
3355 */ 3355 */
3356 count = 0; 3356 count = 0;
3357 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60; /* 60 seconds */ 3357 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60; /* 60 seconds */
3358 state = mpt_GetIocState(ioc, 1); 3358 state = mpt_GetIocState(ioc, 1);
3359 while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) { 3359 while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
3360 if (sleepFlag == CAN_SLEEP) { 3360 if (sleepFlag == CAN_SLEEP) {
3361 msleep(1); 3361 msleep(1);
3362 } else { 3362 } else {
3363 mdelay(1); 3363 mdelay(1);
3364 } 3364 }
3365 3365
3366 if (!cntdn) { 3366 if (!cntdn) {
3367 printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n", 3367 printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
3368 ioc->name, (int)((count+5)/HZ)); 3368 ioc->name, (int)((count+5)/HZ));
3369 return -9; 3369 return -9;
3370 } 3370 }
3371 3371
3372 state = mpt_GetIocState(ioc, 1); 3372 state = mpt_GetIocState(ioc, 1);
3373 count++; 3373 count++;
3374 } 3374 }
3375 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wait IOC_OPERATIONAL state (cnt=%d)\n", 3375 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wait IOC_OPERATIONAL state (cnt=%d)\n",
3376 ioc->name, count)); 3376 ioc->name, count));
3377 3377
3378 ioc->aen_event_read_flag=0; 3378 ioc->aen_event_read_flag=0;
3379 return r; 3379 return r;
3380 } 3380 }
3381 3381
3382 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 3382 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3383 /** 3383 /**
3384 * SendPortEnable - Send PortEnable request to MPT adapter port. 3384 * SendPortEnable - Send PortEnable request to MPT adapter port.
3385 * @ioc: Pointer to MPT_ADAPTER structure 3385 * @ioc: Pointer to MPT_ADAPTER structure
3386 * @portnum: Port number to enable 3386 * @portnum: Port number to enable
3387 * @sleepFlag: Specifies whether the process can sleep 3387 * @sleepFlag: Specifies whether the process can sleep
3388 * 3388 *
3389 * Send PortEnable to bring IOC to OPERATIONAL state. 3389 * Send PortEnable to bring IOC to OPERATIONAL state.
3390 * 3390 *
3391 * Returns 0 for success, non-zero for failure. 3391 * Returns 0 for success, non-zero for failure.
3392 */ 3392 */
3393 static int 3393 static int
3394 SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag) 3394 SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
3395 { 3395 {
3396 PortEnable_t port_enable; 3396 PortEnable_t port_enable;
3397 MPIDefaultReply_t reply_buf; 3397 MPIDefaultReply_t reply_buf;
3398 int rc; 3398 int rc;
3399 int req_sz; 3399 int req_sz;
3400 int reply_sz; 3400 int reply_sz;
3401 3401
3402 /* Destination... */ 3402 /* Destination... */
3403 reply_sz = sizeof(MPIDefaultReply_t); 3403 reply_sz = sizeof(MPIDefaultReply_t);
3404 memset(&reply_buf, 0, reply_sz); 3404 memset(&reply_buf, 0, reply_sz);
3405 3405
3406 req_sz = sizeof(PortEnable_t); 3406 req_sz = sizeof(PortEnable_t);
3407 memset(&port_enable, 0, req_sz); 3407 memset(&port_enable, 0, req_sz);
3408 3408
3409 port_enable.Function = MPI_FUNCTION_PORT_ENABLE; 3409 port_enable.Function = MPI_FUNCTION_PORT_ENABLE;
3410 port_enable.PortNumber = portnum; 3410 port_enable.PortNumber = portnum;
3411 /* port_enable.ChainOffset = 0; */ 3411 /* port_enable.ChainOffset = 0; */
3412 /* port_enable.MsgFlags = 0; */ 3412 /* port_enable.MsgFlags = 0; */
3413 /* port_enable.MsgContext = 0; */ 3413 /* port_enable.MsgContext = 0; */
3414 3414
3415 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Port(%d)Enable (req @ %p)\n", 3415 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Port(%d)Enable (req @ %p)\n",
3416 ioc->name, portnum, &port_enable)); 3416 ioc->name, portnum, &port_enable));
3417 3417
3418 /* RAID FW may take a long time to enable 3418 /* RAID FW may take a long time to enable
3419 */ 3419 */
3420 if (ioc->ir_firmware || ioc->bus_type == SAS) { 3420 if (ioc->ir_firmware || ioc->bus_type == SAS) {
3421 rc = mpt_handshake_req_reply_wait(ioc, req_sz, 3421 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3422 (u32*)&port_enable, reply_sz, (u16*)&reply_buf, 3422 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3423 300 /*seconds*/, sleepFlag); 3423 300 /*seconds*/, sleepFlag);
3424 } else { 3424 } else {
3425 rc = mpt_handshake_req_reply_wait(ioc, req_sz, 3425 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3426 (u32*)&port_enable, reply_sz, (u16*)&reply_buf, 3426 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3427 30 /*seconds*/, sleepFlag); 3427 30 /*seconds*/, sleepFlag);
3428 } 3428 }
3429 return rc; 3429 return rc;
3430 } 3430 }
3431 3431
3432 /** 3432 /**
3433 * mpt_alloc_fw_memory - allocate firmware memory 3433 * mpt_alloc_fw_memory - allocate firmware memory
3434 * @ioc: Pointer to MPT_ADAPTER structure 3434 * @ioc: Pointer to MPT_ADAPTER structure
3435 * @size: total FW bytes 3435 * @size: total FW bytes
3436 * 3436 *
3437 * If memory has already been allocated, the same (cached) value 3437 * If memory has already been allocated, the same (cached) value
3438 * is returned. 3438 * is returned.
3439 * 3439 *
3440 * Return 0 if successfull, or non-zero for failure 3440 * Return 0 if successfull, or non-zero for failure
3441 **/ 3441 **/
3442 int 3442 int
3443 mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size) 3443 mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
3444 { 3444 {
3445 int rc; 3445 int rc;
3446 3446
3447 if (ioc->cached_fw) { 3447 if (ioc->cached_fw) {
3448 rc = 0; /* use already allocated memory */ 3448 rc = 0; /* use already allocated memory */
3449 goto out; 3449 goto out;
3450 } 3450 }
3451 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) { 3451 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
3452 ioc->cached_fw = ioc->alt_ioc->cached_fw; /* use alt_ioc's memory */ 3452 ioc->cached_fw = ioc->alt_ioc->cached_fw; /* use alt_ioc's memory */
3453 ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma; 3453 ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
3454 rc = 0; 3454 rc = 0;
3455 goto out; 3455 goto out;
3456 } 3456 }
3457 ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma); 3457 ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma);
3458 if (!ioc->cached_fw) { 3458 if (!ioc->cached_fw) {
3459 printk(MYIOC_s_ERR_FMT "Unable to allocate memory for the cached firmware image!\n", 3459 printk(MYIOC_s_ERR_FMT "Unable to allocate memory for the cached firmware image!\n",
3460 ioc->name); 3460 ioc->name);
3461 rc = -1; 3461 rc = -1;
3462 } else { 3462 } else {
3463 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FW Image @ %p[%p], sz=%d[%x] bytes\n", 3463 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FW Image @ %p[%p], sz=%d[%x] bytes\n",
3464 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, size, size)); 3464 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, size, size));
3465 ioc->alloc_total += size; 3465 ioc->alloc_total += size;
3466 rc = 0; 3466 rc = 0;
3467 } 3467 }
3468 out: 3468 out:
3469 return rc; 3469 return rc;
3470 } 3470 }
3471 3471
3472 /** 3472 /**
3473 * mpt_free_fw_memory - free firmware memory 3473 * mpt_free_fw_memory - free firmware memory
3474 * @ioc: Pointer to MPT_ADAPTER structure 3474 * @ioc: Pointer to MPT_ADAPTER structure
3475 * 3475 *
3476 * If alt_img is NULL, delete from ioc structure. 3476 * If alt_img is NULL, delete from ioc structure.
3477 * Else, delete a secondary image in same format. 3477 * Else, delete a secondary image in same format.
3478 **/ 3478 **/
3479 void 3479 void
3480 mpt_free_fw_memory(MPT_ADAPTER *ioc) 3480 mpt_free_fw_memory(MPT_ADAPTER *ioc)
3481 { 3481 {
3482 int sz; 3482 int sz;
3483 3483
3484 if (!ioc->cached_fw) 3484 if (!ioc->cached_fw)
3485 return; 3485 return;
3486 3486
3487 sz = ioc->facts.FWImageSize; 3487 sz = ioc->facts.FWImageSize;
3488 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n", 3488 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
3489 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz)); 3489 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3490 pci_free_consistent(ioc->pcidev, sz, ioc->cached_fw, ioc->cached_fw_dma); 3490 pci_free_consistent(ioc->pcidev, sz, ioc->cached_fw, ioc->cached_fw_dma);
3491 ioc->alloc_total -= sz; 3491 ioc->alloc_total -= sz;
3492 ioc->cached_fw = NULL; 3492 ioc->cached_fw = NULL;
3493 } 3493 }
3494 3494
3495 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 3495 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3496 /** 3496 /**
3497 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port. 3497 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
3498 * @ioc: Pointer to MPT_ADAPTER structure 3498 * @ioc: Pointer to MPT_ADAPTER structure
3499 * @sleepFlag: Specifies whether the process can sleep 3499 * @sleepFlag: Specifies whether the process can sleep
3500 * 3500 *
3501 * Returns 0 for success, >0 for handshake failure 3501 * Returns 0 for success, >0 for handshake failure
3502 * <0 for fw upload failure. 3502 * <0 for fw upload failure.
3503 * 3503 *
3504 * Remark: If bound IOC and a successful FWUpload was performed 3504 * Remark: If bound IOC and a successful FWUpload was performed
3505 * on the bound IOC, the second image is discarded 3505 * on the bound IOC, the second image is discarded
3506 * and memory is free'd. Both channels must upload to prevent 3506 * and memory is free'd. Both channels must upload to prevent
3507 * IOC from running in degraded mode. 3507 * IOC from running in degraded mode.
3508 */ 3508 */
3509 static int 3509 static int
3510 mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag) 3510 mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
3511 { 3511 {
3512 u8 reply[sizeof(FWUploadReply_t)]; 3512 u8 reply[sizeof(FWUploadReply_t)];
3513 FWUpload_t *prequest; 3513 FWUpload_t *prequest;
3514 FWUploadReply_t *preply; 3514 FWUploadReply_t *preply;
3515 FWUploadTCSGE_t *ptcsge; 3515 FWUploadTCSGE_t *ptcsge;
3516 u32 flagsLength; 3516 u32 flagsLength;
3517 int ii, sz, reply_sz; 3517 int ii, sz, reply_sz;
3518 int cmdStatus; 3518 int cmdStatus;
3519 int request_size; 3519 int request_size;
3520 /* If the image size is 0, we are done. 3520 /* If the image size is 0, we are done.
3521 */ 3521 */
3522 if ((sz = ioc->facts.FWImageSize) == 0) 3522 if ((sz = ioc->facts.FWImageSize) == 0)
3523 return 0; 3523 return 0;
3524 3524
3525 if (mpt_alloc_fw_memory(ioc, ioc->facts.FWImageSize) != 0) 3525 if (mpt_alloc_fw_memory(ioc, ioc->facts.FWImageSize) != 0)
3526 return -ENOMEM; 3526 return -ENOMEM;
3527 3527
3528 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": FW Image @ %p[%p], sz=%d[%x] bytes\n", 3528 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": FW Image @ %p[%p], sz=%d[%x] bytes\n",
3529 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz)); 3529 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3530 3530
3531 prequest = (sleepFlag == NO_SLEEP) ? kzalloc(ioc->req_sz, GFP_ATOMIC) : 3531 prequest = (sleepFlag == NO_SLEEP) ? kzalloc(ioc->req_sz, GFP_ATOMIC) :
3532 kzalloc(ioc->req_sz, GFP_KERNEL); 3532 kzalloc(ioc->req_sz, GFP_KERNEL);
3533 if (!prequest) { 3533 if (!prequest) {
3534 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "fw upload failed " 3534 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "fw upload failed "
3535 "while allocating memory \n", ioc->name)); 3535 "while allocating memory \n", ioc->name));
3536 mpt_free_fw_memory(ioc); 3536 mpt_free_fw_memory(ioc);
3537 return -ENOMEM; 3537 return -ENOMEM;
3538 } 3538 }
3539 3539
3540 preply = (FWUploadReply_t *)&reply; 3540 preply = (FWUploadReply_t *)&reply;
3541 3541
3542 reply_sz = sizeof(reply); 3542 reply_sz = sizeof(reply);
3543 memset(preply, 0, reply_sz); 3543 memset(preply, 0, reply_sz);
3544 3544
3545 prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM; 3545 prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
3546 prequest->Function = MPI_FUNCTION_FW_UPLOAD; 3546 prequest->Function = MPI_FUNCTION_FW_UPLOAD;
3547 3547
3548 ptcsge = (FWUploadTCSGE_t *) &prequest->SGL; 3548 ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
3549 ptcsge->DetailsLength = 12; 3549 ptcsge->DetailsLength = 12;
3550 ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT; 3550 ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
3551 ptcsge->ImageSize = cpu_to_le32(sz); 3551 ptcsge->ImageSize = cpu_to_le32(sz);
3552 ptcsge++; 3552 ptcsge++;
3553 3553
3554 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz; 3554 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
3555 ioc->add_sge((char *)ptcsge, flagsLength, ioc->cached_fw_dma); 3555 ioc->add_sge((char *)ptcsge, flagsLength, ioc->cached_fw_dma);
3556 request_size = offsetof(FWUpload_t, SGL) + sizeof(FWUploadTCSGE_t) + 3556 request_size = offsetof(FWUpload_t, SGL) + sizeof(FWUploadTCSGE_t) +
3557 ioc->SGE_size; 3557 ioc->SGE_size;
3558 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending FW Upload " 3558 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending FW Upload "
3559 " (req @ %p) fw_size=%d mf_request_size=%d\n", ioc->name, prequest, 3559 " (req @ %p) fw_size=%d mf_request_size=%d\n", ioc->name, prequest,
3560 ioc->facts.FWImageSize, request_size)); 3560 ioc->facts.FWImageSize, request_size));
3561 DBG_DUMP_FW_REQUEST_FRAME(ioc, (u32 *)prequest); 3561 DBG_DUMP_FW_REQUEST_FRAME(ioc, (u32 *)prequest);
3562 3562
3563 ii = mpt_handshake_req_reply_wait(ioc, request_size, (u32 *)prequest, 3563 ii = mpt_handshake_req_reply_wait(ioc, request_size, (u32 *)prequest,
3564 reply_sz, (u16 *)preply, 65 /*seconds*/, sleepFlag); 3564 reply_sz, (u16 *)preply, 65 /*seconds*/, sleepFlag);
3565 3565
3566 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FW Upload completed " 3566 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FW Upload completed "
3567 "rc=%x \n", ioc->name, ii)); 3567 "rc=%x \n", ioc->name, ii));
3568 3568
3569 cmdStatus = -EFAULT; 3569 cmdStatus = -EFAULT;
3570 if (ii == 0) { 3570 if (ii == 0) {
3571 /* Handshake transfer was complete and successful. 3571 /* Handshake transfer was complete and successful.
3572 * Check the Reply Frame. 3572 * Check the Reply Frame.
3573 */ 3573 */
3574 int status; 3574 int status;
3575 status = le16_to_cpu(preply->IOCStatus) & 3575 status = le16_to_cpu(preply->IOCStatus) &
3576 MPI_IOCSTATUS_MASK; 3576 MPI_IOCSTATUS_MASK;
3577 if (status == MPI_IOCSTATUS_SUCCESS && 3577 if (status == MPI_IOCSTATUS_SUCCESS &&
3578 ioc->facts.FWImageSize == 3578 ioc->facts.FWImageSize ==
3579 le32_to_cpu(preply->ActualImageSize)) 3579 le32_to_cpu(preply->ActualImageSize))
3580 cmdStatus = 0; 3580 cmdStatus = 0;
3581 } 3581 }
3582 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": do_upload cmdStatus=%d \n", 3582 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": do_upload cmdStatus=%d \n",
3583 ioc->name, cmdStatus)); 3583 ioc->name, cmdStatus));
3584 3584
3585 3585
3586 if (cmdStatus) { 3586 if (cmdStatus) {
3587 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "fw upload failed, " 3587 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "fw upload failed, "
3588 "freeing image \n", ioc->name)); 3588 "freeing image \n", ioc->name));
3589 mpt_free_fw_memory(ioc); 3589 mpt_free_fw_memory(ioc);
3590 } 3590 }
3591 kfree(prequest); 3591 kfree(prequest);
3592 3592
3593 return cmdStatus; 3593 return cmdStatus;
3594 } 3594 }
3595 3595
3596 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 3596 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3597 /** 3597 /**
3598 * mpt_downloadboot - DownloadBoot code 3598 * mpt_downloadboot - DownloadBoot code
3599 * @ioc: Pointer to MPT_ADAPTER structure 3599 * @ioc: Pointer to MPT_ADAPTER structure
3600 * @pFwHeader: Pointer to firmware header info 3600 * @pFwHeader: Pointer to firmware header info
3601 * @sleepFlag: Specifies whether the process can sleep 3601 * @sleepFlag: Specifies whether the process can sleep
3602 * 3602 *
3603 * FwDownloadBoot requires Programmed IO access. 3603 * FwDownloadBoot requires Programmed IO access.
3604 * 3604 *
3605 * Returns 0 for success 3605 * Returns 0 for success
3606 * -1 FW Image size is 0 3606 * -1 FW Image size is 0
3607 * -2 No valid cached_fw Pointer 3607 * -2 No valid cached_fw Pointer
3608 * <0 for fw upload failure. 3608 * <0 for fw upload failure.
3609 */ 3609 */
3610 static int 3610 static int
3611 mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag) 3611 mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
3612 { 3612 {
3613 MpiExtImageHeader_t *pExtImage; 3613 MpiExtImageHeader_t *pExtImage;
3614 u32 fwSize; 3614 u32 fwSize;
3615 u32 diag0val; 3615 u32 diag0val;
3616 int count; 3616 int count;
3617 u32 *ptrFw; 3617 u32 *ptrFw;
3618 u32 diagRwData; 3618 u32 diagRwData;
3619 u32 nextImage; 3619 u32 nextImage;
3620 u32 load_addr; 3620 u32 load_addr;
3621 u32 ioc_state=0; 3621 u32 ioc_state=0;
3622 3622
3623 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n", 3623 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
3624 ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader)); 3624 ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader));
3625 3625
3626 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF); 3626 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3627 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE); 3627 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3628 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE); 3628 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3629 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE); 3629 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3630 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE); 3630 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3631 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE); 3631 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3632 3632
3633 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM)); 3633 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
3634 3634
3635 /* wait 1 msec */ 3635 /* wait 1 msec */
3636 if (sleepFlag == CAN_SLEEP) { 3636 if (sleepFlag == CAN_SLEEP) {
3637 msleep(1); 3637 msleep(1);
3638 } else { 3638 } else {
3639 mdelay (1); 3639 mdelay (1);
3640 } 3640 }
3641 3641
3642 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic); 3642 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3643 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER); 3643 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3644 3644
3645 for (count = 0; count < 30; count ++) { 3645 for (count = 0; count < 30; count ++) {
3646 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic); 3646 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3647 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) { 3647 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3648 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RESET_ADAPTER cleared, count=%d\n", 3648 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RESET_ADAPTER cleared, count=%d\n",
3649 ioc->name, count)); 3649 ioc->name, count));
3650 break; 3650 break;
3651 } 3651 }
3652 /* wait .1 sec */ 3652 /* wait .1 sec */
3653 if (sleepFlag == CAN_SLEEP) { 3653 if (sleepFlag == CAN_SLEEP) {
3654 msleep (100); 3654 msleep (100);
3655 } else { 3655 } else {
3656 mdelay (100); 3656 mdelay (100);
3657 } 3657 }
3658 } 3658 }
3659 3659
3660 if ( count == 30 ) { 3660 if ( count == 30 ) {
3661 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot failed! " 3661 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot failed! "
3662 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n", 3662 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
3663 ioc->name, diag0val)); 3663 ioc->name, diag0val));
3664 return -3; 3664 return -3;
3665 } 3665 }
3666 3666
3667 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF); 3667 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3668 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE); 3668 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3669 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE); 3669 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3670 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE); 3670 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3671 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE); 3671 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3672 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE); 3672 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3673 3673
3674 /* Set the DiagRwEn and Disable ARM bits */ 3674 /* Set the DiagRwEn and Disable ARM bits */
3675 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM)); 3675 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
3676 3676
3677 fwSize = (pFwHeader->ImageSize + 3)/4; 3677 fwSize = (pFwHeader->ImageSize + 3)/4;
3678 ptrFw = (u32 *) pFwHeader; 3678 ptrFw = (u32 *) pFwHeader;
3679 3679
3680 /* Write the LoadStartAddress to the DiagRw Address Register 3680 /* Write the LoadStartAddress to the DiagRw Address Register
3681 * using Programmed IO 3681 * using Programmed IO
3682 */ 3682 */
3683 if (ioc->errata_flag_1064) 3683 if (ioc->errata_flag_1064)
3684 pci_enable_io_access(ioc->pcidev); 3684 pci_enable_io_access(ioc->pcidev);
3685 3685
3686 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress); 3686 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
3687 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "LoadStart addr written 0x%x \n", 3687 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "LoadStart addr written 0x%x \n",
3688 ioc->name, pFwHeader->LoadStartAddress)); 3688 ioc->name, pFwHeader->LoadStartAddress));
3689 3689
3690 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write FW Image: 0x%x bytes @ %p\n", 3690 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write FW Image: 0x%x bytes @ %p\n",
3691 ioc->name, fwSize*4, ptrFw)); 3691 ioc->name, fwSize*4, ptrFw));
3692 while (fwSize--) { 3692 while (fwSize--) {
3693 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++); 3693 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3694 } 3694 }
3695 3695
3696 nextImage = pFwHeader->NextImageHeaderOffset; 3696 nextImage = pFwHeader->NextImageHeaderOffset;
3697 while (nextImage) { 3697 while (nextImage) {
3698 pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage); 3698 pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage);
3699 3699
3700 load_addr = pExtImage->LoadStartAddress; 3700 load_addr = pExtImage->LoadStartAddress;
3701 3701
3702 fwSize = (pExtImage->ImageSize + 3) >> 2; 3702 fwSize = (pExtImage->ImageSize + 3) >> 2;
3703 ptrFw = (u32 *)pExtImage; 3703 ptrFw = (u32 *)pExtImage;
3704 3704
3705 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n", 3705 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
3706 ioc->name, fwSize*4, fwSize*4, ptrFw, load_addr)); 3706 ioc->name, fwSize*4, fwSize*4, ptrFw, load_addr));
3707 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr); 3707 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
3708 3708
3709 while (fwSize--) { 3709 while (fwSize--) {
3710 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++); 3710 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3711 } 3711 }
3712 nextImage = pExtImage->NextImageHeaderOffset; 3712 nextImage = pExtImage->NextImageHeaderOffset;
3713 } 3713 }
3714 3714
3715 /* Write the IopResetVectorRegAddr */ 3715 /* Write the IopResetVectorRegAddr */
3716 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Addr=%x! \n", ioc->name, pFwHeader->IopResetRegAddr)); 3716 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Addr=%x! \n", ioc->name, pFwHeader->IopResetRegAddr));
3717 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr); 3717 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr);
3718 3718
3719 /* Write the IopResetVectorValue */ 3719 /* Write the IopResetVectorValue */
3720 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue)); 3720 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue));
3721 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue); 3721 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
3722 3722
3723 /* Clear the internal flash bad bit - autoincrementing register, 3723 /* Clear the internal flash bad bit - autoincrementing register,
3724 * so must do two writes. 3724 * so must do two writes.
3725 */ 3725 */
3726 if (ioc->bus_type == SPI) { 3726 if (ioc->bus_type == SPI) {
3727 /* 3727 /*
3728 * 1030 and 1035 H/W errata, workaround to access 3728 * 1030 and 1035 H/W errata, workaround to access
3729 * the ClearFlashBadSignatureBit 3729 * the ClearFlashBadSignatureBit
3730 */ 3730 */
3731 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000); 3731 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3732 diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData); 3732 diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
3733 diagRwData |= 0x40000000; 3733 diagRwData |= 0x40000000;
3734 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000); 3734 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3735 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData); 3735 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
3736 3736
3737 } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ { 3737 } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
3738 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic); 3738 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3739 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | 3739 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val |
3740 MPI_DIAG_CLEAR_FLASH_BAD_SIG); 3740 MPI_DIAG_CLEAR_FLASH_BAD_SIG);
3741 3741
3742 /* wait 1 msec */ 3742 /* wait 1 msec */
3743 if (sleepFlag == CAN_SLEEP) { 3743 if (sleepFlag == CAN_SLEEP) {
3744 msleep (1); 3744 msleep (1);
3745 } else { 3745 } else {
3746 mdelay (1); 3746 mdelay (1);
3747 } 3747 }
3748 } 3748 }
3749 3749
3750 if (ioc->errata_flag_1064) 3750 if (ioc->errata_flag_1064)
3751 pci_disable_io_access(ioc->pcidev); 3751 pci_disable_io_access(ioc->pcidev);
3752 3752
3753 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic); 3753 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3754 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot diag0val=%x, " 3754 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot diag0val=%x, "
3755 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n", 3755 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3756 ioc->name, diag0val)); 3756 ioc->name, diag0val));
3757 diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE); 3757 diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE);
3758 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot now diag0val=%x\n", 3758 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot now diag0val=%x\n",
3759 ioc->name, diag0val)); 3759 ioc->name, diag0val));
3760 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val); 3760 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3761 3761
3762 /* Write 0xFF to reset the sequencer */ 3762 /* Write 0xFF to reset the sequencer */
3763 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF); 3763 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3764 3764
3765 if (ioc->bus_type == SAS) { 3765 if (ioc->bus_type == SAS) {
3766 ioc_state = mpt_GetIocState(ioc, 0); 3766 ioc_state = mpt_GetIocState(ioc, 0);
3767 if ( (GetIocFacts(ioc, sleepFlag, 3767 if ( (GetIocFacts(ioc, sleepFlag,
3768 MPT_HOSTEVENT_IOC_BRINGUP)) != 0 ) { 3768 MPT_HOSTEVENT_IOC_BRINGUP)) != 0 ) {
3769 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "GetIocFacts failed: IocState=%x\n", 3769 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "GetIocFacts failed: IocState=%x\n",
3770 ioc->name, ioc_state)); 3770 ioc->name, ioc_state));
3771 return -EFAULT; 3771 return -EFAULT;
3772 } 3772 }
3773 } 3773 }
3774 3774
3775 for (count=0; count<HZ*20; count++) { 3775 for (count=0; count<HZ*20; count++) {
3776 if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) { 3776 if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
3777 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT 3777 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3778 "downloadboot successful! (count=%d) IocState=%x\n", 3778 "downloadboot successful! (count=%d) IocState=%x\n",
3779 ioc->name, count, ioc_state)); 3779 ioc->name, count, ioc_state));
3780 if (ioc->bus_type == SAS) { 3780 if (ioc->bus_type == SAS) {
3781 return 0; 3781 return 0;
3782 } 3782 }
3783 if ((SendIocInit(ioc, sleepFlag)) != 0) { 3783 if ((SendIocInit(ioc, sleepFlag)) != 0) {
3784 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT 3784 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3785 "downloadboot: SendIocInit failed\n", 3785 "downloadboot: SendIocInit failed\n",
3786 ioc->name)); 3786 ioc->name));
3787 return -EFAULT; 3787 return -EFAULT;
3788 } 3788 }
3789 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT 3789 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3790 "downloadboot: SendIocInit successful\n", 3790 "downloadboot: SendIocInit successful\n",
3791 ioc->name)); 3791 ioc->name));
3792 return 0; 3792 return 0;
3793 } 3793 }
3794 if (sleepFlag == CAN_SLEEP) { 3794 if (sleepFlag == CAN_SLEEP) {
3795 msleep (10); 3795 msleep (10);
3796 } else { 3796 } else {
3797 mdelay (10); 3797 mdelay (10);
3798 } 3798 }
3799 } 3799 }
3800 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT 3800 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3801 "downloadboot failed! IocState=%x\n",ioc->name, ioc_state)); 3801 "downloadboot failed! IocState=%x\n",ioc->name, ioc_state));
3802 return -EFAULT; 3802 return -EFAULT;
3803 } 3803 }
3804 3804
3805 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 3805 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3806 /** 3806 /**
3807 * KickStart - Perform hard reset of MPT adapter. 3807 * KickStart - Perform hard reset of MPT adapter.
3808 * @ioc: Pointer to MPT_ADAPTER structure 3808 * @ioc: Pointer to MPT_ADAPTER structure
3809 * @force: Force hard reset 3809 * @force: Force hard reset
3810 * @sleepFlag: Specifies whether the process can sleep 3810 * @sleepFlag: Specifies whether the process can sleep
3811 * 3811 *
3812 * This routine places MPT adapter in diagnostic mode via the 3812 * This routine places MPT adapter in diagnostic mode via the
3813 * WriteSequence register, and then performs a hard reset of adapter 3813 * WriteSequence register, and then performs a hard reset of adapter
3814 * via the Diagnostic register. 3814 * via the Diagnostic register.
3815 * 3815 *
3816 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread) 3816 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread)
3817 * or NO_SLEEP (interrupt thread, use mdelay) 3817 * or NO_SLEEP (interrupt thread, use mdelay)
3818 * force - 1 if doorbell active, board fault state 3818 * force - 1 if doorbell active, board fault state
3819 * board operational, IOC_RECOVERY or 3819 * board operational, IOC_RECOVERY or
3820 * IOC_BRINGUP and there is an alt_ioc. 3820 * IOC_BRINGUP and there is an alt_ioc.
3821 * 0 else 3821 * 0 else
3822 * 3822 *
3823 * Returns: 3823 * Returns:
3824 * 1 - hard reset, READY 3824 * 1 - hard reset, READY
3825 * 0 - no reset due to History bit, READY 3825 * 0 - no reset due to History bit, READY
3826 * -1 - no reset due to History bit but not READY 3826 * -1 - no reset due to History bit but not READY
3827 * OR reset but failed to come READY 3827 * OR reset but failed to come READY
3828 * -2 - no reset, could not enter DIAG mode 3828 * -2 - no reset, could not enter DIAG mode
3829 * -3 - reset but bad FW bit 3829 * -3 - reset but bad FW bit
3830 */ 3830 */
3831 static int 3831 static int
3832 KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag) 3832 KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
3833 { 3833 {
3834 int hard_reset_done = 0; 3834 int hard_reset_done = 0;
3835 u32 ioc_state=0; 3835 u32 ioc_state=0;
3836 int cnt,cntdn; 3836 int cnt,cntdn;
3837 3837
3838 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStarting!\n", ioc->name)); 3838 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStarting!\n", ioc->name));
3839 if (ioc->bus_type == SPI) { 3839 if (ioc->bus_type == SPI) {
3840 /* Always issue a Msg Unit Reset first. This will clear some 3840 /* Always issue a Msg Unit Reset first. This will clear some
3841 * SCSI bus hang conditions. 3841 * SCSI bus hang conditions.
3842 */ 3842 */
3843 SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag); 3843 SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
3844 3844
3845 if (sleepFlag == CAN_SLEEP) { 3845 if (sleepFlag == CAN_SLEEP) {
3846 msleep (1000); 3846 msleep (1000);
3847 } else { 3847 } else {
3848 mdelay (1000); 3848 mdelay (1000);
3849 } 3849 }
3850 } 3850 }
3851 3851
3852 hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag); 3852 hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
3853 if (hard_reset_done < 0) 3853 if (hard_reset_done < 0)
3854 return hard_reset_done; 3854 return hard_reset_done;
3855 3855
3856 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset successful!\n", 3856 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset successful!\n",
3857 ioc->name)); 3857 ioc->name));
3858 3858
3859 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2; /* 2 seconds */ 3859 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2; /* 2 seconds */
3860 for (cnt=0; cnt<cntdn; cnt++) { 3860 for (cnt=0; cnt<cntdn; cnt++) {
3861 ioc_state = mpt_GetIocState(ioc, 1); 3861 ioc_state = mpt_GetIocState(ioc, 1);
3862 if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) { 3862 if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) {
3863 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStart successful! (cnt=%d)\n", 3863 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStart successful! (cnt=%d)\n",
3864 ioc->name, cnt)); 3864 ioc->name, cnt));
3865 return hard_reset_done; 3865 return hard_reset_done;
3866 } 3866 }
3867 if (sleepFlag == CAN_SLEEP) { 3867 if (sleepFlag == CAN_SLEEP) {
3868 msleep (10); 3868 msleep (10);
3869 } else { 3869 } else {
3870 mdelay (10); 3870 mdelay (10);
3871 } 3871 }
3872 } 3872 }
3873 3873
3874 dinitprintk(ioc, printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n", 3874 dinitprintk(ioc, printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n",
3875 ioc->name, mpt_GetIocState(ioc, 0))); 3875 ioc->name, mpt_GetIocState(ioc, 0)));
3876 return -1; 3876 return -1;
3877 } 3877 }
3878 3878
3879 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 3879 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3880 /** 3880 /**
3881 * mpt_diag_reset - Perform hard reset of the adapter. 3881 * mpt_diag_reset - Perform hard reset of the adapter.
3882 * @ioc: Pointer to MPT_ADAPTER structure 3882 * @ioc: Pointer to MPT_ADAPTER structure
3883 * @ignore: Set if to honor and clear to ignore 3883 * @ignore: Set if to honor and clear to ignore
3884 * the reset history bit 3884 * the reset history bit
3885 * @sleepFlag: CAN_SLEEP if called in a non-interrupt thread, 3885 * @sleepFlag: CAN_SLEEP if called in a non-interrupt thread,
3886 * else set to NO_SLEEP (use mdelay instead) 3886 * else set to NO_SLEEP (use mdelay instead)
3887 * 3887 *
3888 * This routine places the adapter in diagnostic mode via the 3888 * This routine places the adapter in diagnostic mode via the
3889 * WriteSequence register and then performs a hard reset of adapter 3889 * WriteSequence register and then performs a hard reset of adapter
3890 * via the Diagnostic register. Adapter should be in ready state 3890 * via the Diagnostic register. Adapter should be in ready state
3891 * upon successful completion. 3891 * upon successful completion.
3892 * 3892 *
3893 * Returns: 1 hard reset successful 3893 * Returns: 1 hard reset successful
3894 * 0 no reset performed because reset history bit set 3894 * 0 no reset performed because reset history bit set
3895 * -2 enabling diagnostic mode failed 3895 * -2 enabling diagnostic mode failed
3896 * -3 diagnostic reset failed 3896 * -3 diagnostic reset failed
3897 */ 3897 */
3898 static int 3898 static int
3899 mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag) 3899 mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3900 { 3900 {
3901 u32 diag0val; 3901 u32 diag0val;
3902 u32 doorbell; 3902 u32 doorbell;
3903 int hard_reset_done = 0; 3903 int hard_reset_done = 0;
3904 int count = 0; 3904 int count = 0;
3905 u32 diag1val = 0; 3905 u32 diag1val = 0;
3906 MpiFwHeader_t *cached_fw; /* Pointer to FW */ 3906 MpiFwHeader_t *cached_fw; /* Pointer to FW */
3907 u8 cb_idx; 3907 u8 cb_idx;
3908 3908
3909 /* Clear any existing interrupts */ 3909 /* Clear any existing interrupts */
3910 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); 3910 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3911 3911
3912 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) { 3912 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
3913 3913
3914 if (!ignore) 3914 if (!ignore)
3915 return 0; 3915 return 0;
3916 3916
3917 drsprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset " 3917 drsprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset "
3918 "address=%p\n", ioc->name, __func__, 3918 "address=%p\n", ioc->name, __func__,
3919 &ioc->chip->Doorbell, &ioc->chip->Reset_1078)); 3919 &ioc->chip->Doorbell, &ioc->chip->Reset_1078));
3920 CHIPREG_WRITE32(&ioc->chip->Reset_1078, 0x07); 3920 CHIPREG_WRITE32(&ioc->chip->Reset_1078, 0x07);
3921 if (sleepFlag == CAN_SLEEP) 3921 if (sleepFlag == CAN_SLEEP)
3922 msleep(1); 3922 msleep(1);
3923 else 3923 else
3924 mdelay(1); 3924 mdelay(1);
3925 3925
3926 /* 3926 /*
3927 * Call each currently registered protocol IOC reset handler 3927 * Call each currently registered protocol IOC reset handler
3928 * with pre-reset indication. 3928 * with pre-reset indication.
3929 * NOTE: If we're doing _IOC_BRINGUP, there can be no 3929 * NOTE: If we're doing _IOC_BRINGUP, there can be no
3930 * MptResetHandlers[] registered yet. 3930 * MptResetHandlers[] registered yet.
3931 */ 3931 */
3932 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) { 3932 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
3933 if (MptResetHandlers[cb_idx]) 3933 if (MptResetHandlers[cb_idx])
3934 (*(MptResetHandlers[cb_idx]))(ioc, 3934 (*(MptResetHandlers[cb_idx]))(ioc,
3935 MPT_IOC_PRE_RESET); 3935 MPT_IOC_PRE_RESET);
3936 } 3936 }
3937 3937
3938 for (count = 0; count < 60; count ++) { 3938 for (count = 0; count < 60; count ++) {
3939 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell); 3939 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3940 doorbell &= MPI_IOC_STATE_MASK; 3940 doorbell &= MPI_IOC_STATE_MASK;
3941 3941
3942 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT 3942 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3943 "looking for READY STATE: doorbell=%x" 3943 "looking for READY STATE: doorbell=%x"
3944 " count=%d\n", 3944 " count=%d\n",
3945 ioc->name, doorbell, count)); 3945 ioc->name, doorbell, count));
3946 3946
3947 if (doorbell == MPI_IOC_STATE_READY) { 3947 if (doorbell == MPI_IOC_STATE_READY) {
3948 return 1; 3948 return 1;
3949 } 3949 }
3950 3950
3951 /* wait 1 sec */ 3951 /* wait 1 sec */
3952 if (sleepFlag == CAN_SLEEP) 3952 if (sleepFlag == CAN_SLEEP)
3953 msleep(1000); 3953 msleep(1000);
3954 else 3954 else
3955 mdelay(1000); 3955 mdelay(1000);
3956 } 3956 }
3957 return -1; 3957 return -1;
3958 } 3958 }
3959 3959
3960 /* Use "Diagnostic reset" method! (only thing available!) */ 3960 /* Use "Diagnostic reset" method! (only thing available!) */
3961 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic); 3961 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3962 3962
3963 if (ioc->debug_level & MPT_DEBUG) { 3963 if (ioc->debug_level & MPT_DEBUG) {
3964 if (ioc->alt_ioc) 3964 if (ioc->alt_ioc)
3965 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic); 3965 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3966 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG1: diag0=%08x, diag1=%08x\n", 3966 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG1: diag0=%08x, diag1=%08x\n",
3967 ioc->name, diag0val, diag1val)); 3967 ioc->name, diag0val, diag1val));
3968 } 3968 }
3969 3969
3970 /* Do the reset if we are told to ignore the reset history 3970 /* Do the reset if we are told to ignore the reset history
3971 * or if the reset history is 0 3971 * or if the reset history is 0
3972 */ 3972 */
3973 if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) { 3973 if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
3974 while ((diag0val & MPI_DIAG_DRWE) == 0) { 3974 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3975 /* Write magic sequence to WriteSequence register 3975 /* Write magic sequence to WriteSequence register
3976 * Loop until in diagnostic mode 3976 * Loop until in diagnostic mode
3977 */ 3977 */
3978 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF); 3978 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3979 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE); 3979 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3980 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE); 3980 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3981 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE); 3981 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3982 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE); 3982 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3983 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE); 3983 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3984 3984
3985 /* wait 100 msec */ 3985 /* wait 100 msec */
3986 if (sleepFlag == CAN_SLEEP) { 3986 if (sleepFlag == CAN_SLEEP) {
3987 msleep (100); 3987 msleep (100);
3988 } else { 3988 } else {
3989 mdelay (100); 3989 mdelay (100);
3990 } 3990 }
3991 3991
3992 count++; 3992 count++;
3993 if (count > 20) { 3993 if (count > 20) {
3994 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n", 3994 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3995 ioc->name, diag0val); 3995 ioc->name, diag0val);
3996 return -2; 3996 return -2;
3997 3997
3998 } 3998 }
3999 3999
4000 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic); 4000 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4001 4001
4002 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wrote magic DiagWriteEn sequence (%x)\n", 4002 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
4003 ioc->name, diag0val)); 4003 ioc->name, diag0val));
4004 } 4004 }
4005 4005
4006 if (ioc->debug_level & MPT_DEBUG) { 4006 if (ioc->debug_level & MPT_DEBUG) {
4007 if (ioc->alt_ioc) 4007 if (ioc->alt_ioc)
4008 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic); 4008 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
4009 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG2: diag0=%08x, diag1=%08x\n", 4009 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG2: diag0=%08x, diag1=%08x\n",
4010 ioc->name, diag0val, diag1val)); 4010 ioc->name, diag0val, diag1val));
4011 } 4011 }
4012 /* 4012 /*
4013 * Disable the ARM (Bug fix) 4013 * Disable the ARM (Bug fix)
4014 * 4014 *
4015 */ 4015 */
4016 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM); 4016 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
4017 mdelay(1); 4017 mdelay(1);
4018 4018
4019 /* 4019 /*
4020 * Now hit the reset bit in the Diagnostic register 4020 * Now hit the reset bit in the Diagnostic register
4021 * (THE BIG HAMMER!) (Clears DRWE bit). 4021 * (THE BIG HAMMER!) (Clears DRWE bit).
4022 */ 4022 */
4023 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER); 4023 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
4024 hard_reset_done = 1; 4024 hard_reset_done = 1;
4025 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset performed\n", 4025 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset performed\n",
4026 ioc->name)); 4026 ioc->name));
4027 4027
4028 /* 4028 /*
4029 * Call each currently registered protocol IOC reset handler 4029 * Call each currently registered protocol IOC reset handler
4030 * with pre-reset indication. 4030 * with pre-reset indication.
4031 * NOTE: If we're doing _IOC_BRINGUP, there can be no 4031 * NOTE: If we're doing _IOC_BRINGUP, there can be no
4032 * MptResetHandlers[] registered yet. 4032 * MptResetHandlers[] registered yet.
4033 */ 4033 */
4034 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) { 4034 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
4035 if (MptResetHandlers[cb_idx]) { 4035 if (MptResetHandlers[cb_idx]) {
4036 mpt_signal_reset(cb_idx, 4036 mpt_signal_reset(cb_idx,
4037 ioc, MPT_IOC_PRE_RESET); 4037 ioc, MPT_IOC_PRE_RESET);
4038 if (ioc->alt_ioc) { 4038 if (ioc->alt_ioc) {
4039 mpt_signal_reset(cb_idx, 4039 mpt_signal_reset(cb_idx,
4040 ioc->alt_ioc, MPT_IOC_PRE_RESET); 4040 ioc->alt_ioc, MPT_IOC_PRE_RESET);
4041 } 4041 }
4042 } 4042 }
4043 } 4043 }
4044 4044
4045 if (ioc->cached_fw) 4045 if (ioc->cached_fw)
4046 cached_fw = (MpiFwHeader_t *)ioc->cached_fw; 4046 cached_fw = (MpiFwHeader_t *)ioc->cached_fw;
4047 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) 4047 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
4048 cached_fw = (MpiFwHeader_t *)ioc->alt_ioc->cached_fw; 4048 cached_fw = (MpiFwHeader_t *)ioc->alt_ioc->cached_fw;
4049 else 4049 else
4050 cached_fw = NULL; 4050 cached_fw = NULL;
4051 if (cached_fw) { 4051 if (cached_fw) {
4052 /* If the DownloadBoot operation fails, the 4052 /* If the DownloadBoot operation fails, the
4053 * IOC will be left unusable. This is a fatal error 4053 * IOC will be left unusable. This is a fatal error
4054 * case. _diag_reset will return < 0 4054 * case. _diag_reset will return < 0
4055 */ 4055 */
4056 for (count = 0; count < 30; count ++) { 4056 for (count = 0; count < 30; count ++) {
4057 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic); 4057 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4058 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) { 4058 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
4059 break; 4059 break;
4060 } 4060 }
4061 4061
4062 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "cached_fw: diag0val=%x count=%d\n", 4062 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "cached_fw: diag0val=%x count=%d\n",
4063 ioc->name, diag0val, count)); 4063 ioc->name, diag0val, count));
4064 /* wait 1 sec */ 4064 /* wait 1 sec */
4065 if (sleepFlag == CAN_SLEEP) { 4065 if (sleepFlag == CAN_SLEEP) {
4066 msleep (1000); 4066 msleep (1000);
4067 } else { 4067 } else {
4068 mdelay (1000); 4068 mdelay (1000);
4069 } 4069 }
4070 } 4070 }
4071 if ((count = mpt_downloadboot(ioc, cached_fw, sleepFlag)) < 0) { 4071 if ((count = mpt_downloadboot(ioc, cached_fw, sleepFlag)) < 0) {
4072 printk(MYIOC_s_WARN_FMT 4072 printk(MYIOC_s_WARN_FMT
4073 "firmware downloadboot failure (%d)!\n", ioc->name, count); 4073 "firmware downloadboot failure (%d)!\n", ioc->name, count);
4074 } 4074 }
4075 4075
4076 } else { 4076 } else {
4077 /* Wait for FW to reload and for board 4077 /* Wait for FW to reload and for board
4078 * to go to the READY state. 4078 * to go to the READY state.
4079 * Maximum wait is 60 seconds. 4079 * Maximum wait is 60 seconds.
4080 * If fail, no error will check again 4080 * If fail, no error will check again
4081 * with calling program. 4081 * with calling program.
4082 */ 4082 */
4083 for (count = 0; count < 60; count ++) { 4083 for (count = 0; count < 60; count ++) {
4084 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell); 4084 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
4085 doorbell &= MPI_IOC_STATE_MASK; 4085 doorbell &= MPI_IOC_STATE_MASK;
4086 4086
4087 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT 4087 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4088 "looking for READY STATE: doorbell=%x" 4088 "looking for READY STATE: doorbell=%x"
4089 " count=%d\n", ioc->name, doorbell, count)); 4089 " count=%d\n", ioc->name, doorbell, count));
4090 4090
4091 if (doorbell == MPI_IOC_STATE_READY) { 4091 if (doorbell == MPI_IOC_STATE_READY) {
4092 break; 4092 break;
4093 } 4093 }
4094 4094
4095 /* wait 1 sec */ 4095 /* wait 1 sec */
4096 if (sleepFlag == CAN_SLEEP) { 4096 if (sleepFlag == CAN_SLEEP) {
4097 msleep (1000); 4097 msleep (1000);
4098 } else { 4098 } else {
4099 mdelay (1000); 4099 mdelay (1000);
4100 } 4100 }
4101 } 4101 }
4102 4102
4103 if (doorbell != MPI_IOC_STATE_READY) 4103 if (doorbell != MPI_IOC_STATE_READY)
4104 printk(MYIOC_s_ERR_FMT "Failed to come READY " 4104 printk(MYIOC_s_ERR_FMT "Failed to come READY "
4105 "after reset! IocState=%x", ioc->name, 4105 "after reset! IocState=%x", ioc->name,
4106 doorbell); 4106 doorbell);
4107 } 4107 }
4108 } 4108 }
4109 4109
4110 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic); 4110 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4111 if (ioc->debug_level & MPT_DEBUG) { 4111 if (ioc->debug_level & MPT_DEBUG) {
4112 if (ioc->alt_ioc) 4112 if (ioc->alt_ioc)
4113 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic); 4113 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
4114 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG3: diag0=%08x, diag1=%08x\n", 4114 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG3: diag0=%08x, diag1=%08x\n",
4115 ioc->name, diag0val, diag1val)); 4115 ioc->name, diag0val, diag1val));
4116 } 4116 }
4117 4117
4118 /* Clear RESET_HISTORY bit! Place board in the 4118 /* Clear RESET_HISTORY bit! Place board in the
4119 * diagnostic mode to update the diag register. 4119 * diagnostic mode to update the diag register.
4120 */ 4120 */
4121 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic); 4121 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4122 count = 0; 4122 count = 0;
4123 while ((diag0val & MPI_DIAG_DRWE) == 0) { 4123 while ((diag0val & MPI_DIAG_DRWE) == 0) {
4124 /* Write magic sequence to WriteSequence register 4124 /* Write magic sequence to WriteSequence register
4125 * Loop until in diagnostic mode 4125 * Loop until in diagnostic mode
4126 */ 4126 */
4127 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF); 4127 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
4128 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE); 4128 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
4129 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE); 4129 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
4130 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE); 4130 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
4131 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE); 4131 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
4132 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE); 4132 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
4133 4133
4134 /* wait 100 msec */ 4134 /* wait 100 msec */
4135 if (sleepFlag == CAN_SLEEP) { 4135 if (sleepFlag == CAN_SLEEP) {
4136 msleep (100); 4136 msleep (100);
4137 } else { 4137 } else {
4138 mdelay (100); 4138 mdelay (100);
4139 } 4139 }
4140 4140
4141 count++; 4141 count++;
4142 if (count > 20) { 4142 if (count > 20) {
4143 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n", 4143 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
4144 ioc->name, diag0val); 4144 ioc->name, diag0val);
4145 break; 4145 break;
4146 } 4146 }
4147 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic); 4147 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4148 } 4148 }
4149 diag0val &= ~MPI_DIAG_RESET_HISTORY; 4149 diag0val &= ~MPI_DIAG_RESET_HISTORY;
4150 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val); 4150 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
4151 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic); 4151 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4152 if (diag0val & MPI_DIAG_RESET_HISTORY) { 4152 if (diag0val & MPI_DIAG_RESET_HISTORY) {
4153 printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n", 4153 printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
4154 ioc->name); 4154 ioc->name);
4155 } 4155 }
4156 4156
4157 /* Disable Diagnostic Mode 4157 /* Disable Diagnostic Mode
4158 */ 4158 */
4159 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF); 4159 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
4160 4160
4161 /* Check FW reload status flags. 4161 /* Check FW reload status flags.
4162 */ 4162 */
4163 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic); 4163 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4164 if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) { 4164 if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
4165 printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n", 4165 printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
4166 ioc->name, diag0val); 4166 ioc->name, diag0val);
4167 return -3; 4167 return -3;
4168 } 4168 }
4169 4169
4170 if (ioc->debug_level & MPT_DEBUG) { 4170 if (ioc->debug_level & MPT_DEBUG) {
4171 if (ioc->alt_ioc) 4171 if (ioc->alt_ioc)
4172 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic); 4172 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
4173 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG4: diag0=%08x, diag1=%08x\n", 4173 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG4: diag0=%08x, diag1=%08x\n",
4174 ioc->name, diag0val, diag1val)); 4174 ioc->name, diag0val, diag1val));
4175 } 4175 }
4176 4176
4177 /* 4177 /*
4178 * Reset flag that says we've enabled event notification 4178 * Reset flag that says we've enabled event notification
4179 */ 4179 */
4180 ioc->facts.EventState = 0; 4180 ioc->facts.EventState = 0;
4181 4181
4182 if (ioc->alt_ioc) 4182 if (ioc->alt_ioc)
4183 ioc->alt_ioc->facts.EventState = 0; 4183 ioc->alt_ioc->facts.EventState = 0;
4184 4184
4185 return hard_reset_done; 4185 return hard_reset_done;
4186 } 4186 }
4187 4187
4188 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 4188 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4189 /** 4189 /**
4190 * SendIocReset - Send IOCReset request to MPT adapter. 4190 * SendIocReset - Send IOCReset request to MPT adapter.
4191 * @ioc: Pointer to MPT_ADAPTER structure 4191 * @ioc: Pointer to MPT_ADAPTER structure
4192 * @reset_type: reset type, expected values are 4192 * @reset_type: reset type, expected values are
4193 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET 4193 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
4194 * @sleepFlag: Specifies whether the process can sleep 4194 * @sleepFlag: Specifies whether the process can sleep
4195 * 4195 *
4196 * Send IOCReset request to the MPT adapter. 4196 * Send IOCReset request to the MPT adapter.
4197 * 4197 *
4198 * Returns 0 for success, non-zero for failure. 4198 * Returns 0 for success, non-zero for failure.
4199 */ 4199 */
4200 static int 4200 static int
4201 SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag) 4201 SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
4202 { 4202 {
4203 int r; 4203 int r;
4204 u32 state; 4204 u32 state;
4205 int cntdn, count; 4205 int cntdn, count;
4206 4206
4207 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOC reset(0x%02x)!\n", 4207 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOC reset(0x%02x)!\n",
4208 ioc->name, reset_type)); 4208 ioc->name, reset_type));
4209 CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT); 4209 CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
4210 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) 4210 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4211 return r; 4211 return r;
4212 4212
4213 /* FW ACK'd request, wait for READY state 4213 /* FW ACK'd request, wait for READY state
4214 */ 4214 */
4215 count = 0; 4215 count = 0;
4216 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */ 4216 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */
4217 4217
4218 while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) { 4218 while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
4219 cntdn--; 4219 cntdn--;
4220 count++; 4220 count++;
4221 if (!cntdn) { 4221 if (!cntdn) {
4222 if (sleepFlag != CAN_SLEEP) 4222 if (sleepFlag != CAN_SLEEP)
4223 count *= 10; 4223 count *= 10;
4224 4224
4225 printk(MYIOC_s_ERR_FMT 4225 printk(MYIOC_s_ERR_FMT
4226 "Wait IOC_READY state (0x%x) timeout(%d)!\n", 4226 "Wait IOC_READY state (0x%x) timeout(%d)!\n",
4227 ioc->name, state, (int)((count+5)/HZ)); 4227 ioc->name, state, (int)((count+5)/HZ));
4228 return -ETIME; 4228 return -ETIME;
4229 } 4229 }
4230 4230
4231 if (sleepFlag == CAN_SLEEP) { 4231 if (sleepFlag == CAN_SLEEP) {
4232 msleep(1); 4232 msleep(1);
4233 } else { 4233 } else {
4234 mdelay (1); /* 1 msec delay */ 4234 mdelay (1); /* 1 msec delay */
4235 } 4235 }
4236 } 4236 }
4237 4237
4238 /* TODO! 4238 /* TODO!
4239 * Cleanup all event stuff for this IOC; re-issue EventNotification 4239 * Cleanup all event stuff for this IOC; re-issue EventNotification
4240 * request if needed. 4240 * request if needed.
4241 */ 4241 */
4242 if (ioc->facts.Function) 4242 if (ioc->facts.Function)
4243 ioc->facts.EventState = 0; 4243 ioc->facts.EventState = 0;
4244 4244
4245 return 0; 4245 return 0;
4246 } 4246 }
4247 4247
4248 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 4248 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4249 /** 4249 /**
4250 * initChainBuffers - Allocate memory for and initialize chain buffers 4250 * initChainBuffers - Allocate memory for and initialize chain buffers
4251 * @ioc: Pointer to MPT_ADAPTER structure 4251 * @ioc: Pointer to MPT_ADAPTER structure
4252 * 4252 *
4253 * Allocates memory for and initializes chain buffers, 4253 * Allocates memory for and initializes chain buffers,
4254 * chain buffer control arrays and spinlock. 4254 * chain buffer control arrays and spinlock.
4255 */ 4255 */
4256 static int 4256 static int
4257 initChainBuffers(MPT_ADAPTER *ioc) 4257 initChainBuffers(MPT_ADAPTER *ioc)
4258 { 4258 {
4259 u8 *mem; 4259 u8 *mem;
4260 int sz, ii, num_chain; 4260 int sz, ii, num_chain;
4261 int scale, num_sge, numSGE; 4261 int scale, num_sge, numSGE;
4262 4262
4263 /* ReqToChain size must equal the req_depth 4263 /* ReqToChain size must equal the req_depth
4264 * index = req_idx 4264 * index = req_idx
4265 */ 4265 */
4266 if (ioc->ReqToChain == NULL) { 4266 if (ioc->ReqToChain == NULL) {
4267 sz = ioc->req_depth * sizeof(int); 4267 sz = ioc->req_depth * sizeof(int);
4268 mem = kmalloc(sz, GFP_ATOMIC); 4268 mem = kmalloc(sz, GFP_ATOMIC);
4269 if (mem == NULL) 4269 if (mem == NULL)
4270 return -1; 4270 return -1;
4271 4271
4272 ioc->ReqToChain = (int *) mem; 4272 ioc->ReqToChain = (int *) mem;
4273 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReqToChain alloc @ %p, sz=%d bytes\n", 4273 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReqToChain alloc @ %p, sz=%d bytes\n",
4274 ioc->name, mem, sz)); 4274 ioc->name, mem, sz));
4275 mem = kmalloc(sz, GFP_ATOMIC); 4275 mem = kmalloc(sz, GFP_ATOMIC);
4276 if (mem == NULL) 4276 if (mem == NULL)
4277 return -1; 4277 return -1;
4278 4278
4279 ioc->RequestNB = (int *) mem; 4279 ioc->RequestNB = (int *) mem;
4280 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestNB alloc @ %p, sz=%d bytes\n", 4280 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestNB alloc @ %p, sz=%d bytes\n",
4281 ioc->name, mem, sz)); 4281 ioc->name, mem, sz));
4282 } 4282 }
4283 for (ii = 0; ii < ioc->req_depth; ii++) { 4283 for (ii = 0; ii < ioc->req_depth; ii++) {
4284 ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN; 4284 ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
4285 } 4285 }
4286 4286
4287 /* ChainToChain size must equal the total number 4287 /* ChainToChain size must equal the total number
4288 * of chain buffers to be allocated. 4288 * of chain buffers to be allocated.
4289 * index = chain_idx 4289 * index = chain_idx
4290 * 4290 *
4291 * Calculate the number of chain buffers needed(plus 1) per I/O 4291 * Calculate the number of chain buffers needed(plus 1) per I/O
4292 * then multiply the maximum number of simultaneous cmds 4292 * then multiply the maximum number of simultaneous cmds
4293 * 4293 *
4294 * num_sge = num sge in request frame + last chain buffer 4294 * num_sge = num sge in request frame + last chain buffer
4295 * scale = num sge per chain buffer if no chain element 4295 * scale = num sge per chain buffer if no chain element
4296 */ 4296 */
4297 scale = ioc->req_sz / ioc->SGE_size; 4297 scale = ioc->req_sz / ioc->SGE_size;
4298 if (ioc->sg_addr_size == sizeof(u64)) 4298 if (ioc->sg_addr_size == sizeof(u64))
4299 num_sge = scale + (ioc->req_sz - 60) / ioc->SGE_size; 4299 num_sge = scale + (ioc->req_sz - 60) / ioc->SGE_size;
4300 else 4300 else
4301 num_sge = 1 + scale + (ioc->req_sz - 64) / ioc->SGE_size; 4301 num_sge = 1 + scale + (ioc->req_sz - 64) / ioc->SGE_size;
4302 4302
4303 if (ioc->sg_addr_size == sizeof(u64)) { 4303 if (ioc->sg_addr_size == sizeof(u64)) {
4304 numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale + 4304 numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
4305 (ioc->req_sz - 60) / ioc->SGE_size; 4305 (ioc->req_sz - 60) / ioc->SGE_size;
4306 } else { 4306 } else {
4307 numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) + 4307 numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) +
4308 scale + (ioc->req_sz - 64) / ioc->SGE_size; 4308 scale + (ioc->req_sz - 64) / ioc->SGE_size;
4309 } 4309 }
4310 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "num_sge=%d numSGE=%d\n", 4310 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "num_sge=%d numSGE=%d\n",
4311 ioc->name, num_sge, numSGE)); 4311 ioc->name, num_sge, numSGE));
4312 4312
4313 if (ioc->bus_type == FC) { 4313 if (ioc->bus_type == FC) {
4314 if (numSGE > MPT_SCSI_FC_SG_DEPTH) 4314 if (numSGE > MPT_SCSI_FC_SG_DEPTH)
4315 numSGE = MPT_SCSI_FC_SG_DEPTH; 4315 numSGE = MPT_SCSI_FC_SG_DEPTH;
4316 } else { 4316 } else {
4317 if (numSGE > MPT_SCSI_SG_DEPTH) 4317 if (numSGE > MPT_SCSI_SG_DEPTH)
4318 numSGE = MPT_SCSI_SG_DEPTH; 4318 numSGE = MPT_SCSI_SG_DEPTH;
4319 } 4319 }
4320 4320
4321 num_chain = 1; 4321 num_chain = 1;
4322 while (numSGE - num_sge > 0) { 4322 while (numSGE - num_sge > 0) {
4323 num_chain++; 4323 num_chain++;
4324 num_sge += (scale - 1); 4324 num_sge += (scale - 1);
4325 } 4325 }
4326 num_chain++; 4326 num_chain++;
4327 4327
4328 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Now numSGE=%d num_sge=%d num_chain=%d\n", 4328 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Now numSGE=%d num_sge=%d num_chain=%d\n",
4329 ioc->name, numSGE, num_sge, num_chain)); 4329 ioc->name, numSGE, num_sge, num_chain));
4330 4330
4331 if (ioc->bus_type == SPI) 4331 if (ioc->bus_type == SPI)
4332 num_chain *= MPT_SCSI_CAN_QUEUE; 4332 num_chain *= MPT_SCSI_CAN_QUEUE;
4333 else 4333 else
4334 num_chain *= MPT_FC_CAN_QUEUE; 4334 num_chain *= MPT_FC_CAN_QUEUE;
4335 4335
4336 ioc->num_chain = num_chain; 4336 ioc->num_chain = num_chain;
4337 4337
4338 sz = num_chain * sizeof(int); 4338 sz = num_chain * sizeof(int);
4339 if (ioc->ChainToChain == NULL) { 4339 if (ioc->ChainToChain == NULL) {
4340 mem = kmalloc(sz, GFP_ATOMIC); 4340 mem = kmalloc(sz, GFP_ATOMIC);
4341 if (mem == NULL) 4341 if (mem == NULL)
4342 return -1; 4342 return -1;
4343 4343
4344 ioc->ChainToChain = (int *) mem; 4344 ioc->ChainToChain = (int *) mem;
4345 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainToChain alloc @ %p, sz=%d bytes\n", 4345 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainToChain alloc @ %p, sz=%d bytes\n",
4346 ioc->name, mem, sz)); 4346 ioc->name, mem, sz));
4347 } else { 4347 } else {
4348 mem = (u8 *) ioc->ChainToChain; 4348 mem = (u8 *) ioc->ChainToChain;
4349 } 4349 }
4350 memset(mem, 0xFF, sz); 4350 memset(mem, 0xFF, sz);
4351 return num_chain; 4351 return num_chain;
4352 } 4352 }
4353 4353
4354 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 4354 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4355 /** 4355 /**
4356 * PrimeIocFifos - Initialize IOC request and reply FIFOs. 4356 * PrimeIocFifos - Initialize IOC request and reply FIFOs.
4357 * @ioc: Pointer to MPT_ADAPTER structure 4357 * @ioc: Pointer to MPT_ADAPTER structure
4358 * 4358 *
4359 * This routine allocates memory for the MPT reply and request frame 4359 * This routine allocates memory for the MPT reply and request frame
4360 * pools (if necessary), and primes the IOC reply FIFO with 4360 * pools (if necessary), and primes the IOC reply FIFO with
4361 * reply frames. 4361 * reply frames.
4362 * 4362 *
4363 * Returns 0 for success, non-zero for failure. 4363 * Returns 0 for success, non-zero for failure.
4364 */ 4364 */
4365 static int 4365 static int
4366 PrimeIocFifos(MPT_ADAPTER *ioc) 4366 PrimeIocFifos(MPT_ADAPTER *ioc)
4367 { 4367 {
4368 MPT_FRAME_HDR *mf; 4368 MPT_FRAME_HDR *mf;
4369 unsigned long flags; 4369 unsigned long flags;
4370 dma_addr_t alloc_dma; 4370 dma_addr_t alloc_dma;
4371 u8 *mem; 4371 u8 *mem;
4372 int i, reply_sz, sz, total_size, num_chain; 4372 int i, reply_sz, sz, total_size, num_chain;
4373 u64 dma_mask; 4373 u64 dma_mask;
4374 4374
4375 dma_mask = 0; 4375 dma_mask = 0;
4376 4376
4377 /* Prime reply FIFO... */ 4377 /* Prime reply FIFO... */
4378 4378
4379 if (ioc->reply_frames == NULL) { 4379 if (ioc->reply_frames == NULL) {
4380 if ( (num_chain = initChainBuffers(ioc)) < 0) 4380 if ( (num_chain = initChainBuffers(ioc)) < 0)
4381 return -1; 4381 return -1;
4382 /* 4382 /*
4383 * 1078 errata workaround for the 36GB limitation 4383 * 1078 errata workaround for the 36GB limitation
4384 */ 4384 */
4385 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078 && 4385 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078 &&
4386 ioc->dma_mask > DMA_BIT_MASK(35)) { 4386 ioc->dma_mask > DMA_BIT_MASK(35)) {
4387 if (!pci_set_dma_mask(ioc->pcidev, DMA_BIT_MASK(32)) 4387 if (!pci_set_dma_mask(ioc->pcidev, DMA_BIT_MASK(32))
4388 && !pci_set_consistent_dma_mask(ioc->pcidev, 4388 && !pci_set_consistent_dma_mask(ioc->pcidev,
4389 DMA_BIT_MASK(32))) { 4389 DMA_BIT_MASK(32))) {
4390 dma_mask = DMA_BIT_MASK(35); 4390 dma_mask = DMA_BIT_MASK(35);
4391 d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT 4391 d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4392 "setting 35 bit addressing for " 4392 "setting 35 bit addressing for "
4393 "Request/Reply/Chain and Sense Buffers\n", 4393 "Request/Reply/Chain and Sense Buffers\n",
4394 ioc->name)); 4394 ioc->name));
4395 } else { 4395 } else {
4396 /*Reseting DMA mask to 64 bit*/ 4396 /*Reseting DMA mask to 64 bit*/
4397 pci_set_dma_mask(ioc->pcidev, 4397 pci_set_dma_mask(ioc->pcidev,
4398 DMA_BIT_MASK(64)); 4398 DMA_BIT_MASK(64));
4399 pci_set_consistent_dma_mask(ioc->pcidev, 4399 pci_set_consistent_dma_mask(ioc->pcidev,
4400 DMA_BIT_MASK(64)); 4400 DMA_BIT_MASK(64));
4401 4401
4402 printk(MYIOC_s_ERR_FMT 4402 printk(MYIOC_s_ERR_FMT
4403 "failed setting 35 bit addressing for " 4403 "failed setting 35 bit addressing for "
4404 "Request/Reply/Chain and Sense Buffers\n", 4404 "Request/Reply/Chain and Sense Buffers\n",
4405 ioc->name); 4405 ioc->name);
4406 return -1; 4406 return -1;
4407 } 4407 }
4408 } 4408 }
4409 4409
4410 total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth); 4410 total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth);
4411 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d bytes, ReplyDepth=%d\n", 4411 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
4412 ioc->name, ioc->reply_sz, ioc->reply_depth)); 4412 ioc->name, ioc->reply_sz, ioc->reply_depth));
4413 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d[%x] bytes\n", 4413 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d[%x] bytes\n",
4414 ioc->name, reply_sz, reply_sz)); 4414 ioc->name, reply_sz, reply_sz));
4415 4415
4416 sz = (ioc->req_sz * ioc->req_depth); 4416 sz = (ioc->req_sz * ioc->req_depth);
4417 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d bytes, RequestDepth=%d\n", 4417 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d bytes, RequestDepth=%d\n",
4418 ioc->name, ioc->req_sz, ioc->req_depth)); 4418 ioc->name, ioc->req_sz, ioc->req_depth));
4419 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d[%x] bytes\n", 4419 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d[%x] bytes\n",
4420 ioc->name, sz, sz)); 4420 ioc->name, sz, sz));
4421 total_size += sz; 4421 total_size += sz;
4422 4422
4423 sz = num_chain * ioc->req_sz; /* chain buffer pool size */ 4423 sz = num_chain * ioc->req_sz; /* chain buffer pool size */
4424 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d bytes, ChainDepth=%d\n", 4424 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d bytes, ChainDepth=%d\n",
4425 ioc->name, ioc->req_sz, num_chain)); 4425 ioc->name, ioc->req_sz, num_chain));
4426 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d[%x] bytes num_chain=%d\n", 4426 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
4427 ioc->name, sz, sz, num_chain)); 4427 ioc->name, sz, sz, num_chain));
4428 4428
4429 total_size += sz; 4429 total_size += sz;
4430 mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma); 4430 mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma);
4431 if (mem == NULL) { 4431 if (mem == NULL) {
4432 printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n", 4432 printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n",
4433 ioc->name); 4433 ioc->name);
4434 goto out_fail; 4434 goto out_fail;
4435 } 4435 }
4436 4436
4437 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Total alloc @ %p[%p], sz=%d[%x] bytes\n", 4437 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Total alloc @ %p[%p], sz=%d[%x] bytes\n",
4438 ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size)); 4438 ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size));
4439 4439
4440 memset(mem, 0, total_size); 4440 memset(mem, 0, total_size);
4441 ioc->alloc_total += total_size; 4441 ioc->alloc_total += total_size;
4442 ioc->alloc = mem; 4442 ioc->alloc = mem;
4443 ioc->alloc_dma = alloc_dma; 4443 ioc->alloc_dma = alloc_dma;
4444 ioc->alloc_sz = total_size; 4444 ioc->alloc_sz = total_size;
4445 ioc->reply_frames = (MPT_FRAME_HDR *) mem; 4445 ioc->reply_frames = (MPT_FRAME_HDR *) mem;
4446 ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF); 4446 ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
4447 4447
4448 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n", 4448 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4449 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma)); 4449 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4450 4450
4451 alloc_dma += reply_sz; 4451 alloc_dma += reply_sz;
4452 mem += reply_sz; 4452 mem += reply_sz;
4453 4453
4454 /* Request FIFO - WE manage this! */ 4454 /* Request FIFO - WE manage this! */
4455 4455
4456 ioc->req_frames = (MPT_FRAME_HDR *) mem; 4456 ioc->req_frames = (MPT_FRAME_HDR *) mem;
4457 ioc->req_frames_dma = alloc_dma; 4457 ioc->req_frames_dma = alloc_dma;
4458 4458
4459 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffers @ %p[%p]\n", 4459 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffers @ %p[%p]\n",
4460 ioc->name, mem, (void *)(ulong)alloc_dma)); 4460 ioc->name, mem, (void *)(ulong)alloc_dma));
4461 4461
4462 ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF); 4462 ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
4463 4463
4464 #if defined(CONFIG_MTRR) && 0 4464 #if defined(CONFIG_MTRR) && 0
4465 /* 4465 /*
4466 * Enable Write Combining MTRR for IOC's memory region. 4466 * Enable Write Combining MTRR for IOC's memory region.
4467 * (at least as much as we can; "size and base must be 4467 * (at least as much as we can; "size and base must be
4468 * multiples of 4 kiB" 4468 * multiples of 4 kiB"
4469 */ 4469 */
4470 ioc->mtrr_reg = mtrr_add(ioc->req_frames_dma, 4470 ioc->mtrr_reg = mtrr_add(ioc->req_frames_dma,
4471 sz, 4471 sz,
4472 MTRR_TYPE_WRCOMB, 1); 4472 MTRR_TYPE_WRCOMB, 1);
4473 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MTRR region registered (base:size=%08x:%x)\n", 4473 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MTRR region registered (base:size=%08x:%x)\n",
4474 ioc->name, ioc->req_frames_dma, sz)); 4474 ioc->name, ioc->req_frames_dma, sz));
4475 #endif 4475 #endif
4476 4476
4477 for (i = 0; i < ioc->req_depth; i++) { 4477 for (i = 0; i < ioc->req_depth; i++) {
4478 alloc_dma += ioc->req_sz; 4478 alloc_dma += ioc->req_sz;
4479 mem += ioc->req_sz; 4479 mem += ioc->req_sz;
4480 } 4480 }
4481 4481
4482 ioc->ChainBuffer = mem; 4482 ioc->ChainBuffer = mem;
4483 ioc->ChainBufferDMA = alloc_dma; 4483 ioc->ChainBufferDMA = alloc_dma;
4484 4484
4485 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffers @ %p(%p)\n", 4485 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffers @ %p(%p)\n",
4486 ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA)); 4486 ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
4487 4487
4488 /* Initialize the free chain Q. 4488 /* Initialize the free chain Q.
4489 */ 4489 */
4490 4490
4491 INIT_LIST_HEAD(&ioc->FreeChainQ); 4491 INIT_LIST_HEAD(&ioc->FreeChainQ);
4492 4492
4493 /* Post the chain buffers to the FreeChainQ. 4493 /* Post the chain buffers to the FreeChainQ.
4494 */ 4494 */
4495 mem = (u8 *)ioc->ChainBuffer; 4495 mem = (u8 *)ioc->ChainBuffer;
4496 for (i=0; i < num_chain; i++) { 4496 for (i=0; i < num_chain; i++) {
4497 mf = (MPT_FRAME_HDR *) mem; 4497 mf = (MPT_FRAME_HDR *) mem;
4498 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeChainQ); 4498 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeChainQ);
4499 mem += ioc->req_sz; 4499 mem += ioc->req_sz;
4500 } 4500 }
4501 4501
4502 /* Initialize Request frames linked list 4502 /* Initialize Request frames linked list
4503 */ 4503 */
4504 alloc_dma = ioc->req_frames_dma; 4504 alloc_dma = ioc->req_frames_dma;
4505 mem = (u8 *) ioc->req_frames; 4505 mem = (u8 *) ioc->req_frames;
4506 4506
4507 spin_lock_irqsave(&ioc->FreeQlock, flags); 4507 spin_lock_irqsave(&ioc->FreeQlock, flags);
4508 INIT_LIST_HEAD(&ioc->FreeQ); 4508 INIT_LIST_HEAD(&ioc->FreeQ);
4509 for (i = 0; i < ioc->req_depth; i++) { 4509 for (i = 0; i < ioc->req_depth; i++) {
4510 mf = (MPT_FRAME_HDR *) mem; 4510 mf = (MPT_FRAME_HDR *) mem;
4511 4511
4512 /* Queue REQUESTs *internally*! */ 4512 /* Queue REQUESTs *internally*! */
4513 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ); 4513 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
4514 4514
4515 mem += ioc->req_sz; 4515 mem += ioc->req_sz;
4516 } 4516 }
4517 spin_unlock_irqrestore(&ioc->FreeQlock, flags); 4517 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4518 4518
4519 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC); 4519 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4520 ioc->sense_buf_pool = 4520 ioc->sense_buf_pool =
4521 pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma); 4521 pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
4522 if (ioc->sense_buf_pool == NULL) { 4522 if (ioc->sense_buf_pool == NULL) {
4523 printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n", 4523 printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n",
4524 ioc->name); 4524 ioc->name);
4525 goto out_fail; 4525 goto out_fail;
4526 } 4526 }
4527 4527
4528 ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF); 4528 ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
4529 ioc->alloc_total += sz; 4529 ioc->alloc_total += sz;
4530 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SenseBuffers @ %p[%p]\n", 4530 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SenseBuffers @ %p[%p]\n",
4531 ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma)); 4531 ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma));
4532 4532
4533 } 4533 }
4534 4534
4535 /* Post Reply frames to FIFO 4535 /* Post Reply frames to FIFO
4536 */ 4536 */
4537 alloc_dma = ioc->alloc_dma; 4537 alloc_dma = ioc->alloc_dma;
4538 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n", 4538 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4539 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma)); 4539 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4540 4540
4541 for (i = 0; i < ioc->reply_depth; i++) { 4541 for (i = 0; i < ioc->reply_depth; i++) {
4542 /* Write each address to the IOC! */ 4542 /* Write each address to the IOC! */
4543 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma); 4543 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma);
4544 alloc_dma += ioc->reply_sz; 4544 alloc_dma += ioc->reply_sz;
4545 } 4545 }
4546 4546
4547 if (dma_mask == DMA_BIT_MASK(35) && !pci_set_dma_mask(ioc->pcidev, 4547 if (dma_mask == DMA_BIT_MASK(35) && !pci_set_dma_mask(ioc->pcidev,
4548 ioc->dma_mask) && !pci_set_consistent_dma_mask(ioc->pcidev, 4548 ioc->dma_mask) && !pci_set_consistent_dma_mask(ioc->pcidev,
4549 ioc->dma_mask)) 4549 ioc->dma_mask))
4550 d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT 4550 d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4551 "restoring 64 bit addressing\n", ioc->name)); 4551 "restoring 64 bit addressing\n", ioc->name));
4552 4552
4553 return 0; 4553 return 0;
4554 4554
4555 out_fail: 4555 out_fail:
4556 4556
4557 if (ioc->alloc != NULL) { 4557 if (ioc->alloc != NULL) {
4558 sz = ioc->alloc_sz; 4558 sz = ioc->alloc_sz;
4559 pci_free_consistent(ioc->pcidev, 4559 pci_free_consistent(ioc->pcidev,
4560 sz, 4560 sz,
4561 ioc->alloc, ioc->alloc_dma); 4561 ioc->alloc, ioc->alloc_dma);
4562 ioc->reply_frames = NULL; 4562 ioc->reply_frames = NULL;
4563 ioc->req_frames = NULL; 4563 ioc->req_frames = NULL;
4564 ioc->alloc_total -= sz; 4564 ioc->alloc_total -= sz;
4565 } 4565 }
4566 if (ioc->sense_buf_pool != NULL) { 4566 if (ioc->sense_buf_pool != NULL) {
4567 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC); 4567 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4568 pci_free_consistent(ioc->pcidev, 4568 pci_free_consistent(ioc->pcidev,
4569 sz, 4569 sz,
4570 ioc->sense_buf_pool, ioc->sense_buf_pool_dma); 4570 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
4571 ioc->sense_buf_pool = NULL; 4571 ioc->sense_buf_pool = NULL;
4572 } 4572 }
4573 4573
4574 if (dma_mask == DMA_BIT_MASK(35) && !pci_set_dma_mask(ioc->pcidev, 4574 if (dma_mask == DMA_BIT_MASK(35) && !pci_set_dma_mask(ioc->pcidev,
4575 DMA_BIT_MASK(64)) && !pci_set_consistent_dma_mask(ioc->pcidev, 4575 DMA_BIT_MASK(64)) && !pci_set_consistent_dma_mask(ioc->pcidev,
4576 DMA_BIT_MASK(64))) 4576 DMA_BIT_MASK(64)))
4577 d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT 4577 d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4578 "restoring 64 bit addressing\n", ioc->name)); 4578 "restoring 64 bit addressing\n", ioc->name));
4579 4579
4580 return -1; 4580 return -1;
4581 } 4581 }
4582 4582
4583 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 4583 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4584 /** 4584 /**
4585 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply 4585 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply
4586 * from IOC via doorbell handshake method. 4586 * from IOC via doorbell handshake method.
4587 * @ioc: Pointer to MPT_ADAPTER structure 4587 * @ioc: Pointer to MPT_ADAPTER structure
4588 * @reqBytes: Size of the request in bytes 4588 * @reqBytes: Size of the request in bytes
4589 * @req: Pointer to MPT request frame 4589 * @req: Pointer to MPT request frame
4590 * @replyBytes: Expected size of the reply in bytes 4590 * @replyBytes: Expected size of the reply in bytes
4591 * @u16reply: Pointer to area where reply should be written 4591 * @u16reply: Pointer to area where reply should be written
4592 * @maxwait: Max wait time for a reply (in seconds) 4592 * @maxwait: Max wait time for a reply (in seconds)
4593 * @sleepFlag: Specifies whether the process can sleep 4593 * @sleepFlag: Specifies whether the process can sleep
4594 * 4594 *
4595 * NOTES: It is the callers responsibility to byte-swap fields in the 4595 * NOTES: It is the callers responsibility to byte-swap fields in the
4596 * request which are greater than 1 byte in size. It is also the 4596 * request which are greater than 1 byte in size. It is also the
4597 * callers responsibility to byte-swap response fields which are 4597 * callers responsibility to byte-swap response fields which are
4598 * greater than 1 byte in size. 4598 * greater than 1 byte in size.
4599 * 4599 *
4600 * Returns 0 for success, non-zero for failure. 4600 * Returns 0 for success, non-zero for failure.
4601 */ 4601 */
4602 static int 4602 static int
4603 mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req, 4603 mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
4604 int replyBytes, u16 *u16reply, int maxwait, int sleepFlag) 4604 int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
4605 { 4605 {
4606 MPIDefaultReply_t *mptReply; 4606 MPIDefaultReply_t *mptReply;
4607 int failcnt = 0; 4607 int failcnt = 0;
4608 int t; 4608 int t;
4609 4609
4610 /* 4610 /*
4611 * Get ready to cache a handshake reply 4611 * Get ready to cache a handshake reply
4612 */ 4612 */
4613 ioc->hs_reply_idx = 0; 4613 ioc->hs_reply_idx = 0;
4614 mptReply = (MPIDefaultReply_t *) ioc->hs_reply; 4614 mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4615 mptReply->MsgLength = 0; 4615 mptReply->MsgLength = 0;
4616 4616
4617 /* 4617 /*
4618 * Make sure there are no doorbells (WRITE 0 to IntStatus reg), 4618 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
4619 * then tell IOC that we want to handshake a request of N words. 4619 * then tell IOC that we want to handshake a request of N words.
4620 * (WRITE u32val to Doorbell reg). 4620 * (WRITE u32val to Doorbell reg).
4621 */ 4621 */
4622 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); 4622 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4623 CHIPREG_WRITE32(&ioc->chip->Doorbell, 4623 CHIPREG_WRITE32(&ioc->chip->Doorbell,
4624 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) | 4624 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
4625 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT))); 4625 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
4626 4626
4627 /* 4627 /*
4628 * Wait for IOC's doorbell handshake int 4628 * Wait for IOC's doorbell handshake int
4629 */ 4629 */
4630 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) 4630 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4631 failcnt++; 4631 failcnt++;
4632 4632
4633 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request start reqBytes=%d, WaitCnt=%d%s\n", 4633 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
4634 ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : "")); 4634 ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4635 4635
4636 /* Read doorbell and check for active bit */ 4636 /* Read doorbell and check for active bit */
4637 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE)) 4637 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
4638 return -1; 4638 return -1;
4639 4639
4640 /* 4640 /*
4641 * Clear doorbell int (WRITE 0 to IntStatus reg), 4641 * Clear doorbell int (WRITE 0 to IntStatus reg),
4642 * then wait for IOC to ACKnowledge that it's ready for 4642 * then wait for IOC to ACKnowledge that it's ready for
4643 * our handshake request. 4643 * our handshake request.
4644 */ 4644 */
4645 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); 4645 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4646 if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) 4646 if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4647 failcnt++; 4647 failcnt++;
4648 4648
4649 if (!failcnt) { 4649 if (!failcnt) {
4650 int ii; 4650 int ii;
4651 u8 *req_as_bytes = (u8 *) req; 4651 u8 *req_as_bytes = (u8 *) req;
4652 4652
4653 /* 4653 /*
4654 * Stuff request words via doorbell handshake, 4654 * Stuff request words via doorbell handshake,
4655 * with ACK from IOC for each. 4655 * with ACK from IOC for each.
4656 */ 4656 */
4657 for (ii = 0; !failcnt && ii < reqBytes/4; ii++) { 4657 for (ii = 0; !failcnt && ii < reqBytes/4; ii++) {
4658 u32 word = ((req_as_bytes[(ii*4) + 0] << 0) | 4658 u32 word = ((req_as_bytes[(ii*4) + 0] << 0) |
4659 (req_as_bytes[(ii*4) + 1] << 8) | 4659 (req_as_bytes[(ii*4) + 1] << 8) |
4660 (req_as_bytes[(ii*4) + 2] << 16) | 4660 (req_as_bytes[(ii*4) + 2] << 16) |
4661 (req_as_bytes[(ii*4) + 3] << 24)); 4661 (req_as_bytes[(ii*4) + 3] << 24));
4662 4662
4663 CHIPREG_WRITE32(&ioc->chip->Doorbell, word); 4663 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
4664 if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) 4664 if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4665 failcnt++; 4665 failcnt++;
4666 } 4666 }
4667 4667
4668 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handshake request frame (@%p) header\n", ioc->name, req)); 4668 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handshake request frame (@%p) header\n", ioc->name, req));
4669 DBG_DUMP_REQUEST_FRAME_HDR(ioc, (u32 *)req); 4669 DBG_DUMP_REQUEST_FRAME_HDR(ioc, (u32 *)req);
4670 4670
4671 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request post done, WaitCnt=%d%s\n", 4671 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request post done, WaitCnt=%d%s\n",
4672 ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : "")); 4672 ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : ""));
4673 4673
4674 /* 4674 /*
4675 * Wait for completion of doorbell handshake reply from the IOC 4675 * Wait for completion of doorbell handshake reply from the IOC
4676 */ 4676 */
4677 if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0) 4677 if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
4678 failcnt++; 4678 failcnt++;
4679 4679
4680 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake reply count=%d%s\n", 4680 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake reply count=%d%s\n",
4681 ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : "")); 4681 ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : ""));
4682 4682
4683 /* 4683 /*
4684 * Copy out the cached reply... 4684 * Copy out the cached reply...
4685 */ 4685 */
4686 for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++) 4686 for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++)
4687 u16reply[ii] = ioc->hs_reply[ii]; 4687 u16reply[ii] = ioc->hs_reply[ii];
4688 } else { 4688 } else {
4689 return -99; 4689 return -99;
4690 } 4690 }
4691 4691
4692 return -failcnt; 4692 return -failcnt;
4693 } 4693 }
4694 4694
4695 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 4695 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4696 /** 4696 /**
4697 * WaitForDoorbellAck - Wait for IOC doorbell handshake acknowledge 4697 * WaitForDoorbellAck - Wait for IOC doorbell handshake acknowledge
4698 * @ioc: Pointer to MPT_ADAPTER structure 4698 * @ioc: Pointer to MPT_ADAPTER structure
4699 * @howlong: How long to wait (in seconds) 4699 * @howlong: How long to wait (in seconds)
4700 * @sleepFlag: Specifies whether the process can sleep 4700 * @sleepFlag: Specifies whether the process can sleep
4701 * 4701 *
4702 * This routine waits (up to ~2 seconds max) for IOC doorbell 4702 * This routine waits (up to ~2 seconds max) for IOC doorbell
4703 * handshake ACKnowledge, indicated by the IOP_DOORBELL_STATUS 4703 * handshake ACKnowledge, indicated by the IOP_DOORBELL_STATUS
4704 * bit in its IntStatus register being clear. 4704 * bit in its IntStatus register being clear.
4705 * 4705 *
4706 * Returns a negative value on failure, else wait loop count. 4706 * Returns a negative value on failure, else wait loop count.
4707 */ 4707 */
4708 static int 4708 static int
4709 WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag) 4709 WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4710 { 4710 {
4711 int cntdn; 4711 int cntdn;
4712 int count = 0; 4712 int count = 0;
4713 u32 intstat=0; 4713 u32 intstat=0;
4714 4714
4715 cntdn = 1000 * howlong; 4715 cntdn = 1000 * howlong;
4716 4716
4717 if (sleepFlag == CAN_SLEEP) { 4717 if (sleepFlag == CAN_SLEEP) {
4718 while (--cntdn) { 4718 while (--cntdn) {
4719 msleep (1); 4719 msleep (1);
4720 intstat = CHIPREG_READ32(&ioc->chip->IntStatus); 4720 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4721 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS)) 4721 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4722 break; 4722 break;
4723 count++; 4723 count++;
4724 } 4724 }
4725 } else { 4725 } else {
4726 while (--cntdn) { 4726 while (--cntdn) {
4727 udelay (1000); 4727 udelay (1000);
4728 intstat = CHIPREG_READ32(&ioc->chip->IntStatus); 4728 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4729 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS)) 4729 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4730 break; 4730 break;
4731 count++; 4731 count++;
4732 } 4732 }
4733 } 4733 }
4734 4734
4735 if (cntdn) { 4735 if (cntdn) {
4736 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell ACK (count=%d)\n", 4736 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell ACK (count=%d)\n",
4737 ioc->name, count)); 4737 ioc->name, count));
4738 return count; 4738 return count;
4739 } 4739 }
4740 4740
4741 printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout (count=%d), IntStatus=%x!\n", 4741 printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
4742 ioc->name, count, intstat); 4742 ioc->name, count, intstat);
4743 return -1; 4743 return -1;
4744 } 4744 }
4745 4745
4746 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 4746 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4747 /** 4747 /**
4748 * WaitForDoorbellInt - Wait for IOC to set its doorbell interrupt bit 4748 * WaitForDoorbellInt - Wait for IOC to set its doorbell interrupt bit
4749 * @ioc: Pointer to MPT_ADAPTER structure 4749 * @ioc: Pointer to MPT_ADAPTER structure
4750 * @howlong: How long to wait (in seconds) 4750 * @howlong: How long to wait (in seconds)
4751 * @sleepFlag: Specifies whether the process can sleep 4751 * @sleepFlag: Specifies whether the process can sleep
4752 * 4752 *
4753 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt 4753 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt
4754 * (MPI_HIS_DOORBELL_INTERRUPT) to be set in the IntStatus register. 4754 * (MPI_HIS_DOORBELL_INTERRUPT) to be set in the IntStatus register.
4755 * 4755 *
4756 * Returns a negative value on failure, else wait loop count. 4756 * Returns a negative value on failure, else wait loop count.
4757 */ 4757 */
4758 static int 4758 static int
4759 WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag) 4759 WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4760 { 4760 {
4761 int cntdn; 4761 int cntdn;
4762 int count = 0; 4762 int count = 0;
4763 u32 intstat=0; 4763 u32 intstat=0;
4764 4764
4765 cntdn = 1000 * howlong; 4765 cntdn = 1000 * howlong;
4766 if (sleepFlag == CAN_SLEEP) { 4766 if (sleepFlag == CAN_SLEEP) {
4767 while (--cntdn) { 4767 while (--cntdn) {
4768 intstat = CHIPREG_READ32(&ioc->chip->IntStatus); 4768 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4769 if (intstat & MPI_HIS_DOORBELL_INTERRUPT) 4769 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4770 break; 4770 break;
4771 msleep(1); 4771 msleep(1);
4772 count++; 4772 count++;
4773 } 4773 }
4774 } else { 4774 } else {
4775 while (--cntdn) { 4775 while (--cntdn) {
4776 intstat = CHIPREG_READ32(&ioc->chip->IntStatus); 4776 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4777 if (intstat & MPI_HIS_DOORBELL_INTERRUPT) 4777 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4778 break; 4778 break;
4779 udelay (1000); 4779 udelay (1000);
4780 count++; 4780 count++;
4781 } 4781 }
4782 } 4782 }
4783 4783
4784 if (cntdn) { 4784 if (cntdn) {
4785 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell INT (cnt=%d) howlong=%d\n", 4785 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell INT (cnt=%d) howlong=%d\n",
4786 ioc->name, count, howlong)); 4786 ioc->name, count, howlong));
4787 return count; 4787 return count;
4788 } 4788 }
4789 4789
4790 printk(MYIOC_s_ERR_FMT "Doorbell INT timeout (count=%d), IntStatus=%x!\n", 4790 printk(MYIOC_s_ERR_FMT "Doorbell INT timeout (count=%d), IntStatus=%x!\n",
4791 ioc->name, count, intstat); 4791 ioc->name, count, intstat);
4792 return -1; 4792 return -1;
4793 } 4793 }
4794 4794
4795 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 4795 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4796 /** 4796 /**
4797 * WaitForDoorbellReply - Wait for and capture an IOC handshake reply. 4797 * WaitForDoorbellReply - Wait for and capture an IOC handshake reply.
4798 * @ioc: Pointer to MPT_ADAPTER structure 4798 * @ioc: Pointer to MPT_ADAPTER structure
4799 * @howlong: How long to wait (in seconds) 4799 * @howlong: How long to wait (in seconds)
4800 * @sleepFlag: Specifies whether the process can sleep 4800 * @sleepFlag: Specifies whether the process can sleep
4801 * 4801 *
4802 * This routine polls the IOC for a handshake reply, 16 bits at a time. 4802 * This routine polls the IOC for a handshake reply, 16 bits at a time.
4803 * Reply is cached to IOC private area large enough to hold a maximum 4803 * Reply is cached to IOC private area large enough to hold a maximum
4804 * of 128 bytes of reply data. 4804 * of 128 bytes of reply data.
4805 * 4805 *
4806 * Returns a negative value on failure, else size of reply in WORDS. 4806 * Returns a negative value on failure, else size of reply in WORDS.
4807 */ 4807 */
4808 static int 4808 static int
4809 WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag) 4809 WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4810 { 4810 {
4811 int u16cnt = 0; 4811 int u16cnt = 0;
4812 int failcnt = 0; 4812 int failcnt = 0;
4813 int t; 4813 int t;
4814 u16 *hs_reply = ioc->hs_reply; 4814 u16 *hs_reply = ioc->hs_reply;
4815 volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply; 4815 volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4816 u16 hword; 4816 u16 hword;
4817 4817
4818 hs_reply[0] = hs_reply[1] = hs_reply[7] = 0; 4818 hs_reply[0] = hs_reply[1] = hs_reply[7] = 0;
4819 4819
4820 /* 4820 /*
4821 * Get first two u16's so we can look at IOC's intended reply MsgLength 4821 * Get first two u16's so we can look at IOC's intended reply MsgLength
4822 */ 4822 */
4823 u16cnt=0; 4823 u16cnt=0;
4824 if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) { 4824 if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
4825 failcnt++; 4825 failcnt++;
4826 } else { 4826 } else {
4827 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF); 4827 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4828 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); 4828 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4829 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) 4829 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4830 failcnt++; 4830 failcnt++;
4831 else { 4831 else {
4832 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF); 4832 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4833 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); 4833 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4834 } 4834 }
4835 } 4835 }
4836 4836
4837 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitCnt=%d First handshake reply word=%08x%s\n", 4837 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitCnt=%d First handshake reply word=%08x%s\n",
4838 ioc->name, t, le32_to_cpu(*(u32 *)hs_reply), 4838 ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
4839 failcnt ? " - MISSING DOORBELL HANDSHAKE!" : "")); 4839 failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4840 4840
4841 /* 4841 /*
4842 * If no error (and IOC said MsgLength is > 0), piece together 4842 * If no error (and IOC said MsgLength is > 0), piece together
4843 * reply 16 bits at a time. 4843 * reply 16 bits at a time.
4844 */ 4844 */
4845 for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) { 4845 for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
4846 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) 4846 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4847 failcnt++; 4847 failcnt++;
4848 hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF); 4848 hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4849 /* don't overflow our IOC hs_reply[] buffer! */ 4849 /* don't overflow our IOC hs_reply[] buffer! */
4850 if (u16cnt < ARRAY_SIZE(ioc->hs_reply)) 4850 if (u16cnt < ARRAY_SIZE(ioc->hs_reply))
4851 hs_reply[u16cnt] = hword; 4851 hs_reply[u16cnt] = hword;
4852 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); 4852 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4853 } 4853 }
4854 4854
4855 if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) 4855 if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4856 failcnt++; 4856 failcnt++;
4857 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); 4857 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4858 4858
4859 if (failcnt) { 4859 if (failcnt) {
4860 printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n", 4860 printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
4861 ioc->name); 4861 ioc->name);
4862 return -failcnt; 4862 return -failcnt;
4863 } 4863 }
4864 #if 0 4864 #if 0
4865 else if (u16cnt != (2 * mptReply->MsgLength)) { 4865 else if (u16cnt != (2 * mptReply->MsgLength)) {
4866 return -101; 4866 return -101;
4867 } 4867 }
4868 else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) { 4868 else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
4869 return -102; 4869 return -102;
4870 } 4870 }
4871 #endif 4871 #endif
4872 4872
4873 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got Handshake reply:\n", ioc->name)); 4873 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got Handshake reply:\n", ioc->name));
4874 DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mptReply); 4874 DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mptReply);
4875 4875
4876 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n", 4876 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4877 ioc->name, t, u16cnt/2)); 4877 ioc->name, t, u16cnt/2));
4878 return u16cnt/2; 4878 return u16cnt/2;
4879 } 4879 }
4880 4880
4881 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 4881 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4882 /** 4882 /**
4883 * GetLanConfigPages - Fetch LANConfig pages. 4883 * GetLanConfigPages - Fetch LANConfig pages.
4884 * @ioc: Pointer to MPT_ADAPTER structure 4884 * @ioc: Pointer to MPT_ADAPTER structure
4885 * 4885 *
4886 * Return: 0 for success 4886 * Return: 0 for success
4887 * -ENOMEM if no memory available 4887 * -ENOMEM if no memory available
4888 * -EPERM if not allowed due to ISR context 4888 * -EPERM if not allowed due to ISR context
4889 * -EAGAIN if no msg frames currently available 4889 * -EAGAIN if no msg frames currently available
4890 * -EFAULT for non-successful reply or no reply (timeout) 4890 * -EFAULT for non-successful reply or no reply (timeout)
4891 */ 4891 */
4892 static int 4892 static int
4893 GetLanConfigPages(MPT_ADAPTER *ioc) 4893 GetLanConfigPages(MPT_ADAPTER *ioc)
4894 { 4894 {
4895 ConfigPageHeader_t hdr; 4895 ConfigPageHeader_t hdr;
4896 CONFIGPARMS cfg; 4896 CONFIGPARMS cfg;
4897 LANPage0_t *ppage0_alloc; 4897 LANPage0_t *ppage0_alloc;
4898 dma_addr_t page0_dma; 4898 dma_addr_t page0_dma;
4899 LANPage1_t *ppage1_alloc; 4899 LANPage1_t *ppage1_alloc;
4900 dma_addr_t page1_dma; 4900 dma_addr_t page1_dma;
4901 int rc = 0; 4901 int rc = 0;
4902 int data_sz; 4902 int data_sz;
4903 int copy_sz; 4903 int copy_sz;
4904 4904
4905 /* Get LAN Page 0 header */ 4905 /* Get LAN Page 0 header */
4906 hdr.PageVersion = 0; 4906 hdr.PageVersion = 0;
4907 hdr.PageLength = 0; 4907 hdr.PageLength = 0;
4908 hdr.PageNumber = 0; 4908 hdr.PageNumber = 0;
4909 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN; 4909 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4910 cfg.cfghdr.hdr = &hdr; 4910 cfg.cfghdr.hdr = &hdr;
4911 cfg.physAddr = -1; 4911 cfg.physAddr = -1;
4912 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 4912 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4913 cfg.dir = 0; 4913 cfg.dir = 0;
4914 cfg.pageAddr = 0; 4914 cfg.pageAddr = 0;
4915 cfg.timeout = 0; 4915 cfg.timeout = 0;
4916 4916
4917 if ((rc = mpt_config(ioc, &cfg)) != 0) 4917 if ((rc = mpt_config(ioc, &cfg)) != 0)
4918 return rc; 4918 return rc;
4919 4919
4920 if (hdr.PageLength > 0) { 4920 if (hdr.PageLength > 0) {
4921 data_sz = hdr.PageLength * 4; 4921 data_sz = hdr.PageLength * 4;
4922 ppage0_alloc = (LANPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma); 4922 ppage0_alloc = (LANPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4923 rc = -ENOMEM; 4923 rc = -ENOMEM;
4924 if (ppage0_alloc) { 4924 if (ppage0_alloc) {
4925 memset((u8 *)ppage0_alloc, 0, data_sz); 4925 memset((u8 *)ppage0_alloc, 0, data_sz);
4926 cfg.physAddr = page0_dma; 4926 cfg.physAddr = page0_dma;
4927 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 4927 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4928 4928
4929 if ((rc = mpt_config(ioc, &cfg)) == 0) { 4929 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4930 /* save the data */ 4930 /* save the data */
4931 copy_sz = min_t(int, sizeof(LANPage0_t), data_sz); 4931 copy_sz = min_t(int, sizeof(LANPage0_t), data_sz);
4932 memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz); 4932 memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz);
4933 4933
4934 } 4934 }
4935 4935
4936 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma); 4936 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4937 4937
4938 /* FIXME! 4938 /* FIXME!
4939 * Normalize endianness of structure data, 4939 * Normalize endianness of structure data,
4940 * by byte-swapping all > 1 byte fields! 4940 * by byte-swapping all > 1 byte fields!
4941 */ 4941 */
4942 4942
4943 } 4943 }
4944 4944
4945 if (rc) 4945 if (rc)
4946 return rc; 4946 return rc;
4947 } 4947 }
4948 4948
4949 /* Get LAN Page 1 header */ 4949 /* Get LAN Page 1 header */
4950 hdr.PageVersion = 0; 4950 hdr.PageVersion = 0;
4951 hdr.PageLength = 0; 4951 hdr.PageLength = 0;
4952 hdr.PageNumber = 1; 4952 hdr.PageNumber = 1;
4953 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN; 4953 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4954 cfg.cfghdr.hdr = &hdr; 4954 cfg.cfghdr.hdr = &hdr;
4955 cfg.physAddr = -1; 4955 cfg.physAddr = -1;
4956 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 4956 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4957 cfg.dir = 0; 4957 cfg.dir = 0;
4958 cfg.pageAddr = 0; 4958 cfg.pageAddr = 0;
4959 4959
4960 if ((rc = mpt_config(ioc, &cfg)) != 0) 4960 if ((rc = mpt_config(ioc, &cfg)) != 0)
4961 return rc; 4961 return rc;
4962 4962
4963 if (hdr.PageLength == 0) 4963 if (hdr.PageLength == 0)
4964 return 0; 4964 return 0;
4965 4965
4966 data_sz = hdr.PageLength * 4; 4966 data_sz = hdr.PageLength * 4;
4967 rc = -ENOMEM; 4967 rc = -ENOMEM;
4968 ppage1_alloc = (LANPage1_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma); 4968 ppage1_alloc = (LANPage1_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma);
4969 if (ppage1_alloc) { 4969 if (ppage1_alloc) {
4970 memset((u8 *)ppage1_alloc, 0, data_sz); 4970 memset((u8 *)ppage1_alloc, 0, data_sz);
4971 cfg.physAddr = page1_dma; 4971 cfg.physAddr = page1_dma;
4972 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 4972 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4973 4973
4974 if ((rc = mpt_config(ioc, &cfg)) == 0) { 4974 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4975 /* save the data */ 4975 /* save the data */
4976 copy_sz = min_t(int, sizeof(LANPage1_t), data_sz); 4976 copy_sz = min_t(int, sizeof(LANPage1_t), data_sz);
4977 memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz); 4977 memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz);
4978 } 4978 }
4979 4979
4980 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma); 4980 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma);
4981 4981
4982 /* FIXME! 4982 /* FIXME!
4983 * Normalize endianness of structure data, 4983 * Normalize endianness of structure data,
4984 * by byte-swapping all > 1 byte fields! 4984 * by byte-swapping all > 1 byte fields!
4985 */ 4985 */
4986 4986
4987 } 4987 }
4988 4988
4989 return rc; 4989 return rc;
4990 } 4990 }
4991 4991
4992 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 4992 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4993 /** 4993 /**
4994 * mptbase_sas_persist_operation - Perform operation on SAS Persistent Table 4994 * mptbase_sas_persist_operation - Perform operation on SAS Persistent Table
4995 * @ioc: Pointer to MPT_ADAPTER structure 4995 * @ioc: Pointer to MPT_ADAPTER structure
4996 * @persist_opcode: see below 4996 * @persist_opcode: see below
4997 * 4997 *
4998 * MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for 4998 * MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
4999 * devices not currently present. 4999 * devices not currently present.
5000 * MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings 5000 * MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
5001 * 5001 *
5002 * NOTE: Don't use not this function during interrupt time. 5002 * NOTE: Don't use not this function during interrupt time.
5003 * 5003 *
5004 * Returns 0 for success, non-zero error 5004 * Returns 0 for success, non-zero error
5005 */ 5005 */
5006 5006
5007 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 5007 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5008 int 5008 int
5009 mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode) 5009 mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
5010 { 5010 {
5011 SasIoUnitControlRequest_t *sasIoUnitCntrReq; 5011 SasIoUnitControlRequest_t *sasIoUnitCntrReq;
5012 SasIoUnitControlReply_t *sasIoUnitCntrReply; 5012 SasIoUnitControlReply_t *sasIoUnitCntrReply;
5013 MPT_FRAME_HDR *mf = NULL; 5013 MPT_FRAME_HDR *mf = NULL;
5014 MPIHeader_t *mpi_hdr; 5014 MPIHeader_t *mpi_hdr;
5015 int ret = 0; 5015 int ret = 0;
5016 unsigned long timeleft; 5016 unsigned long timeleft;
5017 5017
5018 mutex_lock(&ioc->mptbase_cmds.mutex); 5018 mutex_lock(&ioc->mptbase_cmds.mutex);
5019 5019
5020 /* init the internal cmd struct */ 5020 /* init the internal cmd struct */
5021 memset(ioc->mptbase_cmds.reply, 0 , MPT_DEFAULT_FRAME_SIZE); 5021 memset(ioc->mptbase_cmds.reply, 0 , MPT_DEFAULT_FRAME_SIZE);
5022 INITIALIZE_MGMT_STATUS(ioc->mptbase_cmds.status) 5022 INITIALIZE_MGMT_STATUS(ioc->mptbase_cmds.status)
5023 5023
5024 /* insure garbage is not sent to fw */ 5024 /* insure garbage is not sent to fw */
5025 switch(persist_opcode) { 5025 switch(persist_opcode) {
5026 5026
5027 case MPI_SAS_OP_CLEAR_NOT_PRESENT: 5027 case MPI_SAS_OP_CLEAR_NOT_PRESENT:
5028 case MPI_SAS_OP_CLEAR_ALL_PERSISTENT: 5028 case MPI_SAS_OP_CLEAR_ALL_PERSISTENT:
5029 break; 5029 break;
5030 5030
5031 default: 5031 default:
5032 ret = -1; 5032 ret = -1;
5033 goto out; 5033 goto out;
5034 } 5034 }
5035 5035
5036 printk(KERN_DEBUG "%s: persist_opcode=%x\n", 5036 printk(KERN_DEBUG "%s: persist_opcode=%x\n",
5037 __func__, persist_opcode); 5037 __func__, persist_opcode);
5038 5038
5039 /* Get a MF for this command. 5039 /* Get a MF for this command.
5040 */ 5040 */
5041 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) { 5041 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5042 printk(KERN_DEBUG "%s: no msg frames!\n", __func__); 5042 printk(KERN_DEBUG "%s: no msg frames!\n", __func__);
5043 ret = -1; 5043 ret = -1;
5044 goto out; 5044 goto out;
5045 } 5045 }
5046 5046
5047 mpi_hdr = (MPIHeader_t *) mf; 5047 mpi_hdr = (MPIHeader_t *) mf;
5048 sasIoUnitCntrReq = (SasIoUnitControlRequest_t *)mf; 5048 sasIoUnitCntrReq = (SasIoUnitControlRequest_t *)mf;
5049 memset(sasIoUnitCntrReq,0,sizeof(SasIoUnitControlRequest_t)); 5049 memset(sasIoUnitCntrReq,0,sizeof(SasIoUnitControlRequest_t));
5050 sasIoUnitCntrReq->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL; 5050 sasIoUnitCntrReq->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
5051 sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext; 5051 sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext;
5052 sasIoUnitCntrReq->Operation = persist_opcode; 5052 sasIoUnitCntrReq->Operation = persist_opcode;
5053 5053
5054 mpt_put_msg_frame(mpt_base_index, ioc, mf); 5054 mpt_put_msg_frame(mpt_base_index, ioc, mf);
5055 timeleft = wait_for_completion_timeout(&ioc->mptbase_cmds.done, 10*HZ); 5055 timeleft = wait_for_completion_timeout(&ioc->mptbase_cmds.done, 10*HZ);
5056 if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) { 5056 if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
5057 ret = -ETIME; 5057 ret = -ETIME;
5058 printk(KERN_DEBUG "%s: failed\n", __func__); 5058 printk(KERN_DEBUG "%s: failed\n", __func__);
5059 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET) 5059 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
5060 goto out; 5060 goto out;
5061 if (!timeleft) { 5061 if (!timeleft) {
5062 printk(KERN_DEBUG "%s: Issuing Reset from %s!!\n", 5062 printk(KERN_DEBUG "%s: Issuing Reset from %s!!\n",
5063 ioc->name, __func__); 5063 ioc->name, __func__);
5064 mpt_HardResetHandler(ioc, CAN_SLEEP); 5064 mpt_HardResetHandler(ioc, CAN_SLEEP);
5065 mpt_free_msg_frame(ioc, mf); 5065 mpt_free_msg_frame(ioc, mf);
5066 } 5066 }
5067 goto out; 5067 goto out;
5068 } 5068 }
5069 5069
5070 if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_RF_VALID)) { 5070 if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
5071 ret = -1; 5071 ret = -1;
5072 goto out; 5072 goto out;
5073 } 5073 }
5074 5074
5075 sasIoUnitCntrReply = 5075 sasIoUnitCntrReply =
5076 (SasIoUnitControlReply_t *)ioc->mptbase_cmds.reply; 5076 (SasIoUnitControlReply_t *)ioc->mptbase_cmds.reply;
5077 if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) { 5077 if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) {
5078 printk(KERN_DEBUG "%s: IOCStatus=0x%X IOCLogInfo=0x%X\n", 5078 printk(KERN_DEBUG "%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
5079 __func__, sasIoUnitCntrReply->IOCStatus, 5079 __func__, sasIoUnitCntrReply->IOCStatus,
5080 sasIoUnitCntrReply->IOCLogInfo); 5080 sasIoUnitCntrReply->IOCLogInfo);
5081 printk(KERN_DEBUG "%s: failed\n", __func__); 5081 printk(KERN_DEBUG "%s: failed\n", __func__);
5082 ret = -1; 5082 ret = -1;
5083 } else 5083 } else
5084 printk(KERN_DEBUG "%s: success\n", __func__); 5084 printk(KERN_DEBUG "%s: success\n", __func__);
5085 out: 5085 out:
5086 5086
5087 CLEAR_MGMT_STATUS(ioc->mptbase_cmds.status) 5087 CLEAR_MGMT_STATUS(ioc->mptbase_cmds.status)
5088 mutex_unlock(&ioc->mptbase_cmds.mutex); 5088 mutex_unlock(&ioc->mptbase_cmds.mutex);
5089 return ret; 5089 return ret;
5090 } 5090 }
5091 5091
5092 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 5092 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5093 5093
5094 static void 5094 static void
5095 mptbase_raid_process_event_data(MPT_ADAPTER *ioc, 5095 mptbase_raid_process_event_data(MPT_ADAPTER *ioc,
5096 MpiEventDataRaid_t * pRaidEventData) 5096 MpiEventDataRaid_t * pRaidEventData)
5097 { 5097 {
5098 int volume; 5098 int volume;
5099 int reason; 5099 int reason;
5100 int disk; 5100 int disk;
5101 int status; 5101 int status;
5102 int flags; 5102 int flags;
5103 int state; 5103 int state;
5104 5104
5105 volume = pRaidEventData->VolumeID; 5105 volume = pRaidEventData->VolumeID;
5106 reason = pRaidEventData->ReasonCode; 5106 reason = pRaidEventData->ReasonCode;
5107 disk = pRaidEventData->PhysDiskNum; 5107 disk = pRaidEventData->PhysDiskNum;
5108 status = le32_to_cpu(pRaidEventData->SettingsStatus); 5108 status = le32_to_cpu(pRaidEventData->SettingsStatus);
5109 flags = (status >> 0) & 0xff; 5109 flags = (status >> 0) & 0xff;
5110 state = (status >> 8) & 0xff; 5110 state = (status >> 8) & 0xff;
5111 5111
5112 if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) { 5112 if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
5113 return; 5113 return;
5114 } 5114 }
5115 5115
5116 if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED && 5116 if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED &&
5117 reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) || 5117 reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) ||
5118 (reason == MPI_EVENT_RAID_RC_SMART_DATA)) { 5118 (reason == MPI_EVENT_RAID_RC_SMART_DATA)) {
5119 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d id=%d\n", 5119 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d id=%d\n",
5120 ioc->name, disk, volume); 5120 ioc->name, disk, volume);
5121 } else { 5121 } else {
5122 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n", 5122 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n",
5123 ioc->name, volume); 5123 ioc->name, volume);
5124 } 5124 }
5125 5125
5126 switch(reason) { 5126 switch(reason) {
5127 case MPI_EVENT_RAID_RC_VOLUME_CREATED: 5127 case MPI_EVENT_RAID_RC_VOLUME_CREATED:
5128 printk(MYIOC_s_INFO_FMT " volume has been created\n", 5128 printk(MYIOC_s_INFO_FMT " volume has been created\n",
5129 ioc->name); 5129 ioc->name);
5130 break; 5130 break;
5131 5131
5132 case MPI_EVENT_RAID_RC_VOLUME_DELETED: 5132 case MPI_EVENT_RAID_RC_VOLUME_DELETED:
5133 5133
5134 printk(MYIOC_s_INFO_FMT " volume has been deleted\n", 5134 printk(MYIOC_s_INFO_FMT " volume has been deleted\n",
5135 ioc->name); 5135 ioc->name);
5136 break; 5136 break;
5137 5137
5138 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED: 5138 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED:
5139 printk(MYIOC_s_INFO_FMT " volume settings have been changed\n", 5139 printk(MYIOC_s_INFO_FMT " volume settings have been changed\n",
5140 ioc->name); 5140 ioc->name);
5141 break; 5141 break;
5142 5142
5143 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED: 5143 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
5144 printk(MYIOC_s_INFO_FMT " volume is now %s%s%s%s\n", 5144 printk(MYIOC_s_INFO_FMT " volume is now %s%s%s%s\n",
5145 ioc->name, 5145 ioc->name,
5146 state == MPI_RAIDVOL0_STATUS_STATE_OPTIMAL 5146 state == MPI_RAIDVOL0_STATUS_STATE_OPTIMAL
5147 ? "optimal" 5147 ? "optimal"
5148 : state == MPI_RAIDVOL0_STATUS_STATE_DEGRADED 5148 : state == MPI_RAIDVOL0_STATUS_STATE_DEGRADED
5149 ? "degraded" 5149 ? "degraded"
5150 : state == MPI_RAIDVOL0_STATUS_STATE_FAILED 5150 : state == MPI_RAIDVOL0_STATUS_STATE_FAILED
5151 ? "failed" 5151 ? "failed"
5152 : "state unknown", 5152 : "state unknown",
5153 flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED 5153 flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED
5154 ? ", enabled" : "", 5154 ? ", enabled" : "",
5155 flags & MPI_RAIDVOL0_STATUS_FLAG_QUIESCED 5155 flags & MPI_RAIDVOL0_STATUS_FLAG_QUIESCED
5156 ? ", quiesced" : "", 5156 ? ", quiesced" : "",
5157 flags & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS 5157 flags & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
5158 ? ", resync in progress" : "" ); 5158 ? ", resync in progress" : "" );
5159 break; 5159 break;
5160 5160
5161 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED: 5161 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED:
5162 printk(MYIOC_s_INFO_FMT " volume membership of PhysDisk %d has changed\n", 5162 printk(MYIOC_s_INFO_FMT " volume membership of PhysDisk %d has changed\n",
5163 ioc->name, disk); 5163 ioc->name, disk);
5164 break; 5164 break;
5165 5165
5166 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED: 5166 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
5167 printk(MYIOC_s_INFO_FMT " PhysDisk has been created\n", 5167 printk(MYIOC_s_INFO_FMT " PhysDisk has been created\n",
5168 ioc->name); 5168 ioc->name);
5169 break; 5169 break;
5170 5170
5171 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED: 5171 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
5172 printk(MYIOC_s_INFO_FMT " PhysDisk has been deleted\n", 5172 printk(MYIOC_s_INFO_FMT " PhysDisk has been deleted\n",
5173 ioc->name); 5173 ioc->name);
5174 break; 5174 break;
5175 5175
5176 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED: 5176 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED:
5177 printk(MYIOC_s_INFO_FMT " PhysDisk settings have been changed\n", 5177 printk(MYIOC_s_INFO_FMT " PhysDisk settings have been changed\n",
5178 ioc->name); 5178 ioc->name);
5179 break; 5179 break;
5180 5180
5181 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED: 5181 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
5182 printk(MYIOC_s_INFO_FMT " PhysDisk is now %s%s%s\n", 5182 printk(MYIOC_s_INFO_FMT " PhysDisk is now %s%s%s\n",
5183 ioc->name, 5183 ioc->name,
5184 state == MPI_PHYSDISK0_STATUS_ONLINE 5184 state == MPI_PHYSDISK0_STATUS_ONLINE
5185 ? "online" 5185 ? "online"
5186 : state == MPI_PHYSDISK0_STATUS_MISSING 5186 : state == MPI_PHYSDISK0_STATUS_MISSING
5187 ? "missing" 5187 ? "missing"
5188 : state == MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE 5188 : state == MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE
5189 ? "not compatible" 5189 ? "not compatible"
5190 : state == MPI_PHYSDISK0_STATUS_FAILED 5190 : state == MPI_PHYSDISK0_STATUS_FAILED
5191 ? "failed" 5191 ? "failed"
5192 : state == MPI_PHYSDISK0_STATUS_INITIALIZING 5192 : state == MPI_PHYSDISK0_STATUS_INITIALIZING
5193 ? "initializing" 5193 ? "initializing"
5194 : state == MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED 5194 : state == MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED
5195 ? "offline requested" 5195 ? "offline requested"
5196 : state == MPI_PHYSDISK0_STATUS_FAILED_REQUESTED 5196 : state == MPI_PHYSDISK0_STATUS_FAILED_REQUESTED
5197 ? "failed requested" 5197 ? "failed requested"
5198 : state == MPI_PHYSDISK0_STATUS_OTHER_OFFLINE 5198 : state == MPI_PHYSDISK0_STATUS_OTHER_OFFLINE
5199 ? "offline" 5199 ? "offline"
5200 : "state unknown", 5200 : "state unknown",
5201 flags & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC 5201 flags & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
5202 ? ", out of sync" : "", 5202 ? ", out of sync" : "",
5203 flags & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED 5203 flags & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED
5204 ? ", quiesced" : "" ); 5204 ? ", quiesced" : "" );
5205 break; 5205 break;
5206 5206
5207 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED: 5207 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED:
5208 printk(MYIOC_s_INFO_FMT " Domain Validation needed for PhysDisk %d\n", 5208 printk(MYIOC_s_INFO_FMT " Domain Validation needed for PhysDisk %d\n",
5209 ioc->name, disk); 5209 ioc->name, disk);
5210 break; 5210 break;
5211 5211
5212 case MPI_EVENT_RAID_RC_SMART_DATA: 5212 case MPI_EVENT_RAID_RC_SMART_DATA:
5213 printk(MYIOC_s_INFO_FMT " SMART data received, ASC/ASCQ = %02xh/%02xh\n", 5213 printk(MYIOC_s_INFO_FMT " SMART data received, ASC/ASCQ = %02xh/%02xh\n",
5214 ioc->name, pRaidEventData->ASC, pRaidEventData->ASCQ); 5214 ioc->name, pRaidEventData->ASC, pRaidEventData->ASCQ);
5215 break; 5215 break;
5216 5216
5217 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED: 5217 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED:
5218 printk(MYIOC_s_INFO_FMT " replacement of PhysDisk %d has started\n", 5218 printk(MYIOC_s_INFO_FMT " replacement of PhysDisk %d has started\n",
5219 ioc->name, disk); 5219 ioc->name, disk);
5220 break; 5220 break;
5221 } 5221 }
5222 } 5222 }
5223 5223
5224 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 5224 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5225 /** 5225 /**
5226 * GetIoUnitPage2 - Retrieve BIOS version and boot order information. 5226 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
5227 * @ioc: Pointer to MPT_ADAPTER structure 5227 * @ioc: Pointer to MPT_ADAPTER structure
5228 * 5228 *
5229 * Returns: 0 for success 5229 * Returns: 0 for success
5230 * -ENOMEM if no memory available 5230 * -ENOMEM if no memory available
5231 * -EPERM if not allowed due to ISR context 5231 * -EPERM if not allowed due to ISR context
5232 * -EAGAIN if no msg frames currently available 5232 * -EAGAIN if no msg frames currently available
5233 * -EFAULT for non-successful reply or no reply (timeout) 5233 * -EFAULT for non-successful reply or no reply (timeout)
5234 */ 5234 */
5235 static int 5235 static int
5236 GetIoUnitPage2(MPT_ADAPTER *ioc) 5236 GetIoUnitPage2(MPT_ADAPTER *ioc)
5237 { 5237 {
5238 ConfigPageHeader_t hdr; 5238 ConfigPageHeader_t hdr;
5239 CONFIGPARMS cfg; 5239 CONFIGPARMS cfg;
5240 IOUnitPage2_t *ppage_alloc; 5240 IOUnitPage2_t *ppage_alloc;
5241 dma_addr_t page_dma; 5241 dma_addr_t page_dma;
5242 int data_sz; 5242 int data_sz;
5243 int rc; 5243 int rc;
5244 5244
5245 /* Get the page header */ 5245 /* Get the page header */
5246 hdr.PageVersion = 0; 5246 hdr.PageVersion = 0;
5247 hdr.PageLength = 0; 5247 hdr.PageLength = 0;
5248 hdr.PageNumber = 2; 5248 hdr.PageNumber = 2;
5249 hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT; 5249 hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
5250 cfg.cfghdr.hdr = &hdr; 5250 cfg.cfghdr.hdr = &hdr;
5251 cfg.physAddr = -1; 5251 cfg.physAddr = -1;
5252 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 5252 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5253 cfg.dir = 0; 5253 cfg.dir = 0;
5254 cfg.pageAddr = 0; 5254 cfg.pageAddr = 0;
5255 cfg.timeout = 0; 5255 cfg.timeout = 0;
5256 5256
5257 if ((rc = mpt_config(ioc, &cfg)) != 0) 5257 if ((rc = mpt_config(ioc, &cfg)) != 0)
5258 return rc; 5258 return rc;
5259 5259
5260 if (hdr.PageLength == 0) 5260 if (hdr.PageLength == 0)
5261 return 0; 5261 return 0;
5262 5262
5263 /* Read the config page */ 5263 /* Read the config page */
5264 data_sz = hdr.PageLength * 4; 5264 data_sz = hdr.PageLength * 4;
5265 rc = -ENOMEM; 5265 rc = -ENOMEM;
5266 ppage_alloc = (IOUnitPage2_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma); 5266 ppage_alloc = (IOUnitPage2_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
5267 if (ppage_alloc) { 5267 if (ppage_alloc) {
5268 memset((u8 *)ppage_alloc, 0, data_sz); 5268 memset((u8 *)ppage_alloc, 0, data_sz);
5269 cfg.physAddr = page_dma; 5269 cfg.physAddr = page_dma;
5270 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 5270 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5271 5271
5272 /* If Good, save data */ 5272 /* If Good, save data */
5273 if ((rc = mpt_config(ioc, &cfg)) == 0) 5273 if ((rc = mpt_config(ioc, &cfg)) == 0)
5274 ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion); 5274 ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion);
5275 5275
5276 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma); 5276 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma);
5277 } 5277 }
5278 5278
5279 return rc; 5279 return rc;
5280 } 5280 }
5281 5281
5282 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 5282 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5283 /** 5283 /**
5284 * mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2 5284 * mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
5285 * @ioc: Pointer to a Adapter Strucutre 5285 * @ioc: Pointer to a Adapter Strucutre
5286 * @portnum: IOC port number 5286 * @portnum: IOC port number
5287 * 5287 *
5288 * Return: -EFAULT if read of config page header fails 5288 * Return: -EFAULT if read of config page header fails
5289 * or if no nvram 5289 * or if no nvram
5290 * If read of SCSI Port Page 0 fails, 5290 * If read of SCSI Port Page 0 fails,
5291 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF) 5291 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
5292 * Adapter settings: async, narrow 5292 * Adapter settings: async, narrow
5293 * Return 1 5293 * Return 1
5294 * If read of SCSI Port Page 2 fails, 5294 * If read of SCSI Port Page 2 fails,
5295 * Adapter settings valid 5295 * Adapter settings valid
5296 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF) 5296 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
5297 * Return 1 5297 * Return 1
5298 * Else 5298 * Else
5299 * Both valid 5299 * Both valid
5300 * Return 0 5300 * Return 0
5301 * CHECK - what type of locking mechanisms should be used???? 5301 * CHECK - what type of locking mechanisms should be used????
5302 */ 5302 */
5303 static int 5303 static int
5304 mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum) 5304 mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
5305 { 5305 {
5306 u8 *pbuf; 5306 u8 *pbuf;
5307 dma_addr_t buf_dma; 5307 dma_addr_t buf_dma;
5308 CONFIGPARMS cfg; 5308 CONFIGPARMS cfg;
5309 ConfigPageHeader_t header; 5309 ConfigPageHeader_t header;
5310 int ii; 5310 int ii;
5311 int data, rc = 0; 5311 int data, rc = 0;
5312 5312
5313 /* Allocate memory 5313 /* Allocate memory
5314 */ 5314 */
5315 if (!ioc->spi_data.nvram) { 5315 if (!ioc->spi_data.nvram) {
5316 int sz; 5316 int sz;
5317 u8 *mem; 5317 u8 *mem;
5318 sz = MPT_MAX_SCSI_DEVICES * sizeof(int); 5318 sz = MPT_MAX_SCSI_DEVICES * sizeof(int);
5319 mem = kmalloc(sz, GFP_ATOMIC); 5319 mem = kmalloc(sz, GFP_ATOMIC);
5320 if (mem == NULL) 5320 if (mem == NULL)
5321 return -EFAULT; 5321 return -EFAULT;
5322 5322
5323 ioc->spi_data.nvram = (int *) mem; 5323 ioc->spi_data.nvram = (int *) mem;
5324 5324
5325 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SCSI device NVRAM settings @ %p, sz=%d\n", 5325 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SCSI device NVRAM settings @ %p, sz=%d\n",
5326 ioc->name, ioc->spi_data.nvram, sz)); 5326 ioc->name, ioc->spi_data.nvram, sz));
5327 } 5327 }
5328 5328
5329 /* Invalidate NVRAM information 5329 /* Invalidate NVRAM information
5330 */ 5330 */
5331 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) { 5331 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5332 ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID; 5332 ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID;
5333 } 5333 }
5334 5334
5335 /* Read SPP0 header, allocate memory, then read page. 5335 /* Read SPP0 header, allocate memory, then read page.
5336 */ 5336 */
5337 header.PageVersion = 0; 5337 header.PageVersion = 0;
5338 header.PageLength = 0; 5338 header.PageLength = 0;
5339 header.PageNumber = 0; 5339 header.PageNumber = 0;
5340 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT; 5340 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
5341 cfg.cfghdr.hdr = &header; 5341 cfg.cfghdr.hdr = &header;
5342 cfg.physAddr = -1; 5342 cfg.physAddr = -1;
5343 cfg.pageAddr = portnum; 5343 cfg.pageAddr = portnum;
5344 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 5344 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5345 cfg.dir = 0; 5345 cfg.dir = 0;
5346 cfg.timeout = 0; /* use default */ 5346 cfg.timeout = 0; /* use default */
5347 if (mpt_config(ioc, &cfg) != 0) 5347 if (mpt_config(ioc, &cfg) != 0)
5348 return -EFAULT; 5348 return -EFAULT;
5349 5349
5350 if (header.PageLength > 0) { 5350 if (header.PageLength > 0) {
5351 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma); 5351 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
5352 if (pbuf) { 5352 if (pbuf) {
5353 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 5353 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5354 cfg.physAddr = buf_dma; 5354 cfg.physAddr = buf_dma;
5355 if (mpt_config(ioc, &cfg) != 0) { 5355 if (mpt_config(ioc, &cfg) != 0) {
5356 ioc->spi_data.maxBusWidth = MPT_NARROW; 5356 ioc->spi_data.maxBusWidth = MPT_NARROW;
5357 ioc->spi_data.maxSyncOffset = 0; 5357 ioc->spi_data.maxSyncOffset = 0;
5358 ioc->spi_data.minSyncFactor = MPT_ASYNC; 5358 ioc->spi_data.minSyncFactor = MPT_ASYNC;
5359 ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN; 5359 ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
5360 rc = 1; 5360 rc = 1;
5361 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT 5361 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5362 "Unable to read PortPage0 minSyncFactor=%x\n", 5362 "Unable to read PortPage0 minSyncFactor=%x\n",
5363 ioc->name, ioc->spi_data.minSyncFactor)); 5363 ioc->name, ioc->spi_data.minSyncFactor));
5364 } else { 5364 } else {
5365 /* Save the Port Page 0 data 5365 /* Save the Port Page 0 data
5366 */ 5366 */
5367 SCSIPortPage0_t *pPP0 = (SCSIPortPage0_t *) pbuf; 5367 SCSIPortPage0_t *pPP0 = (SCSIPortPage0_t *) pbuf;
5368 pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities); 5368 pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
5369 pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface); 5369 pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
5370 5370
5371 if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) { 5371 if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) {
5372 ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS; 5372 ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
5373 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT 5373 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5374 "noQas due to Capabilities=%x\n", 5374 "noQas due to Capabilities=%x\n",
5375 ioc->name, pPP0->Capabilities)); 5375 ioc->name, pPP0->Capabilities));
5376 } 5376 }
5377 ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0; 5377 ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
5378 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK; 5378 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
5379 if (data) { 5379 if (data) {
5380 ioc->spi_data.maxSyncOffset = (u8) (data >> 16); 5380 ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
5381 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK; 5381 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
5382 ioc->spi_data.minSyncFactor = (u8) (data >> 8); 5382 ioc->spi_data.minSyncFactor = (u8) (data >> 8);
5383 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT 5383 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5384 "PortPage0 minSyncFactor=%x\n", 5384 "PortPage0 minSyncFactor=%x\n",
5385 ioc->name, ioc->spi_data.minSyncFactor)); 5385 ioc->name, ioc->spi_data.minSyncFactor));
5386 } else { 5386 } else {
5387 ioc->spi_data.maxSyncOffset = 0; 5387 ioc->spi_data.maxSyncOffset = 0;
5388 ioc->spi_data.minSyncFactor = MPT_ASYNC; 5388 ioc->spi_data.minSyncFactor = MPT_ASYNC;
5389 } 5389 }
5390 5390
5391 ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK; 5391 ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK;
5392 5392
5393 /* Update the minSyncFactor based on bus type. 5393 /* Update the minSyncFactor based on bus type.
5394 */ 5394 */
5395 if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) || 5395 if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
5396 (ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE)) { 5396 (ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE)) {
5397 5397
5398 if (ioc->spi_data.minSyncFactor < MPT_ULTRA) { 5398 if (ioc->spi_data.minSyncFactor < MPT_ULTRA) {
5399 ioc->spi_data.minSyncFactor = MPT_ULTRA; 5399 ioc->spi_data.minSyncFactor = MPT_ULTRA;
5400 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT 5400 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5401 "HVD or SE detected, minSyncFactor=%x\n", 5401 "HVD or SE detected, minSyncFactor=%x\n",
5402 ioc->name, ioc->spi_data.minSyncFactor)); 5402 ioc->name, ioc->spi_data.minSyncFactor));
5403 } 5403 }
5404 } 5404 }
5405 } 5405 }
5406 if (pbuf) { 5406 if (pbuf) {
5407 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma); 5407 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
5408 } 5408 }
5409 } 5409 }
5410 } 5410 }
5411 5411
5412 /* SCSI Port Page 2 - Read the header then the page. 5412 /* SCSI Port Page 2 - Read the header then the page.
5413 */ 5413 */
5414 header.PageVersion = 0; 5414 header.PageVersion = 0;
5415 header.PageLength = 0; 5415 header.PageLength = 0;
5416 header.PageNumber = 2; 5416 header.PageNumber = 2;
5417 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT; 5417 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
5418 cfg.cfghdr.hdr = &header; 5418 cfg.cfghdr.hdr = &header;
5419 cfg.physAddr = -1; 5419 cfg.physAddr = -1;
5420 cfg.pageAddr = portnum; 5420 cfg.pageAddr = portnum;
5421 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 5421 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5422 cfg.dir = 0; 5422 cfg.dir = 0;
5423 if (mpt_config(ioc, &cfg) != 0) 5423 if (mpt_config(ioc, &cfg) != 0)
5424 return -EFAULT; 5424 return -EFAULT;
5425 5425
5426 if (header.PageLength > 0) { 5426 if (header.PageLength > 0) {
5427 /* Allocate memory and read SCSI Port Page 2 5427 /* Allocate memory and read SCSI Port Page 2
5428 */ 5428 */
5429 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma); 5429 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
5430 if (pbuf) { 5430 if (pbuf) {
5431 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM; 5431 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM;
5432 cfg.physAddr = buf_dma; 5432 cfg.physAddr = buf_dma;
5433 if (mpt_config(ioc, &cfg) != 0) { 5433 if (mpt_config(ioc, &cfg) != 0) {
5434 /* Nvram data is left with INVALID mark 5434 /* Nvram data is left with INVALID mark
5435 */ 5435 */
5436 rc = 1; 5436 rc = 1;
5437 } else if (ioc->pcidev->vendor == PCI_VENDOR_ID_ATTO) { 5437 } else if (ioc->pcidev->vendor == PCI_VENDOR_ID_ATTO) {
5438 5438
5439 /* This is an ATTO adapter, read Page2 accordingly 5439 /* This is an ATTO adapter, read Page2 accordingly
5440 */ 5440 */
5441 ATTO_SCSIPortPage2_t *pPP2 = (ATTO_SCSIPortPage2_t *) pbuf; 5441 ATTO_SCSIPortPage2_t *pPP2 = (ATTO_SCSIPortPage2_t *) pbuf;
5442 ATTODeviceInfo_t *pdevice = NULL; 5442 ATTODeviceInfo_t *pdevice = NULL;
5443 u16 ATTOFlags; 5443 u16 ATTOFlags;
5444 5444
5445 /* Save the Port Page 2 data 5445 /* Save the Port Page 2 data
5446 * (reformat into a 32bit quantity) 5446 * (reformat into a 32bit quantity)
5447 */ 5447 */
5448 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) { 5448 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5449 pdevice = &pPP2->DeviceSettings[ii]; 5449 pdevice = &pPP2->DeviceSettings[ii];
5450 ATTOFlags = le16_to_cpu(pdevice->ATTOFlags); 5450 ATTOFlags = le16_to_cpu(pdevice->ATTOFlags);
5451 data = 0; 5451 data = 0;
5452 5452
5453 /* Translate ATTO device flags to LSI format 5453 /* Translate ATTO device flags to LSI format
5454 */ 5454 */
5455 if (ATTOFlags & ATTOFLAG_DISC) 5455 if (ATTOFlags & ATTOFLAG_DISC)
5456 data |= (MPI_SCSIPORTPAGE2_DEVICE_DISCONNECT_ENABLE); 5456 data |= (MPI_SCSIPORTPAGE2_DEVICE_DISCONNECT_ENABLE);
5457 if (ATTOFlags & ATTOFLAG_ID_ENB) 5457 if (ATTOFlags & ATTOFLAG_ID_ENB)
5458 data |= (MPI_SCSIPORTPAGE2_DEVICE_ID_SCAN_ENABLE); 5458 data |= (MPI_SCSIPORTPAGE2_DEVICE_ID_SCAN_ENABLE);
5459 if (ATTOFlags & ATTOFLAG_LUN_ENB) 5459 if (ATTOFlags & ATTOFLAG_LUN_ENB)
5460 data |= (MPI_SCSIPORTPAGE2_DEVICE_LUN_SCAN_ENABLE); 5460 data |= (MPI_SCSIPORTPAGE2_DEVICE_LUN_SCAN_ENABLE);
5461 if (ATTOFlags & ATTOFLAG_TAGGED) 5461 if (ATTOFlags & ATTOFLAG_TAGGED)
5462 data |= (MPI_SCSIPORTPAGE2_DEVICE_TAG_QUEUE_ENABLE); 5462 data |= (MPI_SCSIPORTPAGE2_DEVICE_TAG_QUEUE_ENABLE);
5463 if (!(ATTOFlags & ATTOFLAG_WIDE_ENB)) 5463 if (!(ATTOFlags & ATTOFLAG_WIDE_ENB))
5464 data |= (MPI_SCSIPORTPAGE2_DEVICE_WIDE_DISABLE); 5464 data |= (MPI_SCSIPORTPAGE2_DEVICE_WIDE_DISABLE);
5465 5465
5466 data = (data << 16) | (pdevice->Period << 8) | 10; 5466 data = (data << 16) | (pdevice->Period << 8) | 10;
5467 ioc->spi_data.nvram[ii] = data; 5467 ioc->spi_data.nvram[ii] = data;
5468 } 5468 }
5469 } else { 5469 } else {
5470 SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf; 5470 SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf;
5471 MpiDeviceInfo_t *pdevice = NULL; 5471 MpiDeviceInfo_t *pdevice = NULL;
5472 5472
5473 /* 5473 /*
5474 * Save "Set to Avoid SCSI Bus Resets" flag 5474 * Save "Set to Avoid SCSI Bus Resets" flag
5475 */ 5475 */
5476 ioc->spi_data.bus_reset = 5476 ioc->spi_data.bus_reset =
5477 (le32_to_cpu(pPP2->PortFlags) & 5477 (le32_to_cpu(pPP2->PortFlags) &
5478 MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET) ? 5478 MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET) ?
5479 0 : 1 ; 5479 0 : 1 ;
5480 5480
5481 /* Save the Port Page 2 data 5481 /* Save the Port Page 2 data
5482 * (reformat into a 32bit quantity) 5482 * (reformat into a 32bit quantity)
5483 */ 5483 */
5484 data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK; 5484 data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
5485 ioc->spi_data.PortFlags = data; 5485 ioc->spi_data.PortFlags = data;
5486 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) { 5486 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5487 pdevice = &pPP2->DeviceSettings[ii]; 5487 pdevice = &pPP2->DeviceSettings[ii];
5488 data = (le16_to_cpu(pdevice->DeviceFlags) << 16) | 5488 data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
5489 (pdevice->SyncFactor << 8) | pdevice->Timeout; 5489 (pdevice->SyncFactor << 8) | pdevice->Timeout;
5490 ioc->spi_data.nvram[ii] = data; 5490 ioc->spi_data.nvram[ii] = data;
5491 } 5491 }
5492 } 5492 }
5493 5493
5494 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma); 5494 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
5495 } 5495 }
5496 } 5496 }
5497 5497
5498 /* Update Adapter limits with those from NVRAM 5498 /* Update Adapter limits with those from NVRAM
5499 * Comment: Don't need to do this. Target performance 5499 * Comment: Don't need to do this. Target performance
5500 * parameters will never exceed the adapters limits. 5500 * parameters will never exceed the adapters limits.
5501 */ 5501 */
5502 5502
5503 return rc; 5503 return rc;
5504 } 5504 }
5505 5505
5506 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 5506 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5507 /** 5507 /**
5508 * mpt_readScsiDevicePageHeaders - save version and length of SDP1 5508 * mpt_readScsiDevicePageHeaders - save version and length of SDP1
5509 * @ioc: Pointer to a Adapter Strucutre 5509 * @ioc: Pointer to a Adapter Strucutre
5510 * @portnum: IOC port number 5510 * @portnum: IOC port number
5511 * 5511 *
5512 * Return: -EFAULT if read of config page header fails 5512 * Return: -EFAULT if read of config page header fails
5513 * or 0 if success. 5513 * or 0 if success.
5514 */ 5514 */
5515 static int 5515 static int
5516 mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum) 5516 mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
5517 { 5517 {
5518 CONFIGPARMS cfg; 5518 CONFIGPARMS cfg;
5519 ConfigPageHeader_t header; 5519 ConfigPageHeader_t header;
5520 5520
5521 /* Read the SCSI Device Page 1 header 5521 /* Read the SCSI Device Page 1 header
5522 */ 5522 */
5523 header.PageVersion = 0; 5523 header.PageVersion = 0;
5524 header.PageLength = 0; 5524 header.PageLength = 0;
5525 header.PageNumber = 1; 5525 header.PageNumber = 1;
5526 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE; 5526 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5527 cfg.cfghdr.hdr = &header; 5527 cfg.cfghdr.hdr = &header;
5528 cfg.physAddr = -1; 5528 cfg.physAddr = -1;
5529 cfg.pageAddr = portnum; 5529 cfg.pageAddr = portnum;
5530 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 5530 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5531 cfg.dir = 0; 5531 cfg.dir = 0;
5532 cfg.timeout = 0; 5532 cfg.timeout = 0;
5533 if (mpt_config(ioc, &cfg) != 0) 5533 if (mpt_config(ioc, &cfg) != 0)
5534 return -EFAULT; 5534 return -EFAULT;
5535 5535
5536 ioc->spi_data.sdp1version = cfg.cfghdr.hdr->PageVersion; 5536 ioc->spi_data.sdp1version = cfg.cfghdr.hdr->PageVersion;
5537 ioc->spi_data.sdp1length = cfg.cfghdr.hdr->PageLength; 5537 ioc->spi_data.sdp1length = cfg.cfghdr.hdr->PageLength;
5538 5538
5539 header.PageVersion = 0; 5539 header.PageVersion = 0;
5540 header.PageLength = 0; 5540 header.PageLength = 0;
5541 header.PageNumber = 0; 5541 header.PageNumber = 0;
5542 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE; 5542 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5543 if (mpt_config(ioc, &cfg) != 0) 5543 if (mpt_config(ioc, &cfg) != 0)
5544 return -EFAULT; 5544 return -EFAULT;
5545 5545
5546 ioc->spi_data.sdp0version = cfg.cfghdr.hdr->PageVersion; 5546 ioc->spi_data.sdp0version = cfg.cfghdr.hdr->PageVersion;
5547 ioc->spi_data.sdp0length = cfg.cfghdr.hdr->PageLength; 5547 ioc->spi_data.sdp0length = cfg.cfghdr.hdr->PageLength;
5548 5548
5549 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 0: version %d length %d\n", 5549 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 0: version %d length %d\n",
5550 ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length)); 5550 ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
5551 5551
5552 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 1: version %d length %d\n", 5552 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 1: version %d length %d\n",
5553 ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length)); 5553 ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length));
5554 return 0; 5554 return 0;
5555 } 5555 }
5556 5556
5557 /** 5557 /**
5558 * mpt_inactive_raid_list_free - This clears this link list. 5558 * mpt_inactive_raid_list_free - This clears this link list.
5559 * @ioc : pointer to per adapter structure 5559 * @ioc : pointer to per adapter structure
5560 **/ 5560 **/
5561 static void 5561 static void
5562 mpt_inactive_raid_list_free(MPT_ADAPTER *ioc) 5562 mpt_inactive_raid_list_free(MPT_ADAPTER *ioc)
5563 { 5563 {
5564 struct inactive_raid_component_info *component_info, *pNext; 5564 struct inactive_raid_component_info *component_info, *pNext;
5565 5565
5566 if (list_empty(&ioc->raid_data.inactive_list)) 5566 if (list_empty(&ioc->raid_data.inactive_list))
5567 return; 5567 return;
5568 5568
5569 mutex_lock(&ioc->raid_data.inactive_list_mutex); 5569 mutex_lock(&ioc->raid_data.inactive_list_mutex);
5570 list_for_each_entry_safe(component_info, pNext, 5570 list_for_each_entry_safe(component_info, pNext,
5571 &ioc->raid_data.inactive_list, list) { 5571 &ioc->raid_data.inactive_list, list) {
5572 list_del(&component_info->list); 5572 list_del(&component_info->list);
5573 kfree(component_info); 5573 kfree(component_info);
5574 } 5574 }
5575 mutex_unlock(&ioc->raid_data.inactive_list_mutex); 5575 mutex_unlock(&ioc->raid_data.inactive_list_mutex);
5576 } 5576 }
5577 5577
5578 /** 5578 /**
5579 * mpt_inactive_raid_volumes - sets up link list of phy_disk_nums for devices belonging in an inactive volume 5579 * mpt_inactive_raid_volumes - sets up link list of phy_disk_nums for devices belonging in an inactive volume
5580 * 5580 *
5581 * @ioc : pointer to per adapter structure 5581 * @ioc : pointer to per adapter structure
5582 * @channel : volume channel 5582 * @channel : volume channel
5583 * @id : volume target id 5583 * @id : volume target id
5584 **/ 5584 **/
5585 static void 5585 static void
5586 mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id) 5586 mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id)
5587 { 5587 {
5588 CONFIGPARMS cfg; 5588 CONFIGPARMS cfg;
5589 ConfigPageHeader_t hdr; 5589 ConfigPageHeader_t hdr;
5590 dma_addr_t dma_handle; 5590 dma_addr_t dma_handle;
5591 pRaidVolumePage0_t buffer = NULL; 5591 pRaidVolumePage0_t buffer = NULL;
5592 int i; 5592 int i;
5593 RaidPhysDiskPage0_t phys_disk; 5593 RaidPhysDiskPage0_t phys_disk;
5594 struct inactive_raid_component_info *component_info; 5594 struct inactive_raid_component_info *component_info;
5595 int handle_inactive_volumes; 5595 int handle_inactive_volumes;
5596 5596
5597 memset(&cfg, 0 , sizeof(CONFIGPARMS)); 5597 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5598 memset(&hdr, 0 , sizeof(ConfigPageHeader_t)); 5598 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5599 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME; 5599 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
5600 cfg.pageAddr = (channel << 8) + id; 5600 cfg.pageAddr = (channel << 8) + id;
5601 cfg.cfghdr.hdr = &hdr; 5601 cfg.cfghdr.hdr = &hdr;
5602 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 5602 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5603 5603
5604 if (mpt_config(ioc, &cfg) != 0) 5604 if (mpt_config(ioc, &cfg) != 0)
5605 goto out; 5605 goto out;
5606 5606
5607 if (!hdr.PageLength) 5607 if (!hdr.PageLength)
5608 goto out; 5608 goto out;
5609 5609
5610 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, 5610 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5611 &dma_handle); 5611 &dma_handle);
5612 5612
5613 if (!buffer) 5613 if (!buffer)
5614 goto out; 5614 goto out;
5615 5615
5616 cfg.physAddr = dma_handle; 5616 cfg.physAddr = dma_handle;
5617 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 5617 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5618 5618
5619 if (mpt_config(ioc, &cfg) != 0) 5619 if (mpt_config(ioc, &cfg) != 0)
5620 goto out; 5620 goto out;
5621 5621
5622 if (!buffer->NumPhysDisks) 5622 if (!buffer->NumPhysDisks)
5623 goto out; 5623 goto out;
5624 5624
5625 handle_inactive_volumes = 5625 handle_inactive_volumes =
5626 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE || 5626 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE ||
5627 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED) == 0 || 5627 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED) == 0 ||
5628 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_FAILED || 5628 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_FAILED ||
5629 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_MISSING) ? 1 : 0; 5629 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_MISSING) ? 1 : 0;
5630 5630
5631 if (!handle_inactive_volumes) 5631 if (!handle_inactive_volumes)
5632 goto out; 5632 goto out;
5633 5633
5634 mutex_lock(&ioc->raid_data.inactive_list_mutex); 5634 mutex_lock(&ioc->raid_data.inactive_list_mutex);
5635 for (i = 0; i < buffer->NumPhysDisks; i++) { 5635 for (i = 0; i < buffer->NumPhysDisks; i++) {
5636 if(mpt_raid_phys_disk_pg0(ioc, 5636 if(mpt_raid_phys_disk_pg0(ioc,
5637 buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0) 5637 buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
5638 continue; 5638 continue;
5639 5639
5640 if ((component_info = kmalloc(sizeof (*component_info), 5640 if ((component_info = kmalloc(sizeof (*component_info),
5641 GFP_KERNEL)) == NULL) 5641 GFP_KERNEL)) == NULL)
5642 continue; 5642 continue;
5643 5643
5644 component_info->volumeID = id; 5644 component_info->volumeID = id;
5645 component_info->volumeBus = channel; 5645 component_info->volumeBus = channel;
5646 component_info->d.PhysDiskNum = phys_disk.PhysDiskNum; 5646 component_info->d.PhysDiskNum = phys_disk.PhysDiskNum;
5647 component_info->d.PhysDiskBus = phys_disk.PhysDiskBus; 5647 component_info->d.PhysDiskBus = phys_disk.PhysDiskBus;
5648 component_info->d.PhysDiskID = phys_disk.PhysDiskID; 5648 component_info->d.PhysDiskID = phys_disk.PhysDiskID;
5649 component_info->d.PhysDiskIOC = phys_disk.PhysDiskIOC; 5649 component_info->d.PhysDiskIOC = phys_disk.PhysDiskIOC;
5650 5650
5651 list_add_tail(&component_info->list, 5651 list_add_tail(&component_info->list,
5652 &ioc->raid_data.inactive_list); 5652 &ioc->raid_data.inactive_list);
5653 } 5653 }
5654 mutex_unlock(&ioc->raid_data.inactive_list_mutex); 5654 mutex_unlock(&ioc->raid_data.inactive_list_mutex);
5655 5655
5656 out: 5656 out:
5657 if (buffer) 5657 if (buffer)
5658 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer, 5658 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5659 dma_handle); 5659 dma_handle);
5660 } 5660 }
5661 5661
5662 /** 5662 /**
5663 * mpt_raid_phys_disk_pg0 - returns phys disk page zero 5663 * mpt_raid_phys_disk_pg0 - returns phys disk page zero
5664 * @ioc: Pointer to a Adapter Structure 5664 * @ioc: Pointer to a Adapter Structure
5665 * @phys_disk_num: io unit unique phys disk num generated by the ioc 5665 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5666 * @phys_disk: requested payload data returned 5666 * @phys_disk: requested payload data returned
5667 * 5667 *
5668 * Return: 5668 * Return:
5669 * 0 on success 5669 * 0 on success
5670 * -EFAULT if read of config page header fails or data pointer not NULL 5670 * -EFAULT if read of config page header fails or data pointer not NULL
5671 * -ENOMEM if pci_alloc failed 5671 * -ENOMEM if pci_alloc failed
5672 **/ 5672 **/
5673 int 5673 int
5674 mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num, 5674 mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num,
5675 RaidPhysDiskPage0_t *phys_disk) 5675 RaidPhysDiskPage0_t *phys_disk)
5676 { 5676 {
5677 CONFIGPARMS cfg; 5677 CONFIGPARMS cfg;
5678 ConfigPageHeader_t hdr; 5678 ConfigPageHeader_t hdr;
5679 dma_addr_t dma_handle; 5679 dma_addr_t dma_handle;
5680 pRaidPhysDiskPage0_t buffer = NULL; 5680 pRaidPhysDiskPage0_t buffer = NULL;
5681 int rc; 5681 int rc;
5682 5682
5683 memset(&cfg, 0 , sizeof(CONFIGPARMS)); 5683 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5684 memset(&hdr, 0 , sizeof(ConfigPageHeader_t)); 5684 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5685 memset(phys_disk, 0, sizeof(RaidPhysDiskPage0_t)); 5685 memset(phys_disk, 0, sizeof(RaidPhysDiskPage0_t));
5686 5686
5687 hdr.PageVersion = MPI_RAIDPHYSDISKPAGE0_PAGEVERSION; 5687 hdr.PageVersion = MPI_RAIDPHYSDISKPAGE0_PAGEVERSION;
5688 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK; 5688 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5689 cfg.cfghdr.hdr = &hdr; 5689 cfg.cfghdr.hdr = &hdr;
5690 cfg.physAddr = -1; 5690 cfg.physAddr = -1;
5691 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 5691 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5692 5692
5693 if (mpt_config(ioc, &cfg) != 0) { 5693 if (mpt_config(ioc, &cfg) != 0) {
5694 rc = -EFAULT; 5694 rc = -EFAULT;
5695 goto out; 5695 goto out;
5696 } 5696 }
5697 5697
5698 if (!hdr.PageLength) { 5698 if (!hdr.PageLength) {
5699 rc = -EFAULT; 5699 rc = -EFAULT;
5700 goto out; 5700 goto out;
5701 } 5701 }
5702 5702
5703 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, 5703 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5704 &dma_handle); 5704 &dma_handle);
5705 5705
5706 if (!buffer) { 5706 if (!buffer) {
5707 rc = -ENOMEM; 5707 rc = -ENOMEM;
5708 goto out; 5708 goto out;
5709 } 5709 }
5710 5710
5711 cfg.physAddr = dma_handle; 5711 cfg.physAddr = dma_handle;
5712 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 5712 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5713 cfg.pageAddr = phys_disk_num; 5713 cfg.pageAddr = phys_disk_num;
5714 5714
5715 if (mpt_config(ioc, &cfg) != 0) { 5715 if (mpt_config(ioc, &cfg) != 0) {
5716 rc = -EFAULT; 5716 rc = -EFAULT;
5717 goto out; 5717 goto out;
5718 } 5718 }
5719 5719
5720 rc = 0; 5720 rc = 0;
5721 memcpy(phys_disk, buffer, sizeof(*buffer)); 5721 memcpy(phys_disk, buffer, sizeof(*buffer));
5722 phys_disk->MaxLBA = le32_to_cpu(buffer->MaxLBA); 5722 phys_disk->MaxLBA = le32_to_cpu(buffer->MaxLBA);
5723 5723
5724 out: 5724 out:
5725 5725
5726 if (buffer) 5726 if (buffer)
5727 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer, 5727 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5728 dma_handle); 5728 dma_handle);
5729 5729
5730 return rc; 5730 return rc;
5731 } 5731 }
5732 5732
5733 /** 5733 /**
5734 * mpt_raid_phys_disk_get_num_paths - returns number paths associated to this phys_num 5734 * mpt_raid_phys_disk_get_num_paths - returns number paths associated to this phys_num
5735 * @ioc: Pointer to a Adapter Structure 5735 * @ioc: Pointer to a Adapter Structure
5736 * @phys_disk_num: io unit unique phys disk num generated by the ioc 5736 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5737 * 5737 *
5738 * Return: 5738 * Return:
5739 * returns number paths 5739 * returns number paths
5740 **/ 5740 **/
5741 int 5741 int
5742 mpt_raid_phys_disk_get_num_paths(MPT_ADAPTER *ioc, u8 phys_disk_num) 5742 mpt_raid_phys_disk_get_num_paths(MPT_ADAPTER *ioc, u8 phys_disk_num)
5743 { 5743 {
5744 CONFIGPARMS cfg; 5744 CONFIGPARMS cfg;
5745 ConfigPageHeader_t hdr; 5745 ConfigPageHeader_t hdr;
5746 dma_addr_t dma_handle; 5746 dma_addr_t dma_handle;
5747 pRaidPhysDiskPage1_t buffer = NULL; 5747 pRaidPhysDiskPage1_t buffer = NULL;
5748 int rc; 5748 int rc;
5749 5749
5750 memset(&cfg, 0 , sizeof(CONFIGPARMS)); 5750 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5751 memset(&hdr, 0 , sizeof(ConfigPageHeader_t)); 5751 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5752 5752
5753 hdr.PageVersion = MPI_RAIDPHYSDISKPAGE1_PAGEVERSION; 5753 hdr.PageVersion = MPI_RAIDPHYSDISKPAGE1_PAGEVERSION;
5754 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK; 5754 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5755 hdr.PageNumber = 1; 5755 hdr.PageNumber = 1;
5756 cfg.cfghdr.hdr = &hdr; 5756 cfg.cfghdr.hdr = &hdr;
5757 cfg.physAddr = -1; 5757 cfg.physAddr = -1;
5758 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 5758 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5759 5759
5760 if (mpt_config(ioc, &cfg) != 0) { 5760 if (mpt_config(ioc, &cfg) != 0) {
5761 rc = 0; 5761 rc = 0;
5762 goto out; 5762 goto out;
5763 } 5763 }
5764 5764
5765 if (!hdr.PageLength) { 5765 if (!hdr.PageLength) {
5766 rc = 0; 5766 rc = 0;
5767 goto out; 5767 goto out;
5768 } 5768 }
5769 5769
5770 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, 5770 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5771 &dma_handle); 5771 &dma_handle);
5772 5772
5773 if (!buffer) { 5773 if (!buffer) {
5774 rc = 0; 5774 rc = 0;
5775 goto out; 5775 goto out;
5776 } 5776 }
5777 5777
5778 cfg.physAddr = dma_handle; 5778 cfg.physAddr = dma_handle;
5779 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 5779 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5780 cfg.pageAddr = phys_disk_num; 5780 cfg.pageAddr = phys_disk_num;
5781 5781
5782 if (mpt_config(ioc, &cfg) != 0) { 5782 if (mpt_config(ioc, &cfg) != 0) {
5783 rc = 0; 5783 rc = 0;
5784 goto out; 5784 goto out;
5785 } 5785 }
5786 5786
5787 rc = buffer->NumPhysDiskPaths; 5787 rc = buffer->NumPhysDiskPaths;
5788 out: 5788 out:
5789 5789
5790 if (buffer) 5790 if (buffer)
5791 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer, 5791 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5792 dma_handle); 5792 dma_handle);
5793 5793
5794 return rc; 5794 return rc;
5795 } 5795 }
5796 EXPORT_SYMBOL(mpt_raid_phys_disk_get_num_paths); 5796 EXPORT_SYMBOL(mpt_raid_phys_disk_get_num_paths);
5797 5797
5798 /** 5798 /**
5799 * mpt_raid_phys_disk_pg1 - returns phys disk page 1 5799 * mpt_raid_phys_disk_pg1 - returns phys disk page 1
5800 * @ioc: Pointer to a Adapter Structure 5800 * @ioc: Pointer to a Adapter Structure
5801 * @phys_disk_num: io unit unique phys disk num generated by the ioc 5801 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5802 * @phys_disk: requested payload data returned 5802 * @phys_disk: requested payload data returned
5803 * 5803 *
5804 * Return: 5804 * Return:
5805 * 0 on success 5805 * 0 on success
5806 * -EFAULT if read of config page header fails or data pointer not NULL 5806 * -EFAULT if read of config page header fails or data pointer not NULL
5807 * -ENOMEM if pci_alloc failed 5807 * -ENOMEM if pci_alloc failed
5808 **/ 5808 **/
5809 int 5809 int
5810 mpt_raid_phys_disk_pg1(MPT_ADAPTER *ioc, u8 phys_disk_num, 5810 mpt_raid_phys_disk_pg1(MPT_ADAPTER *ioc, u8 phys_disk_num,
5811 RaidPhysDiskPage1_t *phys_disk) 5811 RaidPhysDiskPage1_t *phys_disk)
5812 { 5812 {
5813 CONFIGPARMS cfg; 5813 CONFIGPARMS cfg;
5814 ConfigPageHeader_t hdr; 5814 ConfigPageHeader_t hdr;
5815 dma_addr_t dma_handle; 5815 dma_addr_t dma_handle;
5816 pRaidPhysDiskPage1_t buffer = NULL; 5816 pRaidPhysDiskPage1_t buffer = NULL;
5817 int rc; 5817 int rc;
5818 int i; 5818 int i;
5819 __le64 sas_address; 5819 __le64 sas_address;
5820 5820
5821 memset(&cfg, 0 , sizeof(CONFIGPARMS)); 5821 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5822 memset(&hdr, 0 , sizeof(ConfigPageHeader_t)); 5822 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5823 rc = 0; 5823 rc = 0;
5824 5824
5825 hdr.PageVersion = MPI_RAIDPHYSDISKPAGE1_PAGEVERSION; 5825 hdr.PageVersion = MPI_RAIDPHYSDISKPAGE1_PAGEVERSION;
5826 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK; 5826 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5827 hdr.PageNumber = 1; 5827 hdr.PageNumber = 1;
5828 cfg.cfghdr.hdr = &hdr; 5828 cfg.cfghdr.hdr = &hdr;
5829 cfg.physAddr = -1; 5829 cfg.physAddr = -1;
5830 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 5830 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5831 5831
5832 if (mpt_config(ioc, &cfg) != 0) { 5832 if (mpt_config(ioc, &cfg) != 0) {
5833 rc = -EFAULT; 5833 rc = -EFAULT;
5834 goto out; 5834 goto out;
5835 } 5835 }
5836 5836
5837 if (!hdr.PageLength) { 5837 if (!hdr.PageLength) {
5838 rc = -EFAULT; 5838 rc = -EFAULT;
5839 goto out; 5839 goto out;
5840 } 5840 }
5841 5841
5842 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, 5842 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5843 &dma_handle); 5843 &dma_handle);
5844 5844
5845 if (!buffer) { 5845 if (!buffer) {
5846 rc = -ENOMEM; 5846 rc = -ENOMEM;
5847 goto out; 5847 goto out;
5848 } 5848 }
5849 5849
5850 cfg.physAddr = dma_handle; 5850 cfg.physAddr = dma_handle;
5851 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 5851 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5852 cfg.pageAddr = phys_disk_num; 5852 cfg.pageAddr = phys_disk_num;
5853 5853
5854 if (mpt_config(ioc, &cfg) != 0) { 5854 if (mpt_config(ioc, &cfg) != 0) {
5855 rc = -EFAULT; 5855 rc = -EFAULT;
5856 goto out; 5856 goto out;
5857 } 5857 }
5858 5858
5859 phys_disk->NumPhysDiskPaths = buffer->NumPhysDiskPaths; 5859 phys_disk->NumPhysDiskPaths = buffer->NumPhysDiskPaths;
5860 phys_disk->PhysDiskNum = phys_disk_num; 5860 phys_disk->PhysDiskNum = phys_disk_num;
5861 for (i = 0; i < phys_disk->NumPhysDiskPaths; i++) { 5861 for (i = 0; i < phys_disk->NumPhysDiskPaths; i++) {
5862 phys_disk->Path[i].PhysDiskID = buffer->Path[i].PhysDiskID; 5862 phys_disk->Path[i].PhysDiskID = buffer->Path[i].PhysDiskID;
5863 phys_disk->Path[i].PhysDiskBus = buffer->Path[i].PhysDiskBus; 5863 phys_disk->Path[i].PhysDiskBus = buffer->Path[i].PhysDiskBus;
5864 phys_disk->Path[i].OwnerIdentifier = 5864 phys_disk->Path[i].OwnerIdentifier =
5865 buffer->Path[i].OwnerIdentifier; 5865 buffer->Path[i].OwnerIdentifier;
5866 phys_disk->Path[i].Flags = le16_to_cpu(buffer->Path[i].Flags); 5866 phys_disk->Path[i].Flags = le16_to_cpu(buffer->Path[i].Flags);
5867 memcpy(&sas_address, &buffer->Path[i].WWID, sizeof(__le64)); 5867 memcpy(&sas_address, &buffer->Path[i].WWID, sizeof(__le64));
5868 sas_address = le64_to_cpu(sas_address); 5868 sas_address = le64_to_cpu(sas_address);
5869 memcpy(&phys_disk->Path[i].WWID, &sas_address, sizeof(__le64)); 5869 memcpy(&phys_disk->Path[i].WWID, &sas_address, sizeof(__le64));
5870 memcpy(&sas_address, 5870 memcpy(&sas_address,
5871 &buffer->Path[i].OwnerWWID, sizeof(__le64)); 5871 &buffer->Path[i].OwnerWWID, sizeof(__le64));
5872 sas_address = le64_to_cpu(sas_address); 5872 sas_address = le64_to_cpu(sas_address);
5873 memcpy(&phys_disk->Path[i].OwnerWWID, 5873 memcpy(&phys_disk->Path[i].OwnerWWID,
5874 &sas_address, sizeof(__le64)); 5874 &sas_address, sizeof(__le64));
5875 } 5875 }
5876 5876
5877 out: 5877 out:
5878 5878
5879 if (buffer) 5879 if (buffer)
5880 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer, 5880 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5881 dma_handle); 5881 dma_handle);
5882 5882
5883 return rc; 5883 return rc;
5884 } 5884 }
5885 EXPORT_SYMBOL(mpt_raid_phys_disk_pg1); 5885 EXPORT_SYMBOL(mpt_raid_phys_disk_pg1);
5886 5886
5887 5887
5888 /** 5888 /**
5889 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes 5889 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
5890 * @ioc: Pointer to a Adapter Strucutre 5890 * @ioc: Pointer to a Adapter Strucutre
5891 * 5891 *
5892 * Return: 5892 * Return:
5893 * 0 on success 5893 * 0 on success
5894 * -EFAULT if read of config page header fails or data pointer not NULL 5894 * -EFAULT if read of config page header fails or data pointer not NULL
5895 * -ENOMEM if pci_alloc failed 5895 * -ENOMEM if pci_alloc failed
5896 **/ 5896 **/
5897 int 5897 int
5898 mpt_findImVolumes(MPT_ADAPTER *ioc) 5898 mpt_findImVolumes(MPT_ADAPTER *ioc)
5899 { 5899 {
5900 IOCPage2_t *pIoc2; 5900 IOCPage2_t *pIoc2;
5901 u8 *mem; 5901 u8 *mem;
5902 dma_addr_t ioc2_dma; 5902 dma_addr_t ioc2_dma;
5903 CONFIGPARMS cfg; 5903 CONFIGPARMS cfg;
5904 ConfigPageHeader_t header; 5904 ConfigPageHeader_t header;
5905 int rc = 0; 5905 int rc = 0;
5906 int iocpage2sz; 5906 int iocpage2sz;
5907 int i; 5907 int i;
5908 5908
5909 if (!ioc->ir_firmware) 5909 if (!ioc->ir_firmware)
5910 return 0; 5910 return 0;
5911 5911
5912 /* Free the old page 5912 /* Free the old page
5913 */ 5913 */
5914 kfree(ioc->raid_data.pIocPg2); 5914 kfree(ioc->raid_data.pIocPg2);
5915 ioc->raid_data.pIocPg2 = NULL; 5915 ioc->raid_data.pIocPg2 = NULL;
5916 mpt_inactive_raid_list_free(ioc); 5916 mpt_inactive_raid_list_free(ioc);
5917 5917
5918 /* Read IOCP2 header then the page. 5918 /* Read IOCP2 header then the page.
5919 */ 5919 */
5920 header.PageVersion = 0; 5920 header.PageVersion = 0;
5921 header.PageLength = 0; 5921 header.PageLength = 0;
5922 header.PageNumber = 2; 5922 header.PageNumber = 2;
5923 header.PageType = MPI_CONFIG_PAGETYPE_IOC; 5923 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5924 cfg.cfghdr.hdr = &header; 5924 cfg.cfghdr.hdr = &header;
5925 cfg.physAddr = -1; 5925 cfg.physAddr = -1;
5926 cfg.pageAddr = 0; 5926 cfg.pageAddr = 0;
5927 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 5927 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5928 cfg.dir = 0; 5928 cfg.dir = 0;
5929 cfg.timeout = 0; 5929 cfg.timeout = 0;
5930 if (mpt_config(ioc, &cfg) != 0) 5930 if (mpt_config(ioc, &cfg) != 0)
5931 return -EFAULT; 5931 return -EFAULT;
5932 5932
5933 if (header.PageLength == 0) 5933 if (header.PageLength == 0)
5934 return -EFAULT; 5934 return -EFAULT;
5935 5935
5936 iocpage2sz = header.PageLength * 4; 5936 iocpage2sz = header.PageLength * 4;
5937 pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma); 5937 pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma);
5938 if (!pIoc2) 5938 if (!pIoc2)
5939 return -ENOMEM; 5939 return -ENOMEM;
5940 5940
5941 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 5941 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5942 cfg.physAddr = ioc2_dma; 5942 cfg.physAddr = ioc2_dma;
5943 if (mpt_config(ioc, &cfg) != 0) 5943 if (mpt_config(ioc, &cfg) != 0)
5944 goto out; 5944 goto out;
5945 5945
5946 mem = kmalloc(iocpage2sz, GFP_KERNEL); 5946 mem = kmalloc(iocpage2sz, GFP_KERNEL);
5947 if (!mem) 5947 if (!mem)
5948 goto out; 5948 goto out;
5949 5949
5950 memcpy(mem, (u8 *)pIoc2, iocpage2sz); 5950 memcpy(mem, (u8 *)pIoc2, iocpage2sz);
5951 ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem; 5951 ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
5952 5952
5953 mpt_read_ioc_pg_3(ioc); 5953 mpt_read_ioc_pg_3(ioc);
5954 5954
5955 for (i = 0; i < pIoc2->NumActiveVolumes ; i++) 5955 for (i = 0; i < pIoc2->NumActiveVolumes ; i++)
5956 mpt_inactive_raid_volumes(ioc, 5956 mpt_inactive_raid_volumes(ioc,
5957 pIoc2->RaidVolume[i].VolumeBus, 5957 pIoc2->RaidVolume[i].VolumeBus,
5958 pIoc2->RaidVolume[i].VolumeID); 5958 pIoc2->RaidVolume[i].VolumeID);
5959 5959
5960 out: 5960 out:
5961 pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma); 5961 pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
5962 5962
5963 return rc; 5963 return rc;
5964 } 5964 }
5965 5965
5966 static int 5966 static int
5967 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc) 5967 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
5968 { 5968 {
5969 IOCPage3_t *pIoc3; 5969 IOCPage3_t *pIoc3;
5970 u8 *mem; 5970 u8 *mem;
5971 CONFIGPARMS cfg; 5971 CONFIGPARMS cfg;
5972 ConfigPageHeader_t header; 5972 ConfigPageHeader_t header;
5973 dma_addr_t ioc3_dma; 5973 dma_addr_t ioc3_dma;
5974 int iocpage3sz = 0; 5974 int iocpage3sz = 0;
5975 5975
5976 /* Free the old page 5976 /* Free the old page
5977 */ 5977 */
5978 kfree(ioc->raid_data.pIocPg3); 5978 kfree(ioc->raid_data.pIocPg3);
5979 ioc->raid_data.pIocPg3 = NULL; 5979 ioc->raid_data.pIocPg3 = NULL;
5980 5980
5981 /* There is at least one physical disk. 5981 /* There is at least one physical disk.
5982 * Read and save IOC Page 3 5982 * Read and save IOC Page 3
5983 */ 5983 */
5984 header.PageVersion = 0; 5984 header.PageVersion = 0;
5985 header.PageLength = 0; 5985 header.PageLength = 0;
5986 header.PageNumber = 3; 5986 header.PageNumber = 3;
5987 header.PageType = MPI_CONFIG_PAGETYPE_IOC; 5987 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5988 cfg.cfghdr.hdr = &header; 5988 cfg.cfghdr.hdr = &header;
5989 cfg.physAddr = -1; 5989 cfg.physAddr = -1;
5990 cfg.pageAddr = 0; 5990 cfg.pageAddr = 0;
5991 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 5991 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5992 cfg.dir = 0; 5992 cfg.dir = 0;
5993 cfg.timeout = 0; 5993 cfg.timeout = 0;
5994 if (mpt_config(ioc, &cfg) != 0) 5994 if (mpt_config(ioc, &cfg) != 0)
5995 return 0; 5995 return 0;
5996 5996
5997 if (header.PageLength == 0) 5997 if (header.PageLength == 0)
5998 return 0; 5998 return 0;
5999 5999
6000 /* Read Header good, alloc memory 6000 /* Read Header good, alloc memory
6001 */ 6001 */
6002 iocpage3sz = header.PageLength * 4; 6002 iocpage3sz = header.PageLength * 4;
6003 pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma); 6003 pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma);
6004 if (!pIoc3) 6004 if (!pIoc3)
6005 return 0; 6005 return 0;
6006 6006
6007 /* Read the Page and save the data 6007 /* Read the Page and save the data
6008 * into malloc'd memory. 6008 * into malloc'd memory.
6009 */ 6009 */
6010 cfg.physAddr = ioc3_dma; 6010 cfg.physAddr = ioc3_dma;
6011 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 6011 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
6012 if (mpt_config(ioc, &cfg) == 0) { 6012 if (mpt_config(ioc, &cfg) == 0) {
6013 mem = kmalloc(iocpage3sz, GFP_KERNEL); 6013 mem = kmalloc(iocpage3sz, GFP_KERNEL);
6014 if (mem) { 6014 if (mem) {
6015 memcpy(mem, (u8 *)pIoc3, iocpage3sz); 6015 memcpy(mem, (u8 *)pIoc3, iocpage3sz);
6016 ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem; 6016 ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem;
6017 } 6017 }
6018 } 6018 }
6019 6019
6020 pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma); 6020 pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
6021 6021
6022 return 0; 6022 return 0;
6023 } 6023 }
6024 6024
6025 static void 6025 static void
6026 mpt_read_ioc_pg_4(MPT_ADAPTER *ioc) 6026 mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
6027 { 6027 {
6028 IOCPage4_t *pIoc4; 6028 IOCPage4_t *pIoc4;
6029 CONFIGPARMS cfg; 6029 CONFIGPARMS cfg;
6030 ConfigPageHeader_t header; 6030 ConfigPageHeader_t header;
6031 dma_addr_t ioc4_dma; 6031 dma_addr_t ioc4_dma;
6032 int iocpage4sz; 6032 int iocpage4sz;
6033 6033
6034 /* Read and save IOC Page 4 6034 /* Read and save IOC Page 4
6035 */ 6035 */
6036 header.PageVersion = 0; 6036 header.PageVersion = 0;
6037 header.PageLength = 0; 6037 header.PageLength = 0;
6038 header.PageNumber = 4; 6038 header.PageNumber = 4;
6039 header.PageType = MPI_CONFIG_PAGETYPE_IOC; 6039 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
6040 cfg.cfghdr.hdr = &header; 6040 cfg.cfghdr.hdr = &header;
6041 cfg.physAddr = -1; 6041 cfg.physAddr = -1;
6042 cfg.pageAddr = 0; 6042 cfg.pageAddr = 0;
6043 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 6043 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
6044 cfg.dir = 0; 6044 cfg.dir = 0;
6045 cfg.timeout = 0; 6045 cfg.timeout = 0;
6046 if (mpt_config(ioc, &cfg) != 0) 6046 if (mpt_config(ioc, &cfg) != 0)
6047 return; 6047 return;
6048 6048
6049 if (header.PageLength == 0) 6049 if (header.PageLength == 0)
6050 return; 6050 return;
6051 6051
6052 if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) { 6052 if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
6053 iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */ 6053 iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */
6054 pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma); 6054 pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
6055 if (!pIoc4) 6055 if (!pIoc4)
6056 return; 6056 return;
6057 ioc->alloc_total += iocpage4sz; 6057 ioc->alloc_total += iocpage4sz;
6058 } else { 6058 } else {
6059 ioc4_dma = ioc->spi_data.IocPg4_dma; 6059 ioc4_dma = ioc->spi_data.IocPg4_dma;
6060 iocpage4sz = ioc->spi_data.IocPg4Sz; 6060 iocpage4sz = ioc->spi_data.IocPg4Sz;
6061 } 6061 }
6062 6062
6063 /* Read the Page into dma memory. 6063 /* Read the Page into dma memory.
6064 */ 6064 */
6065 cfg.physAddr = ioc4_dma; 6065 cfg.physAddr = ioc4_dma;
6066 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 6066 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
6067 if (mpt_config(ioc, &cfg) == 0) { 6067 if (mpt_config(ioc, &cfg) == 0) {
6068 ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4; 6068 ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4;
6069 ioc->spi_data.IocPg4_dma = ioc4_dma; 6069 ioc->spi_data.IocPg4_dma = ioc4_dma;
6070 ioc->spi_data.IocPg4Sz = iocpage4sz; 6070 ioc->spi_data.IocPg4Sz = iocpage4sz;
6071 } else { 6071 } else {
6072 pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma); 6072 pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
6073 ioc->spi_data.pIocPg4 = NULL; 6073 ioc->spi_data.pIocPg4 = NULL;
6074 ioc->alloc_total -= iocpage4sz; 6074 ioc->alloc_total -= iocpage4sz;
6075 } 6075 }
6076 } 6076 }
6077 6077
6078 static void 6078 static void
6079 mpt_read_ioc_pg_1(MPT_ADAPTER *ioc) 6079 mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
6080 { 6080 {
6081 IOCPage1_t *pIoc1; 6081 IOCPage1_t *pIoc1;
6082 CONFIGPARMS cfg; 6082 CONFIGPARMS cfg;
6083 ConfigPageHeader_t header; 6083 ConfigPageHeader_t header;
6084 dma_addr_t ioc1_dma; 6084 dma_addr_t ioc1_dma;
6085 int iocpage1sz = 0; 6085 int iocpage1sz = 0;
6086 u32 tmp; 6086 u32 tmp;
6087 6087
6088 /* Check the Coalescing Timeout in IOC Page 1 6088 /* Check the Coalescing Timeout in IOC Page 1
6089 */ 6089 */
6090 header.PageVersion = 0; 6090 header.PageVersion = 0;
6091 header.PageLength = 0; 6091 header.PageLength = 0;
6092 header.PageNumber = 1; 6092 header.PageNumber = 1;
6093 header.PageType = MPI_CONFIG_PAGETYPE_IOC; 6093 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
6094 cfg.cfghdr.hdr = &header; 6094 cfg.cfghdr.hdr = &header;
6095 cfg.physAddr = -1; 6095 cfg.physAddr = -1;
6096 cfg.pageAddr = 0; 6096 cfg.pageAddr = 0;
6097 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 6097 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
6098 cfg.dir = 0; 6098 cfg.dir = 0;
6099 cfg.timeout = 0; 6099 cfg.timeout = 0;
6100 if (mpt_config(ioc, &cfg) != 0) 6100 if (mpt_config(ioc, &cfg) != 0)
6101 return; 6101 return;
6102 6102
6103 if (header.PageLength == 0) 6103 if (header.PageLength == 0)
6104 return; 6104 return;
6105 6105
6106 /* Read Header good, alloc memory 6106 /* Read Header good, alloc memory
6107 */ 6107 */
6108 iocpage1sz = header.PageLength * 4; 6108 iocpage1sz = header.PageLength * 4;
6109 pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma); 6109 pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma);
6110 if (!pIoc1) 6110 if (!pIoc1)
6111 return; 6111 return;
6112 6112
6113 /* Read the Page and check coalescing timeout 6113 /* Read the Page and check coalescing timeout
6114 */ 6114 */
6115 cfg.physAddr = ioc1_dma; 6115 cfg.physAddr = ioc1_dma;
6116 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 6116 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
6117 if (mpt_config(ioc, &cfg) == 0) { 6117 if (mpt_config(ioc, &cfg) == 0) {
6118 6118
6119 tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING; 6119 tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING;
6120 if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) { 6120 if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) {
6121 tmp = le32_to_cpu(pIoc1->CoalescingTimeout); 6121 tmp = le32_to_cpu(pIoc1->CoalescingTimeout);
6122 6122
6123 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Coalescing Enabled Timeout = %d\n", 6123 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Coalescing Enabled Timeout = %d\n",
6124 ioc->name, tmp)); 6124 ioc->name, tmp));
6125 6125
6126 if (tmp > MPT_COALESCING_TIMEOUT) { 6126 if (tmp > MPT_COALESCING_TIMEOUT) {
6127 pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT); 6127 pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT);
6128 6128
6129 /* Write NVRAM and current 6129 /* Write NVRAM and current
6130 */ 6130 */
6131 cfg.dir = 1; 6131 cfg.dir = 1;
6132 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT; 6132 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
6133 if (mpt_config(ioc, &cfg) == 0) { 6133 if (mpt_config(ioc, &cfg) == 0) {
6134 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Reset Current Coalescing Timeout to = %d\n", 6134 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Reset Current Coalescing Timeout to = %d\n",
6135 ioc->name, MPT_COALESCING_TIMEOUT)); 6135 ioc->name, MPT_COALESCING_TIMEOUT));
6136 6136
6137 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM; 6137 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM;
6138 if (mpt_config(ioc, &cfg) == 0) { 6138 if (mpt_config(ioc, &cfg) == 0) {
6139 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT 6139 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6140 "Reset NVRAM Coalescing Timeout to = %d\n", 6140 "Reset NVRAM Coalescing Timeout to = %d\n",
6141 ioc->name, MPT_COALESCING_TIMEOUT)); 6141 ioc->name, MPT_COALESCING_TIMEOUT));
6142 } else { 6142 } else {
6143 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT 6143 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6144 "Reset NVRAM Coalescing Timeout Failed\n", 6144 "Reset NVRAM Coalescing Timeout Failed\n",
6145 ioc->name)); 6145 ioc->name));
6146 } 6146 }
6147 6147
6148 } else { 6148 } else {
6149 dprintk(ioc, printk(MYIOC_s_WARN_FMT 6149 dprintk(ioc, printk(MYIOC_s_WARN_FMT
6150 "Reset of Current Coalescing Timeout Failed!\n", 6150 "Reset of Current Coalescing Timeout Failed!\n",
6151 ioc->name)); 6151 ioc->name));
6152 } 6152 }
6153 } 6153 }
6154 6154
6155 } else { 6155 } else {
6156 dprintk(ioc, printk(MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name)); 6156 dprintk(ioc, printk(MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name));
6157 } 6157 }
6158 } 6158 }
6159 6159
6160 pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma); 6160 pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
6161 6161
6162 return; 6162 return;
6163 } 6163 }
6164 6164
6165 static void 6165 static void
6166 mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc) 6166 mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc)
6167 { 6167 {
6168 CONFIGPARMS cfg; 6168 CONFIGPARMS cfg;
6169 ConfigPageHeader_t hdr; 6169 ConfigPageHeader_t hdr;
6170 dma_addr_t buf_dma; 6170 dma_addr_t buf_dma;
6171 ManufacturingPage0_t *pbuf = NULL; 6171 ManufacturingPage0_t *pbuf = NULL;
6172 6172
6173 memset(&cfg, 0 , sizeof(CONFIGPARMS)); 6173 memset(&cfg, 0 , sizeof(CONFIGPARMS));
6174 memset(&hdr, 0 , sizeof(ConfigPageHeader_t)); 6174 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
6175 6175
6176 hdr.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING; 6176 hdr.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING;
6177 cfg.cfghdr.hdr = &hdr; 6177 cfg.cfghdr.hdr = &hdr;
6178 cfg.physAddr = -1; 6178 cfg.physAddr = -1;
6179 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 6179 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
6180 cfg.timeout = 10; 6180 cfg.timeout = 10;
6181 6181
6182 if (mpt_config(ioc, &cfg) != 0) 6182 if (mpt_config(ioc, &cfg) != 0)
6183 goto out; 6183 goto out;
6184 6184
6185 if (!cfg.cfghdr.hdr->PageLength) 6185 if (!cfg.cfghdr.hdr->PageLength)
6186 goto out; 6186 goto out;
6187 6187
6188 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 6188 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
6189 pbuf = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, &buf_dma); 6189 pbuf = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, &buf_dma);
6190 if (!pbuf) 6190 if (!pbuf)
6191 goto out; 6191 goto out;
6192 6192
6193 cfg.physAddr = buf_dma; 6193 cfg.physAddr = buf_dma;
6194 6194
6195 if (mpt_config(ioc, &cfg) != 0) 6195 if (mpt_config(ioc, &cfg) != 0)
6196 goto out; 6196 goto out;
6197 6197
6198 memcpy(ioc->board_name, pbuf->BoardName, sizeof(ioc->board_name)); 6198 memcpy(ioc->board_name, pbuf->BoardName, sizeof(ioc->board_name));
6199 memcpy(ioc->board_assembly, pbuf->BoardAssembly, sizeof(ioc->board_assembly)); 6199 memcpy(ioc->board_assembly, pbuf->BoardAssembly, sizeof(ioc->board_assembly));
6200 memcpy(ioc->board_tracer, pbuf->BoardTracerNumber, sizeof(ioc->board_tracer)); 6200 memcpy(ioc->board_tracer, pbuf->BoardTracerNumber, sizeof(ioc->board_tracer));
6201 6201
6202 out: 6202 out:
6203 6203
6204 if (pbuf) 6204 if (pbuf)
6205 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma); 6205 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma);
6206 } 6206 }
6207 6207
6208 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 6208 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6209 /** 6209 /**
6210 * SendEventNotification - Send EventNotification (on or off) request to adapter 6210 * SendEventNotification - Send EventNotification (on or off) request to adapter
6211 * @ioc: Pointer to MPT_ADAPTER structure 6211 * @ioc: Pointer to MPT_ADAPTER structure
6212 * @EvSwitch: Event switch flags 6212 * @EvSwitch: Event switch flags
6213 * @sleepFlag: Specifies whether the process can sleep 6213 * @sleepFlag: Specifies whether the process can sleep
6214 */ 6214 */
6215 static int 6215 static int
6216 SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch, int sleepFlag) 6216 SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch, int sleepFlag)
6217 { 6217 {
6218 EventNotification_t evn; 6218 EventNotification_t evn;
6219 MPIDefaultReply_t reply_buf; 6219 MPIDefaultReply_t reply_buf;
6220 6220
6221 memset(&evn, 0, sizeof(EventNotification_t)); 6221 memset(&evn, 0, sizeof(EventNotification_t));
6222 memset(&reply_buf, 0, sizeof(MPIDefaultReply_t)); 6222 memset(&reply_buf, 0, sizeof(MPIDefaultReply_t));
6223 6223
6224 evn.Function = MPI_FUNCTION_EVENT_NOTIFICATION; 6224 evn.Function = MPI_FUNCTION_EVENT_NOTIFICATION;
6225 evn.Switch = EvSwitch; 6225 evn.Switch = EvSwitch;
6226 evn.MsgContext = cpu_to_le32(mpt_base_index << 16); 6226 evn.MsgContext = cpu_to_le32(mpt_base_index << 16);
6227 6227
6228 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT 6228 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6229 "Sending EventNotification (%d) request %p\n", 6229 "Sending EventNotification (%d) request %p\n",
6230 ioc->name, EvSwitch, &evn)); 6230 ioc->name, EvSwitch, &evn));
6231 6231
6232 return mpt_handshake_req_reply_wait(ioc, sizeof(EventNotification_t), 6232 return mpt_handshake_req_reply_wait(ioc, sizeof(EventNotification_t),
6233 (u32 *)&evn, sizeof(MPIDefaultReply_t), (u16 *)&reply_buf, 30, 6233 (u32 *)&evn, sizeof(MPIDefaultReply_t), (u16 *)&reply_buf, 30,
6234 sleepFlag); 6234 sleepFlag);
6235 } 6235 }
6236 6236
6237 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 6237 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6238 /** 6238 /**
6239 * SendEventAck - Send EventAck request to MPT adapter. 6239 * SendEventAck - Send EventAck request to MPT adapter.
6240 * @ioc: Pointer to MPT_ADAPTER structure 6240 * @ioc: Pointer to MPT_ADAPTER structure
6241 * @evnp: Pointer to original EventNotification request 6241 * @evnp: Pointer to original EventNotification request
6242 */ 6242 */
6243 static int 6243 static int
6244 SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp) 6244 SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
6245 { 6245 {
6246 EventAck_t *pAck; 6246 EventAck_t *pAck;
6247 6247
6248 if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) { 6248 if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
6249 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames!!\n", 6249 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames!!\n",
6250 ioc->name, __func__)); 6250 ioc->name, __func__));
6251 return -1; 6251 return -1;
6252 } 6252 }
6253 6253
6254 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending EventAck\n", ioc->name)); 6254 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending EventAck\n", ioc->name));
6255 6255
6256 pAck->Function = MPI_FUNCTION_EVENT_ACK; 6256 pAck->Function = MPI_FUNCTION_EVENT_ACK;
6257 pAck->ChainOffset = 0; 6257 pAck->ChainOffset = 0;
6258 pAck->Reserved[0] = pAck->Reserved[1] = 0; 6258 pAck->Reserved[0] = pAck->Reserved[1] = 0;
6259 pAck->MsgFlags = 0; 6259 pAck->MsgFlags = 0;
6260 pAck->Reserved1[0] = pAck->Reserved1[1] = pAck->Reserved1[2] = 0; 6260 pAck->Reserved1[0] = pAck->Reserved1[1] = pAck->Reserved1[2] = 0;
6261 pAck->Event = evnp->Event; 6261 pAck->Event = evnp->Event;
6262 pAck->EventContext = evnp->EventContext; 6262 pAck->EventContext = evnp->EventContext;
6263 6263
6264 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)pAck); 6264 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)pAck);
6265 6265
6266 return 0; 6266 return 0;
6267 } 6267 }
6268 6268
6269 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 6269 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6270 /** 6270 /**
6271 * mpt_config - Generic function to issue config message 6271 * mpt_config - Generic function to issue config message
6272 * @ioc: Pointer to an adapter structure 6272 * @ioc: Pointer to an adapter structure
6273 * @pCfg: Pointer to a configuration structure. Struct contains 6273 * @pCfg: Pointer to a configuration structure. Struct contains
6274 * action, page address, direction, physical address 6274 * action, page address, direction, physical address
6275 * and pointer to a configuration page header 6275 * and pointer to a configuration page header
6276 * Page header is updated. 6276 * Page header is updated.
6277 * 6277 *
6278 * Returns 0 for success 6278 * Returns 0 for success
6279 * -EPERM if not allowed due to ISR context 6279 * -EPERM if not allowed due to ISR context
6280 * -EAGAIN if no msg frames currently available 6280 * -EAGAIN if no msg frames currently available
6281 * -EFAULT for non-successful reply or no reply (timeout) 6281 * -EFAULT for non-successful reply or no reply (timeout)
6282 */ 6282 */
6283 int 6283 int
6284 mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg) 6284 mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
6285 { 6285 {
6286 Config_t *pReq; 6286 Config_t *pReq;
6287 ConfigReply_t *pReply; 6287 ConfigReply_t *pReply;
6288 ConfigExtendedPageHeader_t *pExtHdr = NULL; 6288 ConfigExtendedPageHeader_t *pExtHdr = NULL;
6289 MPT_FRAME_HDR *mf; 6289 MPT_FRAME_HDR *mf;
6290 int ii; 6290 int ii;
6291 int flagsLength; 6291 int flagsLength;
6292 long timeout; 6292 long timeout;
6293 int ret; 6293 int ret;
6294 u8 page_type = 0, extend_page; 6294 u8 page_type = 0, extend_page;
6295 unsigned long timeleft; 6295 unsigned long timeleft;
6296 unsigned long flags; 6296 unsigned long flags;
6297 int in_isr; 6297 int in_isr;
6298 u8 issue_hard_reset = 0; 6298 u8 issue_hard_reset = 0;
6299 u8 retry_count = 0; 6299 u8 retry_count = 0;
6300 6300
6301 /* Prevent calling wait_event() (below), if caller happens 6301 /* Prevent calling wait_event() (below), if caller happens
6302 * to be in ISR context, because that is fatal! 6302 * to be in ISR context, because that is fatal!
6303 */ 6303 */
6304 in_isr = in_interrupt(); 6304 in_isr = in_interrupt();
6305 if (in_isr) { 6305 if (in_isr) {
6306 dcprintk(ioc, printk(MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n", 6306 dcprintk(ioc, printk(MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n",
6307 ioc->name)); 6307 ioc->name));
6308 return -EPERM; 6308 return -EPERM;
6309 } 6309 }
6310 6310
6311 /* don't send a config page during diag reset */ 6311 /* don't send a config page during diag reset */
6312 spin_lock_irqsave(&ioc->taskmgmt_lock, flags); 6312 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6313 if (ioc->ioc_reset_in_progress) { 6313 if (ioc->ioc_reset_in_progress) {
6314 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT 6314 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6315 "%s: busy with host reset\n", ioc->name, __func__)); 6315 "%s: busy with host reset\n", ioc->name, __func__));
6316 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags); 6316 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6317 return -EBUSY; 6317 return -EBUSY;
6318 } 6318 }
6319 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags); 6319 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6320 6320
6321 /* don't send if no chance of success */ 6321 /* don't send if no chance of success */
6322 if (!ioc->active || 6322 if (!ioc->active ||
6323 mpt_GetIocState(ioc, 1) != MPI_IOC_STATE_OPERATIONAL) { 6323 mpt_GetIocState(ioc, 1) != MPI_IOC_STATE_OPERATIONAL) {
6324 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT 6324 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6325 "%s: ioc not operational, %d, %xh\n", 6325 "%s: ioc not operational, %d, %xh\n",
6326 ioc->name, __func__, ioc->active, 6326 ioc->name, __func__, ioc->active,
6327 mpt_GetIocState(ioc, 0))); 6327 mpt_GetIocState(ioc, 0)));
6328 return -EFAULT; 6328 return -EFAULT;
6329 } 6329 }
6330 6330
6331 retry_config: 6331 retry_config:
6332 mutex_lock(&ioc->mptbase_cmds.mutex); 6332 mutex_lock(&ioc->mptbase_cmds.mutex);
6333 /* init the internal cmd struct */ 6333 /* init the internal cmd struct */
6334 memset(ioc->mptbase_cmds.reply, 0 , MPT_DEFAULT_FRAME_SIZE); 6334 memset(ioc->mptbase_cmds.reply, 0 , MPT_DEFAULT_FRAME_SIZE);
6335 INITIALIZE_MGMT_STATUS(ioc->mptbase_cmds.status) 6335 INITIALIZE_MGMT_STATUS(ioc->mptbase_cmds.status)
6336 6336
6337 /* Get and Populate a free Frame 6337 /* Get and Populate a free Frame
6338 */ 6338 */
6339 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) { 6339 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
6340 dcprintk(ioc, printk(MYIOC_s_WARN_FMT 6340 dcprintk(ioc, printk(MYIOC_s_WARN_FMT
6341 "mpt_config: no msg frames!\n", ioc->name)); 6341 "mpt_config: no msg frames!\n", ioc->name));
6342 ret = -EAGAIN; 6342 ret = -EAGAIN;
6343 goto out; 6343 goto out;
6344 } 6344 }
6345 6345
6346 pReq = (Config_t *)mf; 6346 pReq = (Config_t *)mf;
6347 pReq->Action = pCfg->action; 6347 pReq->Action = pCfg->action;
6348 pReq->Reserved = 0; 6348 pReq->Reserved = 0;
6349 pReq->ChainOffset = 0; 6349 pReq->ChainOffset = 0;
6350 pReq->Function = MPI_FUNCTION_CONFIG; 6350 pReq->Function = MPI_FUNCTION_CONFIG;
6351 6351
6352 /* Assume page type is not extended and clear "reserved" fields. */ 6352 /* Assume page type is not extended and clear "reserved" fields. */
6353 pReq->ExtPageLength = 0; 6353 pReq->ExtPageLength = 0;
6354 pReq->ExtPageType = 0; 6354 pReq->ExtPageType = 0;
6355 pReq->MsgFlags = 0; 6355 pReq->MsgFlags = 0;
6356 6356
6357 for (ii=0; ii < 8; ii++) 6357 for (ii=0; ii < 8; ii++)
6358 pReq->Reserved2[ii] = 0; 6358 pReq->Reserved2[ii] = 0;
6359 6359
6360 pReq->Header.PageVersion = pCfg->cfghdr.hdr->PageVersion; 6360 pReq->Header.PageVersion = pCfg->cfghdr.hdr->PageVersion;
6361 pReq->Header.PageLength = pCfg->cfghdr.hdr->PageLength; 6361 pReq->Header.PageLength = pCfg->cfghdr.hdr->PageLength;
6362 pReq->Header.PageNumber = pCfg->cfghdr.hdr->PageNumber; 6362 pReq->Header.PageNumber = pCfg->cfghdr.hdr->PageNumber;
6363 pReq->Header.PageType = (pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK); 6363 pReq->Header.PageType = (pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
6364 6364
6365 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) { 6365 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
6366 pExtHdr = (ConfigExtendedPageHeader_t *)pCfg->cfghdr.ehdr; 6366 pExtHdr = (ConfigExtendedPageHeader_t *)pCfg->cfghdr.ehdr;
6367 pReq->ExtPageLength = cpu_to_le16(pExtHdr->ExtPageLength); 6367 pReq->ExtPageLength = cpu_to_le16(pExtHdr->ExtPageLength);
6368 pReq->ExtPageType = pExtHdr->ExtPageType; 6368 pReq->ExtPageType = pExtHdr->ExtPageType;
6369 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED; 6369 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
6370 6370
6371 /* Page Length must be treated as a reserved field for the 6371 /* Page Length must be treated as a reserved field for the
6372 * extended header. 6372 * extended header.
6373 */ 6373 */
6374 pReq->Header.PageLength = 0; 6374 pReq->Header.PageLength = 0;
6375 } 6375 }
6376 6376
6377 pReq->PageAddress = cpu_to_le32(pCfg->pageAddr); 6377 pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
6378 6378
6379 /* Add a SGE to the config request. 6379 /* Add a SGE to the config request.
6380 */ 6380 */
6381 if (pCfg->dir) 6381 if (pCfg->dir)
6382 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE; 6382 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
6383 else 6383 else
6384 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ; 6384 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
6385 6385
6386 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == 6386 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) ==
6387 MPI_CONFIG_PAGETYPE_EXTENDED) { 6387 MPI_CONFIG_PAGETYPE_EXTENDED) {
6388 flagsLength |= pExtHdr->ExtPageLength * 4; 6388 flagsLength |= pExtHdr->ExtPageLength * 4;
6389 page_type = pReq->ExtPageType; 6389 page_type = pReq->ExtPageType;
6390 extend_page = 1; 6390 extend_page = 1;
6391 } else { 6391 } else {
6392 flagsLength |= pCfg->cfghdr.hdr->PageLength * 4; 6392 flagsLength |= pCfg->cfghdr.hdr->PageLength * 4;
6393 page_type = pReq->Header.PageType; 6393 page_type = pReq->Header.PageType;
6394 extend_page = 0; 6394 extend_page = 0;
6395 } 6395 }
6396 6396
6397 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT 6397 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6398 "Sending Config request type 0x%x, page 0x%x and action %d\n", 6398 "Sending Config request type 0x%x, page 0x%x and action %d\n",
6399 ioc->name, page_type, pReq->Header.PageNumber, pReq->Action)); 6399 ioc->name, page_type, pReq->Header.PageNumber, pReq->Action));
6400 6400
6401 ioc->add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr); 6401 ioc->add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
6402 timeout = (pCfg->timeout < 15) ? HZ*15 : HZ*pCfg->timeout; 6402 timeout = (pCfg->timeout < 15) ? HZ*15 : HZ*pCfg->timeout;
6403 mpt_put_msg_frame(mpt_base_index, ioc, mf); 6403 mpt_put_msg_frame(mpt_base_index, ioc, mf);
6404 timeleft = wait_for_completion_timeout(&ioc->mptbase_cmds.done, 6404 timeleft = wait_for_completion_timeout(&ioc->mptbase_cmds.done,
6405 timeout); 6405 timeout);
6406 if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) { 6406 if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
6407 ret = -ETIME; 6407 ret = -ETIME;
6408 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT 6408 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6409 "Failed Sending Config request type 0x%x, page 0x%x," 6409 "Failed Sending Config request type 0x%x, page 0x%x,"
6410 " action %d, status %xh, time left %ld\n\n", 6410 " action %d, status %xh, time left %ld\n\n",
6411 ioc->name, page_type, pReq->Header.PageNumber, 6411 ioc->name, page_type, pReq->Header.PageNumber,
6412 pReq->Action, ioc->mptbase_cmds.status, timeleft)); 6412 pReq->Action, ioc->mptbase_cmds.status, timeleft));
6413 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET) 6413 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
6414 goto out; 6414 goto out;
6415 if (!timeleft) 6415 if (!timeleft)
6416 issue_hard_reset = 1; 6416 issue_hard_reset = 1;
6417 goto out; 6417 goto out;
6418 } 6418 }
6419 6419
6420 if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_RF_VALID)) { 6420 if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
6421 ret = -1; 6421 ret = -1;
6422 goto out; 6422 goto out;
6423 } 6423 }
6424 pReply = (ConfigReply_t *)ioc->mptbase_cmds.reply; 6424 pReply = (ConfigReply_t *)ioc->mptbase_cmds.reply;
6425 ret = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK; 6425 ret = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
6426 if (ret == MPI_IOCSTATUS_SUCCESS) { 6426 if (ret == MPI_IOCSTATUS_SUCCESS) {
6427 if (extend_page) { 6427 if (extend_page) {
6428 pCfg->cfghdr.ehdr->ExtPageLength = 6428 pCfg->cfghdr.ehdr->ExtPageLength =
6429 le16_to_cpu(pReply->ExtPageLength); 6429 le16_to_cpu(pReply->ExtPageLength);
6430 pCfg->cfghdr.ehdr->ExtPageType = 6430 pCfg->cfghdr.ehdr->ExtPageType =
6431 pReply->ExtPageType; 6431 pReply->ExtPageType;
6432 } 6432 }
6433 pCfg->cfghdr.hdr->PageVersion = pReply->Header.PageVersion; 6433 pCfg->cfghdr.hdr->PageVersion = pReply->Header.PageVersion;
6434 pCfg->cfghdr.hdr->PageLength = pReply->Header.PageLength; 6434 pCfg->cfghdr.hdr->PageLength = pReply->Header.PageLength;
6435 pCfg->cfghdr.hdr->PageNumber = pReply->Header.PageNumber; 6435 pCfg->cfghdr.hdr->PageNumber = pReply->Header.PageNumber;
6436 pCfg->cfghdr.hdr->PageType = pReply->Header.PageType; 6436 pCfg->cfghdr.hdr->PageType = pReply->Header.PageType;
6437 6437
6438 } 6438 }
6439 6439
6440 if (retry_count) 6440 if (retry_count)
6441 printk(MYIOC_s_INFO_FMT "Retry completed " 6441 printk(MYIOC_s_INFO_FMT "Retry completed "
6442 "ret=0x%x timeleft=%ld\n", 6442 "ret=0x%x timeleft=%ld\n",
6443 ioc->name, ret, timeleft); 6443 ioc->name, ret, timeleft);
6444 6444
6445 dcprintk(ioc, printk(KERN_DEBUG "IOCStatus=%04xh, IOCLogInfo=%08xh\n", 6445 dcprintk(ioc, printk(KERN_DEBUG "IOCStatus=%04xh, IOCLogInfo=%08xh\n",
6446 ret, le32_to_cpu(pReply->IOCLogInfo))); 6446 ret, le32_to_cpu(pReply->IOCLogInfo)));
6447 6447
6448 out: 6448 out:
6449 6449
6450 CLEAR_MGMT_STATUS(ioc->mptbase_cmds.status) 6450 CLEAR_MGMT_STATUS(ioc->mptbase_cmds.status)
6451 mutex_unlock(&ioc->mptbase_cmds.mutex); 6451 mutex_unlock(&ioc->mptbase_cmds.mutex);
6452 if (issue_hard_reset) { 6452 if (issue_hard_reset) {
6453 issue_hard_reset = 0; 6453 issue_hard_reset = 0;
6454 printk(MYIOC_s_WARN_FMT "Issuing Reset from %s!!\n", 6454 printk(MYIOC_s_WARN_FMT "Issuing Reset from %s!!\n",
6455 ioc->name, __func__); 6455 ioc->name, __func__);
6456 mpt_HardResetHandler(ioc, CAN_SLEEP); 6456 mpt_HardResetHandler(ioc, CAN_SLEEP);
6457 mpt_free_msg_frame(ioc, mf); 6457 mpt_free_msg_frame(ioc, mf);
6458 /* attempt one retry for a timed out command */ 6458 /* attempt one retry for a timed out command */
6459 if (!retry_count) { 6459 if (!retry_count) {
6460 printk(MYIOC_s_INFO_FMT 6460 printk(MYIOC_s_INFO_FMT
6461 "Attempting Retry Config request" 6461 "Attempting Retry Config request"
6462 " type 0x%x, page 0x%x," 6462 " type 0x%x, page 0x%x,"
6463 " action %d\n", ioc->name, page_type, 6463 " action %d\n", ioc->name, page_type,
6464 pCfg->cfghdr.hdr->PageNumber, pCfg->action); 6464 pCfg->cfghdr.hdr->PageNumber, pCfg->action);
6465 retry_count++; 6465 retry_count++;
6466 goto retry_config; 6466 goto retry_config;
6467 } 6467 }
6468 } 6468 }
6469 return ret; 6469 return ret;
6470 6470
6471 } 6471 }
6472 6472
6473 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 6473 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6474 /** 6474 /**
6475 * mpt_ioc_reset - Base cleanup for hard reset 6475 * mpt_ioc_reset - Base cleanup for hard reset
6476 * @ioc: Pointer to the adapter structure 6476 * @ioc: Pointer to the adapter structure
6477 * @reset_phase: Indicates pre- or post-reset functionality 6477 * @reset_phase: Indicates pre- or post-reset functionality
6478 * 6478 *
6479 * Remark: Frees resources with internally generated commands. 6479 * Remark: Frees resources with internally generated commands.
6480 */ 6480 */
6481 static int 6481 static int
6482 mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) 6482 mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
6483 { 6483 {
6484 switch (reset_phase) { 6484 switch (reset_phase) {
6485 case MPT_IOC_SETUP_RESET: 6485 case MPT_IOC_SETUP_RESET:
6486 ioc->taskmgmt_quiesce_io = 1; 6486 ioc->taskmgmt_quiesce_io = 1;
6487 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT 6487 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6488 "%s: MPT_IOC_SETUP_RESET\n", ioc->name, __func__)); 6488 "%s: MPT_IOC_SETUP_RESET\n", ioc->name, __func__));
6489 break; 6489 break;
6490 case MPT_IOC_PRE_RESET: 6490 case MPT_IOC_PRE_RESET:
6491 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT 6491 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6492 "%s: MPT_IOC_PRE_RESET\n", ioc->name, __func__)); 6492 "%s: MPT_IOC_PRE_RESET\n", ioc->name, __func__));
6493 break; 6493 break;
6494 case MPT_IOC_POST_RESET: 6494 case MPT_IOC_POST_RESET:
6495 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT 6495 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6496 "%s: MPT_IOC_POST_RESET\n", ioc->name, __func__)); 6496 "%s: MPT_IOC_POST_RESET\n", ioc->name, __func__));
6497 /* wake up mptbase_cmds */ 6497 /* wake up mptbase_cmds */
6498 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_PENDING) { 6498 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_PENDING) {
6499 ioc->mptbase_cmds.status |= 6499 ioc->mptbase_cmds.status |=
6500 MPT_MGMT_STATUS_DID_IOCRESET; 6500 MPT_MGMT_STATUS_DID_IOCRESET;
6501 complete(&ioc->mptbase_cmds.done); 6501 complete(&ioc->mptbase_cmds.done);
6502 } 6502 }
6503 /* wake up taskmgmt_cmds */ 6503 /* wake up taskmgmt_cmds */
6504 if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_PENDING) { 6504 if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_PENDING) {
6505 ioc->taskmgmt_cmds.status |= 6505 ioc->taskmgmt_cmds.status |=
6506 MPT_MGMT_STATUS_DID_IOCRESET; 6506 MPT_MGMT_STATUS_DID_IOCRESET;
6507 complete(&ioc->taskmgmt_cmds.done); 6507 complete(&ioc->taskmgmt_cmds.done);
6508 } 6508 }
6509 break; 6509 break;
6510 default: 6510 default:
6511 break; 6511 break;
6512 } 6512 }
6513 6513
6514 return 1; /* currently means nothing really */ 6514 return 1; /* currently means nothing really */
6515 } 6515 }
6516 6516
6517 6517
6518 #ifdef CONFIG_PROC_FS /* { */ 6518 #ifdef CONFIG_PROC_FS /* { */
6519 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 6519 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6520 /* 6520 /*
6521 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff... 6521 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
6522 */ 6522 */
6523 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 6523 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6524 /** 6524 /**
6525 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries. 6525 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
6526 * 6526 *
6527 * Returns 0 for success, non-zero for failure. 6527 * Returns 0 for success, non-zero for failure.
6528 */ 6528 */
6529 static int 6529 static int
6530 procmpt_create(void) 6530 procmpt_create(void)
6531 { 6531 {
6532 struct proc_dir_entry *ent; 6532 struct proc_dir_entry *ent;
6533 6533
6534 mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL); 6534 mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
6535 if (mpt_proc_root_dir == NULL) 6535 if (mpt_proc_root_dir == NULL)
6536 return -ENOTDIR; 6536 return -ENOTDIR;
6537 6537
6538 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, mpt_proc_root_dir); 6538 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, mpt_proc_root_dir);
6539 if (ent) 6539 if (ent)
6540 ent->read_proc = procmpt_summary_read; 6540 ent->read_proc = procmpt_summary_read;
6541 6541
6542 ent = create_proc_entry("version", S_IFREG|S_IRUGO, mpt_proc_root_dir); 6542 ent = create_proc_entry("version", S_IFREG|S_IRUGO, mpt_proc_root_dir);
6543 if (ent) 6543 if (ent)
6544 ent->read_proc = procmpt_version_read; 6544 ent->read_proc = procmpt_version_read;
6545 6545
6546 return 0; 6546 return 0;
6547 } 6547 }
6548 6548
6549 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 6549 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6550 /** 6550 /**
6551 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries. 6551 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
6552 * 6552 *
6553 * Returns 0 for success, non-zero for failure. 6553 * Returns 0 for success, non-zero for failure.
6554 */ 6554 */
6555 static void 6555 static void
6556 procmpt_destroy(void) 6556 procmpt_destroy(void)
6557 { 6557 {
6558 remove_proc_entry("version", mpt_proc_root_dir); 6558 remove_proc_entry("version", mpt_proc_root_dir);
6559 remove_proc_entry("summary", mpt_proc_root_dir); 6559 remove_proc_entry("summary", mpt_proc_root_dir);
6560 remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL); 6560 remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
6561 } 6561 }
6562 6562
6563 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 6563 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6564 /** 6564 /**
6565 * procmpt_summary_read - Handle read request of a summary file 6565 * procmpt_summary_read - Handle read request of a summary file
6566 * @buf: Pointer to area to write information 6566 * @buf: Pointer to area to write information
6567 * @start: Pointer to start pointer 6567 * @start: Pointer to start pointer
6568 * @offset: Offset to start writing 6568 * @offset: Offset to start writing
6569 * @request: Amount of read data requested 6569 * @request: Amount of read data requested
6570 * @eof: Pointer to EOF integer 6570 * @eof: Pointer to EOF integer
6571 * @data: Pointer 6571 * @data: Pointer
6572 * 6572 *
6573 * Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary. 6573 * Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary.
6574 * Returns number of characters written to process performing the read. 6574 * Returns number of characters written to process performing the read.
6575 */ 6575 */
6576 static int 6576 static int
6577 procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eof, void *data) 6577 procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
6578 { 6578 {
6579 MPT_ADAPTER *ioc; 6579 MPT_ADAPTER *ioc;
6580 char *out = buf; 6580 char *out = buf;
6581 int len; 6581 int len;
6582 6582
6583 if (data) { 6583 if (data) {
6584 int more = 0; 6584 int more = 0;
6585 6585
6586 ioc = data; 6586 ioc = data;
6587 mpt_print_ioc_summary(ioc, out, &more, 0, 1); 6587 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
6588 6588
6589 out += more; 6589 out += more;
6590 } else { 6590 } else {
6591 list_for_each_entry(ioc, &ioc_list, list) { 6591 list_for_each_entry(ioc, &ioc_list, list) {
6592 int more = 0; 6592 int more = 0;
6593 6593
6594 mpt_print_ioc_summary(ioc, out, &more, 0, 1); 6594 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
6595 6595
6596 out += more; 6596 out += more;
6597 if ((out-buf) >= request) 6597 if ((out-buf) >= request)
6598 break; 6598 break;
6599 } 6599 }
6600 } 6600 }
6601 6601
6602 len = out - buf; 6602 len = out - buf;
6603 6603
6604 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len); 6604 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
6605 } 6605 }
6606 6606
6607 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 6607 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6608 /** 6608 /**
6609 * procmpt_version_read - Handle read request from /proc/mpt/version. 6609 * procmpt_version_read - Handle read request from /proc/mpt/version.
6610 * @buf: Pointer to area to write information 6610 * @buf: Pointer to area to write information
6611 * @start: Pointer to start pointer 6611 * @start: Pointer to start pointer
6612 * @offset: Offset to start writing 6612 * @offset: Offset to start writing
6613 * @request: Amount of read data requested 6613 * @request: Amount of read data requested
6614 * @eof: Pointer to EOF integer 6614 * @eof: Pointer to EOF integer
6615 * @data: Pointer 6615 * @data: Pointer
6616 * 6616 *
6617 * Returns number of characters written to process performing the read. 6617 * Returns number of characters written to process performing the read.
6618 */ 6618 */
6619 static int 6619 static int
6620 procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eof, void *data) 6620 procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
6621 { 6621 {
6622 u8 cb_idx; 6622 u8 cb_idx;
6623 int scsi, fc, sas, lan, ctl, targ, dmp; 6623 int scsi, fc, sas, lan, ctl, targ, dmp;
6624 char *drvname; 6624 char *drvname;
6625 int len; 6625 int len;
6626 6626
6627 len = sprintf(buf, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON); 6627 len = sprintf(buf, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
6628 len += sprintf(buf+len, " Fusion MPT base driver\n"); 6628 len += sprintf(buf+len, " Fusion MPT base driver\n");
6629 6629
6630 scsi = fc = sas = lan = ctl = targ = dmp = 0; 6630 scsi = fc = sas = lan = ctl = targ = dmp = 0;
6631 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) { 6631 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6632 drvname = NULL; 6632 drvname = NULL;
6633 if (MptCallbacks[cb_idx]) { 6633 if (MptCallbacks[cb_idx]) {
6634 switch (MptDriverClass[cb_idx]) { 6634 switch (MptDriverClass[cb_idx]) {
6635 case MPTSPI_DRIVER: 6635 case MPTSPI_DRIVER:
6636 if (!scsi++) drvname = "SPI host"; 6636 if (!scsi++) drvname = "SPI host";
6637 break; 6637 break;
6638 case MPTFC_DRIVER: 6638 case MPTFC_DRIVER:
6639 if (!fc++) drvname = "FC host"; 6639 if (!fc++) drvname = "FC host";
6640 break; 6640 break;
6641 case MPTSAS_DRIVER: 6641 case MPTSAS_DRIVER:
6642 if (!sas++) drvname = "SAS host"; 6642 if (!sas++) drvname = "SAS host";
6643 break; 6643 break;
6644 case MPTLAN_DRIVER: 6644 case MPTLAN_DRIVER:
6645 if (!lan++) drvname = "LAN"; 6645 if (!lan++) drvname = "LAN";
6646 break; 6646 break;
6647 case MPTSTM_DRIVER: 6647 case MPTSTM_DRIVER:
6648 if (!targ++) drvname = "SCSI target"; 6648 if (!targ++) drvname = "SCSI target";
6649 break; 6649 break;
6650 case MPTCTL_DRIVER: 6650 case MPTCTL_DRIVER:
6651 if (!ctl++) drvname = "ioctl"; 6651 if (!ctl++) drvname = "ioctl";
6652 break; 6652 break;
6653 } 6653 }
6654 6654
6655 if (drvname) 6655 if (drvname)
6656 len += sprintf(buf+len, " Fusion MPT %s driver\n", drvname); 6656 len += sprintf(buf+len, " Fusion MPT %s driver\n", drvname);
6657 } 6657 }
6658 } 6658 }
6659 6659
6660 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len); 6660 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
6661 } 6661 }
6662 6662
6663 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 6663 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6664 /** 6664 /**
6665 * procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info. 6665 * procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
6666 * @buf: Pointer to area to write information 6666 * @buf: Pointer to area to write information
6667 * @start: Pointer to start pointer 6667 * @start: Pointer to start pointer
6668 * @offset: Offset to start writing 6668 * @offset: Offset to start writing
6669 * @request: Amount of read data requested 6669 * @request: Amount of read data requested
6670 * @eof: Pointer to EOF integer 6670 * @eof: Pointer to EOF integer
6671 * @data: Pointer 6671 * @data: Pointer
6672 * 6672 *
6673 * Returns number of characters written to process performing the read. 6673 * Returns number of characters written to process performing the read.
6674 */ 6674 */
6675 static int 6675 static int
6676 procmpt_iocinfo_read(char *buf, char **start, off_t offset, int request, int *eof, void *data) 6676 procmpt_iocinfo_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
6677 { 6677 {
6678 MPT_ADAPTER *ioc = data; 6678 MPT_ADAPTER *ioc = data;
6679 int len; 6679 int len;
6680 char expVer[32]; 6680 char expVer[32];
6681 int sz; 6681 int sz;
6682 int p; 6682 int p;
6683 6683
6684 mpt_get_fw_exp_ver(expVer, ioc); 6684 mpt_get_fw_exp_ver(expVer, ioc);
6685 6685
6686 len = sprintf(buf, "%s:", ioc->name); 6686 len = sprintf(buf, "%s:", ioc->name);
6687 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT) 6687 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
6688 len += sprintf(buf+len, " (f/w download boot flag set)"); 6688 len += sprintf(buf+len, " (f/w download boot flag set)");
6689 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL) 6689 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
6690 // len += sprintf(buf+len, " CONFIG_CHECKSUM_FAIL!"); 6690 // len += sprintf(buf+len, " CONFIG_CHECKSUM_FAIL!");
6691 6691
6692 len += sprintf(buf+len, "\n ProductID = 0x%04x (%s)\n", 6692 len += sprintf(buf+len, "\n ProductID = 0x%04x (%s)\n",
6693 ioc->facts.ProductID, 6693 ioc->facts.ProductID,
6694 ioc->prod_name); 6694 ioc->prod_name);
6695 len += sprintf(buf+len, " FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer); 6695 len += sprintf(buf+len, " FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
6696 if (ioc->facts.FWImageSize) 6696 if (ioc->facts.FWImageSize)
6697 len += sprintf(buf+len, " (fw_size=%d)", ioc->facts.FWImageSize); 6697 len += sprintf(buf+len, " (fw_size=%d)", ioc->facts.FWImageSize);
6698 len += sprintf(buf+len, "\n MsgVersion = 0x%04x\n", ioc->facts.MsgVersion); 6698 len += sprintf(buf+len, "\n MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
6699 len += sprintf(buf+len, " FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit); 6699 len += sprintf(buf+len, " FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
6700 len += sprintf(buf+len, " EventState = 0x%02x\n", ioc->facts.EventState); 6700 len += sprintf(buf+len, " EventState = 0x%02x\n", ioc->facts.EventState);
6701 6701
6702 len += sprintf(buf+len, " CurrentHostMfaHighAddr = 0x%08x\n", 6702 len += sprintf(buf+len, " CurrentHostMfaHighAddr = 0x%08x\n",
6703 ioc->facts.CurrentHostMfaHighAddr); 6703 ioc->facts.CurrentHostMfaHighAddr);
6704 len += sprintf(buf+len, " CurrentSenseBufferHighAddr = 0x%08x\n", 6704 len += sprintf(buf+len, " CurrentSenseBufferHighAddr = 0x%08x\n",
6705 ioc->facts.CurrentSenseBufferHighAddr); 6705 ioc->facts.CurrentSenseBufferHighAddr);
6706 6706
6707 len += sprintf(buf+len, " MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth); 6707 len += sprintf(buf+len, " MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
6708 len += sprintf(buf+len, " MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize); 6708 len += sprintf(buf+len, " MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
6709 6709
6710 len += sprintf(buf+len, " RequestFrames @ 0x%p (Dma @ 0x%p)\n", 6710 len += sprintf(buf+len, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
6711 (void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma); 6711 (void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
6712 /* 6712 /*
6713 * Rounding UP to nearest 4-kB boundary here... 6713 * Rounding UP to nearest 4-kB boundary here...
6714 */ 6714 */
6715 sz = (ioc->req_sz * ioc->req_depth) + 128; 6715 sz = (ioc->req_sz * ioc->req_depth) + 128;
6716 sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000; 6716 sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
6717 len += sprintf(buf+len, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n", 6717 len += sprintf(buf+len, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
6718 ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz); 6718 ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
6719 len += sprintf(buf+len, " {MaxReqSz=%d} {MaxReqDepth=%d}\n", 6719 len += sprintf(buf+len, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
6720 4*ioc->facts.RequestFrameSize, 6720 4*ioc->facts.RequestFrameSize,
6721 ioc->facts.GlobalCredits); 6721 ioc->facts.GlobalCredits);
6722 6722
6723 len += sprintf(buf+len, " Frames @ 0x%p (Dma @ 0x%p)\n", 6723 len += sprintf(buf+len, " Frames @ 0x%p (Dma @ 0x%p)\n",
6724 (void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma); 6724 (void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma);
6725 sz = (ioc->reply_sz * ioc->reply_depth) + 128; 6725 sz = (ioc->reply_sz * ioc->reply_depth) + 128;
6726 len += sprintf(buf+len, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n", 6726 len += sprintf(buf+len, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
6727 ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz); 6727 ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
6728 len += sprintf(buf+len, " {MaxRepSz=%d} {MaxRepDepth=%d}\n", 6728 len += sprintf(buf+len, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
6729 ioc->facts.CurReplyFrameSize, 6729 ioc->facts.CurReplyFrameSize,
6730 ioc->facts.ReplyQueueDepth); 6730 ioc->facts.ReplyQueueDepth);
6731 6731
6732 len += sprintf(buf+len, " MaxDevices = %d\n", 6732 len += sprintf(buf+len, " MaxDevices = %d\n",
6733 (ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices); 6733 (ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
6734 len += sprintf(buf+len, " MaxBuses = %d\n", ioc->facts.MaxBuses); 6734 len += sprintf(buf+len, " MaxBuses = %d\n", ioc->facts.MaxBuses);
6735 6735
6736 /* per-port info */ 6736 /* per-port info */
6737 for (p=0; p < ioc->facts.NumberOfPorts; p++) { 6737 for (p=0; p < ioc->facts.NumberOfPorts; p++) {
6738 len += sprintf(buf+len, " PortNumber = %d (of %d)\n", 6738 len += sprintf(buf+len, " PortNumber = %d (of %d)\n",
6739 p+1, 6739 p+1,
6740 ioc->facts.NumberOfPorts); 6740 ioc->facts.NumberOfPorts);
6741 if (ioc->bus_type == FC) { 6741 if (ioc->bus_type == FC) {
6742 if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) { 6742 if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
6743 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow; 6743 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6744 len += sprintf(buf+len, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n", 6744 len += sprintf(buf+len, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
6745 a[5], a[4], a[3], a[2], a[1], a[0]); 6745 a[5], a[4], a[3], a[2], a[1], a[0]);
6746 } 6746 }
6747 len += sprintf(buf+len, " WWN = %08X%08X:%08X%08X\n", 6747 len += sprintf(buf+len, " WWN = %08X%08X:%08X%08X\n",
6748 ioc->fc_port_page0[p].WWNN.High, 6748 ioc->fc_port_page0[p].WWNN.High,
6749 ioc->fc_port_page0[p].WWNN.Low, 6749 ioc->fc_port_page0[p].WWNN.Low,
6750 ioc->fc_port_page0[p].WWPN.High, 6750 ioc->fc_port_page0[p].WWPN.High,
6751 ioc->fc_port_page0[p].WWPN.Low); 6751 ioc->fc_port_page0[p].WWPN.Low);
6752 } 6752 }
6753 } 6753 }
6754 6754
6755 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len); 6755 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
6756 } 6756 }
6757 6757
6758 #endif /* CONFIG_PROC_FS } */ 6758 #endif /* CONFIG_PROC_FS } */
6759 6759
6760 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 6760 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6761 static void 6761 static void
6762 mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc) 6762 mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
6763 { 6763 {
6764 buf[0] ='\0'; 6764 buf[0] ='\0';
6765 if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) { 6765 if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) {
6766 sprintf(buf, " (Exp %02d%02d)", 6766 sprintf(buf, " (Exp %02d%02d)",
6767 (ioc->facts.FWVersion.Word >> 16) & 0x00FF, /* Month */ 6767 (ioc->facts.FWVersion.Word >> 16) & 0x00FF, /* Month */
6768 (ioc->facts.FWVersion.Word >> 8) & 0x1F); /* Day */ 6768 (ioc->facts.FWVersion.Word >> 8) & 0x1F); /* Day */
6769 6769
6770 /* insider hack! */ 6770 /* insider hack! */
6771 if ((ioc->facts.FWVersion.Word >> 8) & 0x80) 6771 if ((ioc->facts.FWVersion.Word >> 8) & 0x80)
6772 strcat(buf, " [MDBG]"); 6772 strcat(buf, " [MDBG]");
6773 } 6773 }
6774 } 6774 }
6775 6775
6776 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 6776 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6777 /** 6777 /**
6778 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer. 6778 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
6779 * @ioc: Pointer to MPT_ADAPTER structure 6779 * @ioc: Pointer to MPT_ADAPTER structure
6780 * @buffer: Pointer to buffer where IOC summary info should be written 6780 * @buffer: Pointer to buffer where IOC summary info should be written
6781 * @size: Pointer to number of bytes we wrote (set by this routine) 6781 * @size: Pointer to number of bytes we wrote (set by this routine)
6782 * @len: Offset at which to start writing in buffer 6782 * @len: Offset at which to start writing in buffer
6783 * @showlan: Display LAN stuff? 6783 * @showlan: Display LAN stuff?
6784 * 6784 *
6785 * This routine writes (english readable) ASCII text, which represents 6785 * This routine writes (english readable) ASCII text, which represents
6786 * a summary of IOC information, to a buffer. 6786 * a summary of IOC information, to a buffer.
6787 */ 6787 */
6788 void 6788 void
6789 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan) 6789 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
6790 { 6790 {
6791 char expVer[32]; 6791 char expVer[32];
6792 int y; 6792 int y;
6793 6793
6794 mpt_get_fw_exp_ver(expVer, ioc); 6794 mpt_get_fw_exp_ver(expVer, ioc);
6795 6795
6796 /* 6796 /*
6797 * Shorter summary of attached ioc's... 6797 * Shorter summary of attached ioc's...
6798 */ 6798 */
6799 y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d", 6799 y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
6800 ioc->name, 6800 ioc->name,
6801 ioc->prod_name, 6801 ioc->prod_name,
6802 MPT_FW_REV_MAGIC_ID_STRING, /* "FwRev=" or somesuch */ 6802 MPT_FW_REV_MAGIC_ID_STRING, /* "FwRev=" or somesuch */
6803 ioc->facts.FWVersion.Word, 6803 ioc->facts.FWVersion.Word,
6804 expVer, 6804 expVer,
6805 ioc->facts.NumberOfPorts, 6805 ioc->facts.NumberOfPorts,
6806 ioc->req_depth); 6806 ioc->req_depth);
6807 6807
6808 if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) { 6808 if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
6809 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow; 6809 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6810 y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X", 6810 y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
6811 a[5], a[4], a[3], a[2], a[1], a[0]); 6811 a[5], a[4], a[3], a[2], a[1], a[0]);
6812 } 6812 }
6813 6813
6814 y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq); 6814 y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
6815 6815
6816 if (!ioc->active) 6816 if (!ioc->active)
6817 y += sprintf(buffer+len+y, " (disabled)"); 6817 y += sprintf(buffer+len+y, " (disabled)");
6818 6818
6819 y += sprintf(buffer+len+y, "\n"); 6819 y += sprintf(buffer+len+y, "\n");
6820 6820
6821 *size = y; 6821 *size = y;
6822 } 6822 }
6823 /** 6823 /**
6824 * mpt_set_taskmgmt_in_progress_flag - set flags associated with task managment 6824 * mpt_set_taskmgmt_in_progress_flag - set flags associated with task management
6825 * @ioc: Pointer to MPT_ADAPTER structure 6825 * @ioc: Pointer to MPT_ADAPTER structure
6826 * 6826 *
6827 * Returns 0 for SUCCESS or -1 if FAILED. 6827 * Returns 0 for SUCCESS or -1 if FAILED.
6828 * 6828 *
6829 * If -1 is return, then it was not possible to set the flags 6829 * If -1 is return, then it was not possible to set the flags
6830 **/ 6830 **/
6831 int 6831 int
6832 mpt_set_taskmgmt_in_progress_flag(MPT_ADAPTER *ioc) 6832 mpt_set_taskmgmt_in_progress_flag(MPT_ADAPTER *ioc)
6833 { 6833 {
6834 unsigned long flags; 6834 unsigned long flags;
6835 int retval; 6835 int retval;
6836 6836
6837 spin_lock_irqsave(&ioc->taskmgmt_lock, flags); 6837 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6838 if (ioc->ioc_reset_in_progress || ioc->taskmgmt_in_progress || 6838 if (ioc->ioc_reset_in_progress || ioc->taskmgmt_in_progress ||
6839 (ioc->alt_ioc && ioc->alt_ioc->taskmgmt_in_progress)) { 6839 (ioc->alt_ioc && ioc->alt_ioc->taskmgmt_in_progress)) {
6840 retval = -1; 6840 retval = -1;
6841 goto out; 6841 goto out;
6842 } 6842 }
6843 retval = 0; 6843 retval = 0;
6844 ioc->taskmgmt_in_progress = 1; 6844 ioc->taskmgmt_in_progress = 1;
6845 ioc->taskmgmt_quiesce_io = 1; 6845 ioc->taskmgmt_quiesce_io = 1;
6846 if (ioc->alt_ioc) { 6846 if (ioc->alt_ioc) {
6847 ioc->alt_ioc->taskmgmt_in_progress = 1; 6847 ioc->alt_ioc->taskmgmt_in_progress = 1;
6848 ioc->alt_ioc->taskmgmt_quiesce_io = 1; 6848 ioc->alt_ioc->taskmgmt_quiesce_io = 1;
6849 } 6849 }
6850 out: 6850 out:
6851 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags); 6851 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6852 return retval; 6852 return retval;
6853 } 6853 }
6854 EXPORT_SYMBOL(mpt_set_taskmgmt_in_progress_flag); 6854 EXPORT_SYMBOL(mpt_set_taskmgmt_in_progress_flag);
6855 6855
6856 /** 6856 /**
6857 * mpt_clear_taskmgmt_in_progress_flag - clear flags associated with task managment 6857 * mpt_clear_taskmgmt_in_progress_flag - clear flags associated with task management
6858 * @ioc: Pointer to MPT_ADAPTER structure 6858 * @ioc: Pointer to MPT_ADAPTER structure
6859 * 6859 *
6860 **/ 6860 **/
6861 void 6861 void
6862 mpt_clear_taskmgmt_in_progress_flag(MPT_ADAPTER *ioc) 6862 mpt_clear_taskmgmt_in_progress_flag(MPT_ADAPTER *ioc)
6863 { 6863 {
6864 unsigned long flags; 6864 unsigned long flags;
6865 6865
6866 spin_lock_irqsave(&ioc->taskmgmt_lock, flags); 6866 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6867 ioc->taskmgmt_in_progress = 0; 6867 ioc->taskmgmt_in_progress = 0;
6868 ioc->taskmgmt_quiesce_io = 0; 6868 ioc->taskmgmt_quiesce_io = 0;
6869 if (ioc->alt_ioc) { 6869 if (ioc->alt_ioc) {
6870 ioc->alt_ioc->taskmgmt_in_progress = 0; 6870 ioc->alt_ioc->taskmgmt_in_progress = 0;
6871 ioc->alt_ioc->taskmgmt_quiesce_io = 0; 6871 ioc->alt_ioc->taskmgmt_quiesce_io = 0;
6872 } 6872 }
6873 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags); 6873 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6874 } 6874 }
6875 EXPORT_SYMBOL(mpt_clear_taskmgmt_in_progress_flag); 6875 EXPORT_SYMBOL(mpt_clear_taskmgmt_in_progress_flag);
6876 6876
6877 6877
6878 /** 6878 /**
6879 * mpt_halt_firmware - Halts the firmware if it is operational and panic 6879 * mpt_halt_firmware - Halts the firmware if it is operational and panic
6880 * the kernel 6880 * the kernel
6881 * @ioc: Pointer to MPT_ADAPTER structure 6881 * @ioc: Pointer to MPT_ADAPTER structure
6882 * 6882 *
6883 **/ 6883 **/
6884 void 6884 void
6885 mpt_halt_firmware(MPT_ADAPTER *ioc) 6885 mpt_halt_firmware(MPT_ADAPTER *ioc)
6886 { 6886 {
6887 u32 ioc_raw_state; 6887 u32 ioc_raw_state;
6888 6888
6889 ioc_raw_state = mpt_GetIocState(ioc, 0); 6889 ioc_raw_state = mpt_GetIocState(ioc, 0);
6890 6890
6891 if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) { 6891 if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
6892 printk(MYIOC_s_ERR_FMT "IOC is in FAULT state (%04xh)!!!\n", 6892 printk(MYIOC_s_ERR_FMT "IOC is in FAULT state (%04xh)!!!\n",
6893 ioc->name, ioc_raw_state & MPI_DOORBELL_DATA_MASK); 6893 ioc->name, ioc_raw_state & MPI_DOORBELL_DATA_MASK);
6894 panic("%s: IOC Fault (%04xh)!!!\n", ioc->name, 6894 panic("%s: IOC Fault (%04xh)!!!\n", ioc->name,
6895 ioc_raw_state & MPI_DOORBELL_DATA_MASK); 6895 ioc_raw_state & MPI_DOORBELL_DATA_MASK);
6896 } else { 6896 } else {
6897 CHIPREG_WRITE32(&ioc->chip->Doorbell, 0xC0FFEE00); 6897 CHIPREG_WRITE32(&ioc->chip->Doorbell, 0xC0FFEE00);
6898 panic("%s: Firmware is halted due to command timeout\n", 6898 panic("%s: Firmware is halted due to command timeout\n",
6899 ioc->name); 6899 ioc->name);
6900 } 6900 }
6901 } 6901 }
6902 EXPORT_SYMBOL(mpt_halt_firmware); 6902 EXPORT_SYMBOL(mpt_halt_firmware);
6903 6903
6904 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 6904 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6905 /* 6905 /*
6906 * Reset Handling 6906 * Reset Handling
6907 */ 6907 */
6908 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 6908 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6909 /** 6909 /**
6910 * mpt_HardResetHandler - Generic reset handler 6910 * mpt_HardResetHandler - Generic reset handler
6911 * @ioc: Pointer to MPT_ADAPTER structure 6911 * @ioc: Pointer to MPT_ADAPTER structure
6912 * @sleepFlag: Indicates if sleep or schedule must be called. 6912 * @sleepFlag: Indicates if sleep or schedule must be called.
6913 * 6913 *
6914 * Issues SCSI Task Management call based on input arg values. 6914 * Issues SCSI Task Management call based on input arg values.
6915 * If TaskMgmt fails, returns associated SCSI request. 6915 * If TaskMgmt fails, returns associated SCSI request.
6916 * 6916 *
6917 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer) 6917 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
6918 * or a non-interrupt thread. In the former, must not call schedule(). 6918 * or a non-interrupt thread. In the former, must not call schedule().
6919 * 6919 *
6920 * Note: A return of -1 is a FATAL error case, as it means a 6920 * Note: A return of -1 is a FATAL error case, as it means a
6921 * FW reload/initialization failed. 6921 * FW reload/initialization failed.
6922 * 6922 *
6923 * Returns 0 for SUCCESS or -1 if FAILED. 6923 * Returns 0 for SUCCESS or -1 if FAILED.
6924 */ 6924 */
6925 int 6925 int
6926 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag) 6926 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
6927 { 6927 {
6928 int rc; 6928 int rc;
6929 u8 cb_idx; 6929 u8 cb_idx;
6930 unsigned long flags; 6930 unsigned long flags;
6931 unsigned long time_count; 6931 unsigned long time_count;
6932 6932
6933 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler Entered!\n", ioc->name)); 6933 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler Entered!\n", ioc->name));
6934 #ifdef MFCNT 6934 #ifdef MFCNT
6935 printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name); 6935 printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
6936 printk("MF count 0x%x !\n", ioc->mfcnt); 6936 printk("MF count 0x%x !\n", ioc->mfcnt);
6937 #endif 6937 #endif
6938 if (mpt_fwfault_debug) 6938 if (mpt_fwfault_debug)
6939 mpt_halt_firmware(ioc); 6939 mpt_halt_firmware(ioc);
6940 6940
6941 /* Reset the adapter. Prevent more than 1 call to 6941 /* Reset the adapter. Prevent more than 1 call to
6942 * mpt_do_ioc_recovery at any instant in time. 6942 * mpt_do_ioc_recovery at any instant in time.
6943 */ 6943 */
6944 spin_lock_irqsave(&ioc->taskmgmt_lock, flags); 6944 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6945 if (ioc->ioc_reset_in_progress) { 6945 if (ioc->ioc_reset_in_progress) {
6946 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags); 6946 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6947 return 0; 6947 return 0;
6948 } 6948 }
6949 ioc->ioc_reset_in_progress = 1; 6949 ioc->ioc_reset_in_progress = 1;
6950 if (ioc->alt_ioc) 6950 if (ioc->alt_ioc)
6951 ioc->alt_ioc->ioc_reset_in_progress = 1; 6951 ioc->alt_ioc->ioc_reset_in_progress = 1;
6952 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags); 6952 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6953 6953
6954 6954
6955 /* The SCSI driver needs to adjust timeouts on all current 6955 /* The SCSI driver needs to adjust timeouts on all current
6956 * commands prior to the diagnostic reset being issued. 6956 * commands prior to the diagnostic reset being issued.
6957 * Prevents timeouts occurring during a diagnostic reset...very bad. 6957 * Prevents timeouts occurring during a diagnostic reset...very bad.
6958 * For all other protocol drivers, this is a no-op. 6958 * For all other protocol drivers, this is a no-op.
6959 */ 6959 */
6960 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) { 6960 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6961 if (MptResetHandlers[cb_idx]) { 6961 if (MptResetHandlers[cb_idx]) {
6962 mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET); 6962 mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET);
6963 if (ioc->alt_ioc) 6963 if (ioc->alt_ioc)
6964 mpt_signal_reset(cb_idx, ioc->alt_ioc, 6964 mpt_signal_reset(cb_idx, ioc->alt_ioc,
6965 MPT_IOC_SETUP_RESET); 6965 MPT_IOC_SETUP_RESET);
6966 } 6966 }
6967 } 6967 }
6968 6968
6969 time_count = jiffies; 6969 time_count = jiffies;
6970 rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag); 6970 rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag);
6971 if (rc != 0) { 6971 if (rc != 0) {
6972 printk(KERN_WARNING MYNAM 6972 printk(KERN_WARNING MYNAM
6973 ": WARNING - (%d) Cannot recover %s\n", rc, ioc->name); 6973 ": WARNING - (%d) Cannot recover %s\n", rc, ioc->name);
6974 } else { 6974 } else {
6975 if (ioc->hard_resets < -1) 6975 if (ioc->hard_resets < -1)
6976 ioc->hard_resets++; 6976 ioc->hard_resets++;
6977 } 6977 }
6978 6978
6979 spin_lock_irqsave(&ioc->taskmgmt_lock, flags); 6979 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6980 ioc->ioc_reset_in_progress = 0; 6980 ioc->ioc_reset_in_progress = 0;
6981 ioc->taskmgmt_quiesce_io = 0; 6981 ioc->taskmgmt_quiesce_io = 0;
6982 ioc->taskmgmt_in_progress = 0; 6982 ioc->taskmgmt_in_progress = 0;
6983 if (ioc->alt_ioc) { 6983 if (ioc->alt_ioc) {
6984 ioc->alt_ioc->ioc_reset_in_progress = 0; 6984 ioc->alt_ioc->ioc_reset_in_progress = 0;
6985 ioc->alt_ioc->taskmgmt_quiesce_io = 0; 6985 ioc->alt_ioc->taskmgmt_quiesce_io = 0;
6986 ioc->alt_ioc->taskmgmt_in_progress = 0; 6986 ioc->alt_ioc->taskmgmt_in_progress = 0;
6987 } 6987 }
6988 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags); 6988 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6989 6989
6990 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) { 6990 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6991 if (MptResetHandlers[cb_idx]) { 6991 if (MptResetHandlers[cb_idx]) {
6992 mpt_signal_reset(cb_idx, ioc, MPT_IOC_POST_RESET); 6992 mpt_signal_reset(cb_idx, ioc, MPT_IOC_POST_RESET);
6993 if (ioc->alt_ioc) 6993 if (ioc->alt_ioc)
6994 mpt_signal_reset(cb_idx, 6994 mpt_signal_reset(cb_idx,
6995 ioc->alt_ioc, MPT_IOC_POST_RESET); 6995 ioc->alt_ioc, MPT_IOC_POST_RESET);
6996 } 6996 }
6997 } 6997 }
6998 6998
6999 dtmprintk(ioc, 6999 dtmprintk(ioc,
7000 printk(MYIOC_s_DEBUG_FMT 7000 printk(MYIOC_s_DEBUG_FMT
7001 "HardResetHandler: completed (%d seconds): %s\n", ioc->name, 7001 "HardResetHandler: completed (%d seconds): %s\n", ioc->name,
7002 jiffies_to_msecs(jiffies - time_count)/1000, ((rc == 0) ? 7002 jiffies_to_msecs(jiffies - time_count)/1000, ((rc == 0) ?
7003 "SUCCESS" : "FAILED"))); 7003 "SUCCESS" : "FAILED")));
7004 7004
7005 return rc; 7005 return rc;
7006 } 7006 }
7007 7007
7008 #ifdef CONFIG_FUSION_LOGGING 7008 #ifdef CONFIG_FUSION_LOGGING
7009 static void 7009 static void
7010 mpt_display_event_info(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply) 7010 mpt_display_event_info(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply)
7011 { 7011 {
7012 char *ds = NULL; 7012 char *ds = NULL;
7013 u32 evData0; 7013 u32 evData0;
7014 int ii; 7014 int ii;
7015 u8 event; 7015 u8 event;
7016 char *evStr = ioc->evStr; 7016 char *evStr = ioc->evStr;
7017 7017
7018 event = le32_to_cpu(pEventReply->Event) & 0xFF; 7018 event = le32_to_cpu(pEventReply->Event) & 0xFF;
7019 evData0 = le32_to_cpu(pEventReply->Data[0]); 7019 evData0 = le32_to_cpu(pEventReply->Data[0]);
7020 7020
7021 switch(event) { 7021 switch(event) {
7022 case MPI_EVENT_NONE: 7022 case MPI_EVENT_NONE:
7023 ds = "None"; 7023 ds = "None";
7024 break; 7024 break;
7025 case MPI_EVENT_LOG_DATA: 7025 case MPI_EVENT_LOG_DATA:
7026 ds = "Log Data"; 7026 ds = "Log Data";
7027 break; 7027 break;
7028 case MPI_EVENT_STATE_CHANGE: 7028 case MPI_EVENT_STATE_CHANGE:
7029 ds = "State Change"; 7029 ds = "State Change";
7030 break; 7030 break;
7031 case MPI_EVENT_UNIT_ATTENTION: 7031 case MPI_EVENT_UNIT_ATTENTION:
7032 ds = "Unit Attention"; 7032 ds = "Unit Attention";
7033 break; 7033 break;
7034 case MPI_EVENT_IOC_BUS_RESET: 7034 case MPI_EVENT_IOC_BUS_RESET:
7035 ds = "IOC Bus Reset"; 7035 ds = "IOC Bus Reset";
7036 break; 7036 break;
7037 case MPI_EVENT_EXT_BUS_RESET: 7037 case MPI_EVENT_EXT_BUS_RESET:
7038 ds = "External Bus Reset"; 7038 ds = "External Bus Reset";
7039 break; 7039 break;
7040 case MPI_EVENT_RESCAN: 7040 case MPI_EVENT_RESCAN:
7041 ds = "Bus Rescan Event"; 7041 ds = "Bus Rescan Event";
7042 break; 7042 break;
7043 case MPI_EVENT_LINK_STATUS_CHANGE: 7043 case MPI_EVENT_LINK_STATUS_CHANGE:
7044 if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE) 7044 if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE)
7045 ds = "Link Status(FAILURE) Change"; 7045 ds = "Link Status(FAILURE) Change";
7046 else 7046 else
7047 ds = "Link Status(ACTIVE) Change"; 7047 ds = "Link Status(ACTIVE) Change";
7048 break; 7048 break;
7049 case MPI_EVENT_LOOP_STATE_CHANGE: 7049 case MPI_EVENT_LOOP_STATE_CHANGE:
7050 if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP) 7050 if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
7051 ds = "Loop State(LIP) Change"; 7051 ds = "Loop State(LIP) Change";
7052 else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE) 7052 else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
7053 ds = "Loop State(LPE) Change"; 7053 ds = "Loop State(LPE) Change";
7054 else 7054 else
7055 ds = "Loop State(LPB) Change"; 7055 ds = "Loop State(LPB) Change";
7056 break; 7056 break;
7057 case MPI_EVENT_LOGOUT: 7057 case MPI_EVENT_LOGOUT:
7058 ds = "Logout"; 7058 ds = "Logout";
7059 break; 7059 break;
7060 case MPI_EVENT_EVENT_CHANGE: 7060 case MPI_EVENT_EVENT_CHANGE:
7061 if (evData0) 7061 if (evData0)
7062 ds = "Events ON"; 7062 ds = "Events ON";
7063 else 7063 else
7064 ds = "Events OFF"; 7064 ds = "Events OFF";
7065 break; 7065 break;
7066 case MPI_EVENT_INTEGRATED_RAID: 7066 case MPI_EVENT_INTEGRATED_RAID:
7067 { 7067 {
7068 u8 ReasonCode = (u8)(evData0 >> 16); 7068 u8 ReasonCode = (u8)(evData0 >> 16);
7069 switch (ReasonCode) { 7069 switch (ReasonCode) {
7070 case MPI_EVENT_RAID_RC_VOLUME_CREATED : 7070 case MPI_EVENT_RAID_RC_VOLUME_CREATED :
7071 ds = "Integrated Raid: Volume Created"; 7071 ds = "Integrated Raid: Volume Created";
7072 break; 7072 break;
7073 case MPI_EVENT_RAID_RC_VOLUME_DELETED : 7073 case MPI_EVENT_RAID_RC_VOLUME_DELETED :
7074 ds = "Integrated Raid: Volume Deleted"; 7074 ds = "Integrated Raid: Volume Deleted";
7075 break; 7075 break;
7076 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED : 7076 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED :
7077 ds = "Integrated Raid: Volume Settings Changed"; 7077 ds = "Integrated Raid: Volume Settings Changed";
7078 break; 7078 break;
7079 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED : 7079 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED :
7080 ds = "Integrated Raid: Volume Status Changed"; 7080 ds = "Integrated Raid: Volume Status Changed";
7081 break; 7081 break;
7082 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED : 7082 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED :
7083 ds = "Integrated Raid: Volume Physdisk Changed"; 7083 ds = "Integrated Raid: Volume Physdisk Changed";
7084 break; 7084 break;
7085 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED : 7085 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED :
7086 ds = "Integrated Raid: Physdisk Created"; 7086 ds = "Integrated Raid: Physdisk Created";
7087 break; 7087 break;
7088 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED : 7088 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED :
7089 ds = "Integrated Raid: Physdisk Deleted"; 7089 ds = "Integrated Raid: Physdisk Deleted";
7090 break; 7090 break;
7091 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED : 7091 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED :
7092 ds = "Integrated Raid: Physdisk Settings Changed"; 7092 ds = "Integrated Raid: Physdisk Settings Changed";
7093 break; 7093 break;
7094 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED : 7094 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED :
7095 ds = "Integrated Raid: Physdisk Status Changed"; 7095 ds = "Integrated Raid: Physdisk Status Changed";
7096 break; 7096 break;
7097 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED : 7097 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED :
7098 ds = "Integrated Raid: Domain Validation Needed"; 7098 ds = "Integrated Raid: Domain Validation Needed";
7099 break; 7099 break;
7100 case MPI_EVENT_RAID_RC_SMART_DATA : 7100 case MPI_EVENT_RAID_RC_SMART_DATA :
7101 ds = "Integrated Raid; Smart Data"; 7101 ds = "Integrated Raid; Smart Data";
7102 break; 7102 break;
7103 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED : 7103 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED :
7104 ds = "Integrated Raid: Replace Action Started"; 7104 ds = "Integrated Raid: Replace Action Started";
7105 break; 7105 break;
7106 default: 7106 default:
7107 ds = "Integrated Raid"; 7107 ds = "Integrated Raid";
7108 break; 7108 break;
7109 } 7109 }
7110 break; 7110 break;
7111 } 7111 }
7112 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE: 7112 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE:
7113 ds = "SCSI Device Status Change"; 7113 ds = "SCSI Device Status Change";
7114 break; 7114 break;
7115 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE: 7115 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
7116 { 7116 {
7117 u8 id = (u8)(evData0); 7117 u8 id = (u8)(evData0);
7118 u8 channel = (u8)(evData0 >> 8); 7118 u8 channel = (u8)(evData0 >> 8);
7119 u8 ReasonCode = (u8)(evData0 >> 16); 7119 u8 ReasonCode = (u8)(evData0 >> 16);
7120 switch (ReasonCode) { 7120 switch (ReasonCode) {
7121 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED: 7121 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
7122 snprintf(evStr, EVENT_DESCR_STR_SZ, 7122 snprintf(evStr, EVENT_DESCR_STR_SZ,
7123 "SAS Device Status Change: Added: " 7123 "SAS Device Status Change: Added: "
7124 "id=%d channel=%d", id, channel); 7124 "id=%d channel=%d", id, channel);
7125 break; 7125 break;
7126 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING: 7126 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
7127 snprintf(evStr, EVENT_DESCR_STR_SZ, 7127 snprintf(evStr, EVENT_DESCR_STR_SZ,
7128 "SAS Device Status Change: Deleted: " 7128 "SAS Device Status Change: Deleted: "
7129 "id=%d channel=%d", id, channel); 7129 "id=%d channel=%d", id, channel);
7130 break; 7130 break;
7131 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA: 7131 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
7132 snprintf(evStr, EVENT_DESCR_STR_SZ, 7132 snprintf(evStr, EVENT_DESCR_STR_SZ,
7133 "SAS Device Status Change: SMART Data: " 7133 "SAS Device Status Change: SMART Data: "
7134 "id=%d channel=%d", id, channel); 7134 "id=%d channel=%d", id, channel);
7135 break; 7135 break;
7136 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED: 7136 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
7137 snprintf(evStr, EVENT_DESCR_STR_SZ, 7137 snprintf(evStr, EVENT_DESCR_STR_SZ,
7138 "SAS Device Status Change: No Persistancy: " 7138 "SAS Device Status Change: No Persistancy: "
7139 "id=%d channel=%d", id, channel); 7139 "id=%d channel=%d", id, channel);
7140 break; 7140 break;
7141 case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED: 7141 case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
7142 snprintf(evStr, EVENT_DESCR_STR_SZ, 7142 snprintf(evStr, EVENT_DESCR_STR_SZ,
7143 "SAS Device Status Change: Unsupported Device " 7143 "SAS Device Status Change: Unsupported Device "
7144 "Discovered : id=%d channel=%d", id, channel); 7144 "Discovered : id=%d channel=%d", id, channel);
7145 break; 7145 break;
7146 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET: 7146 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
7147 snprintf(evStr, EVENT_DESCR_STR_SZ, 7147 snprintf(evStr, EVENT_DESCR_STR_SZ,
7148 "SAS Device Status Change: Internal Device " 7148 "SAS Device Status Change: Internal Device "
7149 "Reset : id=%d channel=%d", id, channel); 7149 "Reset : id=%d channel=%d", id, channel);
7150 break; 7150 break;
7151 case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL: 7151 case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
7152 snprintf(evStr, EVENT_DESCR_STR_SZ, 7152 snprintf(evStr, EVENT_DESCR_STR_SZ,
7153 "SAS Device Status Change: Internal Task " 7153 "SAS Device Status Change: Internal Task "
7154 "Abort : id=%d channel=%d", id, channel); 7154 "Abort : id=%d channel=%d", id, channel);
7155 break; 7155 break;
7156 case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL: 7156 case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
7157 snprintf(evStr, EVENT_DESCR_STR_SZ, 7157 snprintf(evStr, EVENT_DESCR_STR_SZ,
7158 "SAS Device Status Change: Internal Abort " 7158 "SAS Device Status Change: Internal Abort "
7159 "Task Set : id=%d channel=%d", id, channel); 7159 "Task Set : id=%d channel=%d", id, channel);
7160 break; 7160 break;
7161 case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL: 7161 case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
7162 snprintf(evStr, EVENT_DESCR_STR_SZ, 7162 snprintf(evStr, EVENT_DESCR_STR_SZ,
7163 "SAS Device Status Change: Internal Clear " 7163 "SAS Device Status Change: Internal Clear "
7164 "Task Set : id=%d channel=%d", id, channel); 7164 "Task Set : id=%d channel=%d", id, channel);
7165 break; 7165 break;
7166 case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL: 7166 case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
7167 snprintf(evStr, EVENT_DESCR_STR_SZ, 7167 snprintf(evStr, EVENT_DESCR_STR_SZ,
7168 "SAS Device Status Change: Internal Query " 7168 "SAS Device Status Change: Internal Query "
7169 "Task : id=%d channel=%d", id, channel); 7169 "Task : id=%d channel=%d", id, channel);
7170 break; 7170 break;
7171 default: 7171 default:
7172 snprintf(evStr, EVENT_DESCR_STR_SZ, 7172 snprintf(evStr, EVENT_DESCR_STR_SZ,
7173 "SAS Device Status Change: Unknown: " 7173 "SAS Device Status Change: Unknown: "
7174 "id=%d channel=%d", id, channel); 7174 "id=%d channel=%d", id, channel);
7175 break; 7175 break;
7176 } 7176 }
7177 break; 7177 break;
7178 } 7178 }
7179 case MPI_EVENT_ON_BUS_TIMER_EXPIRED: 7179 case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
7180 ds = "Bus Timer Expired"; 7180 ds = "Bus Timer Expired";
7181 break; 7181 break;
7182 case MPI_EVENT_QUEUE_FULL: 7182 case MPI_EVENT_QUEUE_FULL:
7183 { 7183 {
7184 u16 curr_depth = (u16)(evData0 >> 16); 7184 u16 curr_depth = (u16)(evData0 >> 16);
7185 u8 channel = (u8)(evData0 >> 8); 7185 u8 channel = (u8)(evData0 >> 8);
7186 u8 id = (u8)(evData0); 7186 u8 id = (u8)(evData0);
7187 7187
7188 snprintf(evStr, EVENT_DESCR_STR_SZ, 7188 snprintf(evStr, EVENT_DESCR_STR_SZ,
7189 "Queue Full: channel=%d id=%d depth=%d", 7189 "Queue Full: channel=%d id=%d depth=%d",
7190 channel, id, curr_depth); 7190 channel, id, curr_depth);
7191 break; 7191 break;
7192 } 7192 }
7193 case MPI_EVENT_SAS_SES: 7193 case MPI_EVENT_SAS_SES:
7194 ds = "SAS SES Event"; 7194 ds = "SAS SES Event";
7195 break; 7195 break;
7196 case MPI_EVENT_PERSISTENT_TABLE_FULL: 7196 case MPI_EVENT_PERSISTENT_TABLE_FULL:
7197 ds = "Persistent Table Full"; 7197 ds = "Persistent Table Full";
7198 break; 7198 break;
7199 case MPI_EVENT_SAS_PHY_LINK_STATUS: 7199 case MPI_EVENT_SAS_PHY_LINK_STATUS:
7200 { 7200 {
7201 u8 LinkRates = (u8)(evData0 >> 8); 7201 u8 LinkRates = (u8)(evData0 >> 8);
7202 u8 PhyNumber = (u8)(evData0); 7202 u8 PhyNumber = (u8)(evData0);
7203 LinkRates = (LinkRates & MPI_EVENT_SAS_PLS_LR_CURRENT_MASK) >> 7203 LinkRates = (LinkRates & MPI_EVENT_SAS_PLS_LR_CURRENT_MASK) >>
7204 MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT; 7204 MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT;
7205 switch (LinkRates) { 7205 switch (LinkRates) {
7206 case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN: 7206 case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN:
7207 snprintf(evStr, EVENT_DESCR_STR_SZ, 7207 snprintf(evStr, EVENT_DESCR_STR_SZ,
7208 "SAS PHY Link Status: Phy=%d:" 7208 "SAS PHY Link Status: Phy=%d:"
7209 " Rate Unknown",PhyNumber); 7209 " Rate Unknown",PhyNumber);
7210 break; 7210 break;
7211 case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED: 7211 case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED:
7212 snprintf(evStr, EVENT_DESCR_STR_SZ, 7212 snprintf(evStr, EVENT_DESCR_STR_SZ,
7213 "SAS PHY Link Status: Phy=%d:" 7213 "SAS PHY Link Status: Phy=%d:"
7214 " Phy Disabled",PhyNumber); 7214 " Phy Disabled",PhyNumber);
7215 break; 7215 break;
7216 case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION: 7216 case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION:
7217 snprintf(evStr, EVENT_DESCR_STR_SZ, 7217 snprintf(evStr, EVENT_DESCR_STR_SZ,
7218 "SAS PHY Link Status: Phy=%d:" 7218 "SAS PHY Link Status: Phy=%d:"
7219 " Failed Speed Nego",PhyNumber); 7219 " Failed Speed Nego",PhyNumber);
7220 break; 7220 break;
7221 case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE: 7221 case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE:
7222 snprintf(evStr, EVENT_DESCR_STR_SZ, 7222 snprintf(evStr, EVENT_DESCR_STR_SZ,
7223 "SAS PHY Link Status: Phy=%d:" 7223 "SAS PHY Link Status: Phy=%d:"
7224 " Sata OOB Completed",PhyNumber); 7224 " Sata OOB Completed",PhyNumber);
7225 break; 7225 break;
7226 case MPI_EVENT_SAS_PLS_LR_RATE_1_5: 7226 case MPI_EVENT_SAS_PLS_LR_RATE_1_5:
7227 snprintf(evStr, EVENT_DESCR_STR_SZ, 7227 snprintf(evStr, EVENT_DESCR_STR_SZ,
7228 "SAS PHY Link Status: Phy=%d:" 7228 "SAS PHY Link Status: Phy=%d:"
7229 " Rate 1.5 Gbps",PhyNumber); 7229 " Rate 1.5 Gbps",PhyNumber);
7230 break; 7230 break;
7231 case MPI_EVENT_SAS_PLS_LR_RATE_3_0: 7231 case MPI_EVENT_SAS_PLS_LR_RATE_3_0:
7232 snprintf(evStr, EVENT_DESCR_STR_SZ, 7232 snprintf(evStr, EVENT_DESCR_STR_SZ,
7233 "SAS PHY Link Status: Phy=%d:" 7233 "SAS PHY Link Status: Phy=%d:"
7234 " Rate 3.0 Gpbs",PhyNumber); 7234 " Rate 3.0 Gpbs",PhyNumber);
7235 break; 7235 break;
7236 default: 7236 default:
7237 snprintf(evStr, EVENT_DESCR_STR_SZ, 7237 snprintf(evStr, EVENT_DESCR_STR_SZ,
7238 "SAS PHY Link Status: Phy=%d", PhyNumber); 7238 "SAS PHY Link Status: Phy=%d", PhyNumber);
7239 break; 7239 break;
7240 } 7240 }
7241 break; 7241 break;
7242 } 7242 }
7243 case MPI_EVENT_SAS_DISCOVERY_ERROR: 7243 case MPI_EVENT_SAS_DISCOVERY_ERROR:
7244 ds = "SAS Discovery Error"; 7244 ds = "SAS Discovery Error";
7245 break; 7245 break;
7246 case MPI_EVENT_IR_RESYNC_UPDATE: 7246 case MPI_EVENT_IR_RESYNC_UPDATE:
7247 { 7247 {
7248 u8 resync_complete = (u8)(evData0 >> 16); 7248 u8 resync_complete = (u8)(evData0 >> 16);
7249 snprintf(evStr, EVENT_DESCR_STR_SZ, 7249 snprintf(evStr, EVENT_DESCR_STR_SZ,
7250 "IR Resync Update: Complete = %d:",resync_complete); 7250 "IR Resync Update: Complete = %d:",resync_complete);
7251 break; 7251 break;
7252 } 7252 }
7253 case MPI_EVENT_IR2: 7253 case MPI_EVENT_IR2:
7254 { 7254 {
7255 u8 id = (u8)(evData0); 7255 u8 id = (u8)(evData0);
7256 u8 channel = (u8)(evData0 >> 8); 7256 u8 channel = (u8)(evData0 >> 8);
7257 u8 phys_num = (u8)(evData0 >> 24); 7257 u8 phys_num = (u8)(evData0 >> 24);
7258 u8 ReasonCode = (u8)(evData0 >> 16); 7258 u8 ReasonCode = (u8)(evData0 >> 16);
7259 7259
7260 switch (ReasonCode) { 7260 switch (ReasonCode) {
7261 case MPI_EVENT_IR2_RC_LD_STATE_CHANGED: 7261 case MPI_EVENT_IR2_RC_LD_STATE_CHANGED:
7262 snprintf(evStr, EVENT_DESCR_STR_SZ, 7262 snprintf(evStr, EVENT_DESCR_STR_SZ,
7263 "IR2: LD State Changed: " 7263 "IR2: LD State Changed: "
7264 "id=%d channel=%d phys_num=%d", 7264 "id=%d channel=%d phys_num=%d",
7265 id, channel, phys_num); 7265 id, channel, phys_num);
7266 break; 7266 break;
7267 case MPI_EVENT_IR2_RC_PD_STATE_CHANGED: 7267 case MPI_EVENT_IR2_RC_PD_STATE_CHANGED:
7268 snprintf(evStr, EVENT_DESCR_STR_SZ, 7268 snprintf(evStr, EVENT_DESCR_STR_SZ,
7269 "IR2: PD State Changed " 7269 "IR2: PD State Changed "
7270 "id=%d channel=%d phys_num=%d", 7270 "id=%d channel=%d phys_num=%d",
7271 id, channel, phys_num); 7271 id, channel, phys_num);
7272 break; 7272 break;
7273 case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL: 7273 case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL:
7274 snprintf(evStr, EVENT_DESCR_STR_SZ, 7274 snprintf(evStr, EVENT_DESCR_STR_SZ,
7275 "IR2: Bad Block Table Full: " 7275 "IR2: Bad Block Table Full: "
7276 "id=%d channel=%d phys_num=%d", 7276 "id=%d channel=%d phys_num=%d",
7277 id, channel, phys_num); 7277 id, channel, phys_num);
7278 break; 7278 break;
7279 case MPI_EVENT_IR2_RC_PD_INSERTED: 7279 case MPI_EVENT_IR2_RC_PD_INSERTED:
7280 snprintf(evStr, EVENT_DESCR_STR_SZ, 7280 snprintf(evStr, EVENT_DESCR_STR_SZ,
7281 "IR2: PD Inserted: " 7281 "IR2: PD Inserted: "
7282 "id=%d channel=%d phys_num=%d", 7282 "id=%d channel=%d phys_num=%d",
7283 id, channel, phys_num); 7283 id, channel, phys_num);
7284 break; 7284 break;
7285 case MPI_EVENT_IR2_RC_PD_REMOVED: 7285 case MPI_EVENT_IR2_RC_PD_REMOVED:
7286 snprintf(evStr, EVENT_DESCR_STR_SZ, 7286 snprintf(evStr, EVENT_DESCR_STR_SZ,
7287 "IR2: PD Removed: " 7287 "IR2: PD Removed: "
7288 "id=%d channel=%d phys_num=%d", 7288 "id=%d channel=%d phys_num=%d",
7289 id, channel, phys_num); 7289 id, channel, phys_num);
7290 break; 7290 break;
7291 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED: 7291 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
7292 snprintf(evStr, EVENT_DESCR_STR_SZ, 7292 snprintf(evStr, EVENT_DESCR_STR_SZ,
7293 "IR2: Foreign CFG Detected: " 7293 "IR2: Foreign CFG Detected: "
7294 "id=%d channel=%d phys_num=%d", 7294 "id=%d channel=%d phys_num=%d",
7295 id, channel, phys_num); 7295 id, channel, phys_num);
7296 break; 7296 break;
7297 case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR: 7297 case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR:
7298 snprintf(evStr, EVENT_DESCR_STR_SZ, 7298 snprintf(evStr, EVENT_DESCR_STR_SZ,
7299 "IR2: Rebuild Medium Error: " 7299 "IR2: Rebuild Medium Error: "
7300 "id=%d channel=%d phys_num=%d", 7300 "id=%d channel=%d phys_num=%d",
7301 id, channel, phys_num); 7301 id, channel, phys_num);
7302 break; 7302 break;
7303 case MPI_EVENT_IR2_RC_DUAL_PORT_ADDED: 7303 case MPI_EVENT_IR2_RC_DUAL_PORT_ADDED:
7304 snprintf(evStr, EVENT_DESCR_STR_SZ, 7304 snprintf(evStr, EVENT_DESCR_STR_SZ,
7305 "IR2: Dual Port Added: " 7305 "IR2: Dual Port Added: "
7306 "id=%d channel=%d phys_num=%d", 7306 "id=%d channel=%d phys_num=%d",
7307 id, channel, phys_num); 7307 id, channel, phys_num);
7308 break; 7308 break;
7309 case MPI_EVENT_IR2_RC_DUAL_PORT_REMOVED: 7309 case MPI_EVENT_IR2_RC_DUAL_PORT_REMOVED:
7310 snprintf(evStr, EVENT_DESCR_STR_SZ, 7310 snprintf(evStr, EVENT_DESCR_STR_SZ,
7311 "IR2: Dual Port Removed: " 7311 "IR2: Dual Port Removed: "
7312 "id=%d channel=%d phys_num=%d", 7312 "id=%d channel=%d phys_num=%d",
7313 id, channel, phys_num); 7313 id, channel, phys_num);
7314 break; 7314 break;
7315 default: 7315 default:
7316 ds = "IR2"; 7316 ds = "IR2";
7317 break; 7317 break;
7318 } 7318 }
7319 break; 7319 break;
7320 } 7320 }
7321 case MPI_EVENT_SAS_DISCOVERY: 7321 case MPI_EVENT_SAS_DISCOVERY:
7322 { 7322 {
7323 if (evData0) 7323 if (evData0)
7324 ds = "SAS Discovery: Start"; 7324 ds = "SAS Discovery: Start";
7325 else 7325 else
7326 ds = "SAS Discovery: Stop"; 7326 ds = "SAS Discovery: Stop";
7327 break; 7327 break;
7328 } 7328 }
7329 case MPI_EVENT_LOG_ENTRY_ADDED: 7329 case MPI_EVENT_LOG_ENTRY_ADDED:
7330 ds = "SAS Log Entry Added"; 7330 ds = "SAS Log Entry Added";
7331 break; 7331 break;
7332 7332
7333 case MPI_EVENT_SAS_BROADCAST_PRIMITIVE: 7333 case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
7334 { 7334 {
7335 u8 phy_num = (u8)(evData0); 7335 u8 phy_num = (u8)(evData0);
7336 u8 port_num = (u8)(evData0 >> 8); 7336 u8 port_num = (u8)(evData0 >> 8);
7337 u8 port_width = (u8)(evData0 >> 16); 7337 u8 port_width = (u8)(evData0 >> 16);
7338 u8 primative = (u8)(evData0 >> 24); 7338 u8 primative = (u8)(evData0 >> 24);
7339 snprintf(evStr, EVENT_DESCR_STR_SZ, 7339 snprintf(evStr, EVENT_DESCR_STR_SZ,
7340 "SAS Broadcase Primative: phy=%d port=%d " 7340 "SAS Broadcase Primative: phy=%d port=%d "
7341 "width=%d primative=0x%02x", 7341 "width=%d primative=0x%02x",
7342 phy_num, port_num, port_width, primative); 7342 phy_num, port_num, port_width, primative);
7343 break; 7343 break;
7344 } 7344 }
7345 7345
7346 case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE: 7346 case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE:
7347 { 7347 {
7348 u8 reason = (u8)(evData0); 7348 u8 reason = (u8)(evData0);
7349 7349
7350 switch (reason) { 7350 switch (reason) {
7351 case MPI_EVENT_SAS_INIT_RC_ADDED: 7351 case MPI_EVENT_SAS_INIT_RC_ADDED:
7352 ds = "SAS Initiator Status Change: Added"; 7352 ds = "SAS Initiator Status Change: Added";
7353 break; 7353 break;
7354 case MPI_EVENT_SAS_INIT_RC_REMOVED: 7354 case MPI_EVENT_SAS_INIT_RC_REMOVED:
7355 ds = "SAS Initiator Status Change: Deleted"; 7355 ds = "SAS Initiator Status Change: Deleted";
7356 break; 7356 break;
7357 default: 7357 default:
7358 ds = "SAS Initiator Status Change"; 7358 ds = "SAS Initiator Status Change";
7359 break; 7359 break;
7360 } 7360 }
7361 break; 7361 break;
7362 } 7362 }
7363 7363
7364 case MPI_EVENT_SAS_INIT_TABLE_OVERFLOW: 7364 case MPI_EVENT_SAS_INIT_TABLE_OVERFLOW:
7365 { 7365 {
7366 u8 max_init = (u8)(evData0); 7366 u8 max_init = (u8)(evData0);
7367 u8 current_init = (u8)(evData0 >> 8); 7367 u8 current_init = (u8)(evData0 >> 8);
7368 7368
7369 snprintf(evStr, EVENT_DESCR_STR_SZ, 7369 snprintf(evStr, EVENT_DESCR_STR_SZ,
7370 "SAS Initiator Device Table Overflow: max initiators=%02d " 7370 "SAS Initiator Device Table Overflow: max initiators=%02d "
7371 "current initators=%02d", 7371 "current initators=%02d",
7372 max_init, current_init); 7372 max_init, current_init);
7373 break; 7373 break;
7374 } 7374 }
7375 case MPI_EVENT_SAS_SMP_ERROR: 7375 case MPI_EVENT_SAS_SMP_ERROR:
7376 { 7376 {
7377 u8 status = (u8)(evData0); 7377 u8 status = (u8)(evData0);
7378 u8 port_num = (u8)(evData0 >> 8); 7378 u8 port_num = (u8)(evData0 >> 8);
7379 u8 result = (u8)(evData0 >> 16); 7379 u8 result = (u8)(evData0 >> 16);
7380 7380
7381 if (status == MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID) 7381 if (status == MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID)
7382 snprintf(evStr, EVENT_DESCR_STR_SZ, 7382 snprintf(evStr, EVENT_DESCR_STR_SZ,
7383 "SAS SMP Error: port=%d result=0x%02x", 7383 "SAS SMP Error: port=%d result=0x%02x",
7384 port_num, result); 7384 port_num, result);
7385 else if (status == MPI_EVENT_SAS_SMP_CRC_ERROR) 7385 else if (status == MPI_EVENT_SAS_SMP_CRC_ERROR)
7386 snprintf(evStr, EVENT_DESCR_STR_SZ, 7386 snprintf(evStr, EVENT_DESCR_STR_SZ,
7387 "SAS SMP Error: port=%d : CRC Error", 7387 "SAS SMP Error: port=%d : CRC Error",
7388 port_num); 7388 port_num);
7389 else if (status == MPI_EVENT_SAS_SMP_TIMEOUT) 7389 else if (status == MPI_EVENT_SAS_SMP_TIMEOUT)
7390 snprintf(evStr, EVENT_DESCR_STR_SZ, 7390 snprintf(evStr, EVENT_DESCR_STR_SZ,
7391 "SAS SMP Error: port=%d : Timeout", 7391 "SAS SMP Error: port=%d : Timeout",
7392 port_num); 7392 port_num);
7393 else if (status == MPI_EVENT_SAS_SMP_NO_DESTINATION) 7393 else if (status == MPI_EVENT_SAS_SMP_NO_DESTINATION)
7394 snprintf(evStr, EVENT_DESCR_STR_SZ, 7394 snprintf(evStr, EVENT_DESCR_STR_SZ,
7395 "SAS SMP Error: port=%d : No Destination", 7395 "SAS SMP Error: port=%d : No Destination",
7396 port_num); 7396 port_num);
7397 else if (status == MPI_EVENT_SAS_SMP_BAD_DESTINATION) 7397 else if (status == MPI_EVENT_SAS_SMP_BAD_DESTINATION)
7398 snprintf(evStr, EVENT_DESCR_STR_SZ, 7398 snprintf(evStr, EVENT_DESCR_STR_SZ,
7399 "SAS SMP Error: port=%d : Bad Destination", 7399 "SAS SMP Error: port=%d : Bad Destination",
7400 port_num); 7400 port_num);
7401 else 7401 else
7402 snprintf(evStr, EVENT_DESCR_STR_SZ, 7402 snprintf(evStr, EVENT_DESCR_STR_SZ,
7403 "SAS SMP Error: port=%d : status=0x%02x", 7403 "SAS SMP Error: port=%d : status=0x%02x",
7404 port_num, status); 7404 port_num, status);
7405 break; 7405 break;
7406 } 7406 }
7407 7407
7408 case MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE: 7408 case MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE:
7409 { 7409 {
7410 u8 reason = (u8)(evData0); 7410 u8 reason = (u8)(evData0);
7411 7411
7412 switch (reason) { 7412 switch (reason) {
7413 case MPI_EVENT_SAS_EXP_RC_ADDED: 7413 case MPI_EVENT_SAS_EXP_RC_ADDED:
7414 ds = "Expander Status Change: Added"; 7414 ds = "Expander Status Change: Added";
7415 break; 7415 break;
7416 case MPI_EVENT_SAS_EXP_RC_NOT_RESPONDING: 7416 case MPI_EVENT_SAS_EXP_RC_NOT_RESPONDING:
7417 ds = "Expander Status Change: Deleted"; 7417 ds = "Expander Status Change: Deleted";
7418 break; 7418 break;
7419 default: 7419 default:
7420 ds = "Expander Status Change"; 7420 ds = "Expander Status Change";
7421 break; 7421 break;
7422 } 7422 }
7423 break; 7423 break;
7424 } 7424 }
7425 7425
7426 /* 7426 /*
7427 * MPT base "custom" events may be added here... 7427 * MPT base "custom" events may be added here...
7428 */ 7428 */
7429 default: 7429 default:
7430 ds = "Unknown"; 7430 ds = "Unknown";
7431 break; 7431 break;
7432 } 7432 }
7433 if (ds) 7433 if (ds)
7434 strncpy(evStr, ds, EVENT_DESCR_STR_SZ); 7434 strncpy(evStr, ds, EVENT_DESCR_STR_SZ);
7435 7435
7436 7436
7437 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT 7437 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7438 "MPT event:(%02Xh) : %s\n", 7438 "MPT event:(%02Xh) : %s\n",
7439 ioc->name, event, evStr)); 7439 ioc->name, event, evStr));
7440 7440
7441 devtverboseprintk(ioc, printk(KERN_DEBUG MYNAM 7441 devtverboseprintk(ioc, printk(KERN_DEBUG MYNAM
7442 ": Event data:\n")); 7442 ": Event data:\n"));
7443 for (ii = 0; ii < le16_to_cpu(pEventReply->EventDataLength); ii++) 7443 for (ii = 0; ii < le16_to_cpu(pEventReply->EventDataLength); ii++)
7444 devtverboseprintk(ioc, printk(" %08x", 7444 devtverboseprintk(ioc, printk(" %08x",
7445 le32_to_cpu(pEventReply->Data[ii]))); 7445 le32_to_cpu(pEventReply->Data[ii])));
7446 devtverboseprintk(ioc, printk(KERN_DEBUG "\n")); 7446 devtverboseprintk(ioc, printk(KERN_DEBUG "\n"));
7447 } 7447 }
7448 #endif 7448 #endif
7449 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 7449 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7450 /** 7450 /**
7451 * ProcessEventNotification - Route EventNotificationReply to all event handlers 7451 * ProcessEventNotification - Route EventNotificationReply to all event handlers
7452 * @ioc: Pointer to MPT_ADAPTER structure 7452 * @ioc: Pointer to MPT_ADAPTER structure
7453 * @pEventReply: Pointer to EventNotification reply frame 7453 * @pEventReply: Pointer to EventNotification reply frame
7454 * @evHandlers: Pointer to integer, number of event handlers 7454 * @evHandlers: Pointer to integer, number of event handlers
7455 * 7455 *
7456 * Routes a received EventNotificationReply to all currently registered 7456 * Routes a received EventNotificationReply to all currently registered
7457 * event handlers. 7457 * event handlers.
7458 * Returns sum of event handlers return values. 7458 * Returns sum of event handlers return values.
7459 */ 7459 */
7460 static int 7460 static int
7461 ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers) 7461 ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers)
7462 { 7462 {
7463 u16 evDataLen; 7463 u16 evDataLen;
7464 u32 evData0 = 0; 7464 u32 evData0 = 0;
7465 int ii; 7465 int ii;
7466 u8 cb_idx; 7466 u8 cb_idx;
7467 int r = 0; 7467 int r = 0;
7468 int handlers = 0; 7468 int handlers = 0;
7469 u8 event; 7469 u8 event;
7470 7470
7471 /* 7471 /*
7472 * Do platform normalization of values 7472 * Do platform normalization of values
7473 */ 7473 */
7474 event = le32_to_cpu(pEventReply->Event) & 0xFF; 7474 event = le32_to_cpu(pEventReply->Event) & 0xFF;
7475 evDataLen = le16_to_cpu(pEventReply->EventDataLength); 7475 evDataLen = le16_to_cpu(pEventReply->EventDataLength);
7476 if (evDataLen) { 7476 if (evDataLen) {
7477 evData0 = le32_to_cpu(pEventReply->Data[0]); 7477 evData0 = le32_to_cpu(pEventReply->Data[0]);
7478 } 7478 }
7479 7479
7480 #ifdef CONFIG_FUSION_LOGGING 7480 #ifdef CONFIG_FUSION_LOGGING
7481 if (evDataLen) 7481 if (evDataLen)
7482 mpt_display_event_info(ioc, pEventReply); 7482 mpt_display_event_info(ioc, pEventReply);
7483 #endif 7483 #endif
7484 7484
7485 /* 7485 /*
7486 * Do general / base driver event processing 7486 * Do general / base driver event processing
7487 */ 7487 */
7488 switch(event) { 7488 switch(event) {
7489 case MPI_EVENT_EVENT_CHANGE: /* 0A */ 7489 case MPI_EVENT_EVENT_CHANGE: /* 0A */
7490 if (evDataLen) { 7490 if (evDataLen) {
7491 u8 evState = evData0 & 0xFF; 7491 u8 evState = evData0 & 0xFF;
7492 7492
7493 /* CHECKME! What if evState unexpectedly says OFF (0)? */ 7493 /* CHECKME! What if evState unexpectedly says OFF (0)? */
7494 7494
7495 /* Update EventState field in cached IocFacts */ 7495 /* Update EventState field in cached IocFacts */
7496 if (ioc->facts.Function) { 7496 if (ioc->facts.Function) {
7497 ioc->facts.EventState = evState; 7497 ioc->facts.EventState = evState;
7498 } 7498 }
7499 } 7499 }
7500 break; 7500 break;
7501 case MPI_EVENT_INTEGRATED_RAID: 7501 case MPI_EVENT_INTEGRATED_RAID:
7502 mptbase_raid_process_event_data(ioc, 7502 mptbase_raid_process_event_data(ioc,
7503 (MpiEventDataRaid_t *)pEventReply->Data); 7503 (MpiEventDataRaid_t *)pEventReply->Data);
7504 break; 7504 break;
7505 default: 7505 default:
7506 break; 7506 break;
7507 } 7507 }
7508 7508
7509 /* 7509 /*
7510 * Should this event be logged? Events are written sequentially. 7510 * Should this event be logged? Events are written sequentially.
7511 * When buffer is full, start again at the top. 7511 * When buffer is full, start again at the top.
7512 */ 7512 */
7513 if (ioc->events && (ioc->eventTypes & ( 1 << event))) { 7513 if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
7514 int idx; 7514 int idx;
7515 7515
7516 idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE; 7516 idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
7517 7517
7518 ioc->events[idx].event = event; 7518 ioc->events[idx].event = event;
7519 ioc->events[idx].eventContext = ioc->eventContext; 7519 ioc->events[idx].eventContext = ioc->eventContext;
7520 7520
7521 for (ii = 0; ii < 2; ii++) { 7521 for (ii = 0; ii < 2; ii++) {
7522 if (ii < evDataLen) 7522 if (ii < evDataLen)
7523 ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]); 7523 ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]);
7524 else 7524 else
7525 ioc->events[idx].data[ii] = 0; 7525 ioc->events[idx].data[ii] = 0;
7526 } 7526 }
7527 7527
7528 ioc->eventContext++; 7528 ioc->eventContext++;
7529 } 7529 }
7530 7530
7531 7531
7532 /* 7532 /*
7533 * Call each currently registered protocol event handler. 7533 * Call each currently registered protocol event handler.
7534 */ 7534 */
7535 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) { 7535 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7536 if (MptEvHandlers[cb_idx]) { 7536 if (MptEvHandlers[cb_idx]) {
7537 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT 7537 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7538 "Routing Event to event handler #%d\n", 7538 "Routing Event to event handler #%d\n",
7539 ioc->name, cb_idx)); 7539 ioc->name, cb_idx));
7540 r += (*(MptEvHandlers[cb_idx]))(ioc, pEventReply); 7540 r += (*(MptEvHandlers[cb_idx]))(ioc, pEventReply);
7541 handlers++; 7541 handlers++;
7542 } 7542 }
7543 } 7543 }
7544 /* FIXME? Examine results here? */ 7544 /* FIXME? Examine results here? */
7545 7545
7546 /* 7546 /*
7547 * If needed, send (a single) EventAck. 7547 * If needed, send (a single) EventAck.
7548 */ 7548 */
7549 if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) { 7549 if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
7550 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT 7550 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7551 "EventAck required\n",ioc->name)); 7551 "EventAck required\n",ioc->name));
7552 if ((ii = SendEventAck(ioc, pEventReply)) != 0) { 7552 if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
7553 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SendEventAck returned %d\n", 7553 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SendEventAck returned %d\n",
7554 ioc->name, ii)); 7554 ioc->name, ii));
7555 } 7555 }
7556 } 7556 }
7557 7557
7558 *evHandlers = handlers; 7558 *evHandlers = handlers;
7559 return r; 7559 return r;
7560 } 7560 }
7561 7561
7562 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 7562 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7563 /** 7563 /**
7564 * mpt_fc_log_info - Log information returned from Fibre Channel IOC. 7564 * mpt_fc_log_info - Log information returned from Fibre Channel IOC.
7565 * @ioc: Pointer to MPT_ADAPTER structure 7565 * @ioc: Pointer to MPT_ADAPTER structure
7566 * @log_info: U32 LogInfo reply word from the IOC 7566 * @log_info: U32 LogInfo reply word from the IOC
7567 * 7567 *
7568 * Refer to lsi/mpi_log_fc.h. 7568 * Refer to lsi/mpi_log_fc.h.
7569 */ 7569 */
7570 static void 7570 static void
7571 mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info) 7571 mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
7572 { 7572 {
7573 char *desc = "unknown"; 7573 char *desc = "unknown";
7574 7574
7575 switch (log_info & 0xFF000000) { 7575 switch (log_info & 0xFF000000) {
7576 case MPI_IOCLOGINFO_FC_INIT_BASE: 7576 case MPI_IOCLOGINFO_FC_INIT_BASE:
7577 desc = "FCP Initiator"; 7577 desc = "FCP Initiator";
7578 break; 7578 break;
7579 case MPI_IOCLOGINFO_FC_TARGET_BASE: 7579 case MPI_IOCLOGINFO_FC_TARGET_BASE:
7580 desc = "FCP Target"; 7580 desc = "FCP Target";
7581 break; 7581 break;
7582 case MPI_IOCLOGINFO_FC_LAN_BASE: 7582 case MPI_IOCLOGINFO_FC_LAN_BASE:
7583 desc = "LAN"; 7583 desc = "LAN";
7584 break; 7584 break;
7585 case MPI_IOCLOGINFO_FC_MSG_BASE: 7585 case MPI_IOCLOGINFO_FC_MSG_BASE:
7586 desc = "MPI Message Layer"; 7586 desc = "MPI Message Layer";
7587 break; 7587 break;
7588 case MPI_IOCLOGINFO_FC_LINK_BASE: 7588 case MPI_IOCLOGINFO_FC_LINK_BASE:
7589 desc = "FC Link"; 7589 desc = "FC Link";
7590 break; 7590 break;
7591 case MPI_IOCLOGINFO_FC_CTX_BASE: 7591 case MPI_IOCLOGINFO_FC_CTX_BASE:
7592 desc = "Context Manager"; 7592 desc = "Context Manager";
7593 break; 7593 break;
7594 case MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET: 7594 case MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET:
7595 desc = "Invalid Field Offset"; 7595 desc = "Invalid Field Offset";
7596 break; 7596 break;
7597 case MPI_IOCLOGINFO_FC_STATE_CHANGE: 7597 case MPI_IOCLOGINFO_FC_STATE_CHANGE:
7598 desc = "State Change Info"; 7598 desc = "State Change Info";
7599 break; 7599 break;
7600 } 7600 }
7601 7601
7602 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubClass={%s}, Value=(0x%06x)\n", 7602 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubClass={%s}, Value=(0x%06x)\n",
7603 ioc->name, log_info, desc, (log_info & 0xFFFFFF)); 7603 ioc->name, log_info, desc, (log_info & 0xFFFFFF));
7604 } 7604 }
7605 7605
7606 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 7606 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7607 /** 7607 /**
7608 * mpt_spi_log_info - Log information returned from SCSI Parallel IOC. 7608 * mpt_spi_log_info - Log information returned from SCSI Parallel IOC.
7609 * @ioc: Pointer to MPT_ADAPTER structure 7609 * @ioc: Pointer to MPT_ADAPTER structure
7610 * @log_info: U32 LogInfo word from the IOC 7610 * @log_info: U32 LogInfo word from the IOC
7611 * 7611 *
7612 * Refer to lsi/sp_log.h. 7612 * Refer to lsi/sp_log.h.
7613 */ 7613 */
7614 static void 7614 static void
7615 mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info) 7615 mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
7616 { 7616 {
7617 u32 info = log_info & 0x00FF0000; 7617 u32 info = log_info & 0x00FF0000;
7618 char *desc = "unknown"; 7618 char *desc = "unknown";
7619 7619
7620 switch (info) { 7620 switch (info) {
7621 case 0x00010000: 7621 case 0x00010000:
7622 desc = "bug! MID not found"; 7622 desc = "bug! MID not found";
7623 break; 7623 break;
7624 7624
7625 case 0x00020000: 7625 case 0x00020000:
7626 desc = "Parity Error"; 7626 desc = "Parity Error";
7627 break; 7627 break;
7628 7628
7629 case 0x00030000: 7629 case 0x00030000:
7630 desc = "ASYNC Outbound Overrun"; 7630 desc = "ASYNC Outbound Overrun";
7631 break; 7631 break;
7632 7632
7633 case 0x00040000: 7633 case 0x00040000:
7634 desc = "SYNC Offset Error"; 7634 desc = "SYNC Offset Error";
7635 break; 7635 break;
7636 7636
7637 case 0x00050000: 7637 case 0x00050000:
7638 desc = "BM Change"; 7638 desc = "BM Change";
7639 break; 7639 break;
7640 7640
7641 case 0x00060000: 7641 case 0x00060000:
7642 desc = "Msg In Overflow"; 7642 desc = "Msg In Overflow";
7643 break; 7643 break;
7644 7644
7645 case 0x00070000: 7645 case 0x00070000:
7646 desc = "DMA Error"; 7646 desc = "DMA Error";
7647 break; 7647 break;
7648 7648
7649 case 0x00080000: 7649 case 0x00080000:
7650 desc = "Outbound DMA Overrun"; 7650 desc = "Outbound DMA Overrun";
7651 break; 7651 break;
7652 7652
7653 case 0x00090000: 7653 case 0x00090000:
7654 desc = "Task Management"; 7654 desc = "Task Management";
7655 break; 7655 break;
7656 7656
7657 case 0x000A0000: 7657 case 0x000A0000:
7658 desc = "Device Problem"; 7658 desc = "Device Problem";
7659 break; 7659 break;
7660 7660
7661 case 0x000B0000: 7661 case 0x000B0000:
7662 desc = "Invalid Phase Change"; 7662 desc = "Invalid Phase Change";
7663 break; 7663 break;
7664 7664
7665 case 0x000C0000: 7665 case 0x000C0000:
7666 desc = "Untagged Table Size"; 7666 desc = "Untagged Table Size";
7667 break; 7667 break;
7668 7668
7669 } 7669 }
7670 7670
7671 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc); 7671 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
7672 } 7672 }
7673 7673
7674 /* strings for sas loginfo */ 7674 /* strings for sas loginfo */
7675 static char *originator_str[] = { 7675 static char *originator_str[] = {
7676 "IOP", /* 00h */ 7676 "IOP", /* 00h */
7677 "PL", /* 01h */ 7677 "PL", /* 01h */
7678 "IR" /* 02h */ 7678 "IR" /* 02h */
7679 }; 7679 };
7680 static char *iop_code_str[] = { 7680 static char *iop_code_str[] = {
7681 NULL, /* 00h */ 7681 NULL, /* 00h */
7682 "Invalid SAS Address", /* 01h */ 7682 "Invalid SAS Address", /* 01h */
7683 NULL, /* 02h */ 7683 NULL, /* 02h */
7684 "Invalid Page", /* 03h */ 7684 "Invalid Page", /* 03h */
7685 "Diag Message Error", /* 04h */ 7685 "Diag Message Error", /* 04h */
7686 "Task Terminated", /* 05h */ 7686 "Task Terminated", /* 05h */
7687 "Enclosure Management", /* 06h */ 7687 "Enclosure Management", /* 06h */
7688 "Target Mode" /* 07h */ 7688 "Target Mode" /* 07h */
7689 }; 7689 };
7690 static char *pl_code_str[] = { 7690 static char *pl_code_str[] = {
7691 NULL, /* 00h */ 7691 NULL, /* 00h */
7692 "Open Failure", /* 01h */ 7692 "Open Failure", /* 01h */
7693 "Invalid Scatter Gather List", /* 02h */ 7693 "Invalid Scatter Gather List", /* 02h */
7694 "Wrong Relative Offset or Frame Length", /* 03h */ 7694 "Wrong Relative Offset or Frame Length", /* 03h */
7695 "Frame Transfer Error", /* 04h */ 7695 "Frame Transfer Error", /* 04h */
7696 "Transmit Frame Connected Low", /* 05h */ 7696 "Transmit Frame Connected Low", /* 05h */
7697 "SATA Non-NCQ RW Error Bit Set", /* 06h */ 7697 "SATA Non-NCQ RW Error Bit Set", /* 06h */
7698 "SATA Read Log Receive Data Error", /* 07h */ 7698 "SATA Read Log Receive Data Error", /* 07h */
7699 "SATA NCQ Fail All Commands After Error", /* 08h */ 7699 "SATA NCQ Fail All Commands After Error", /* 08h */
7700 "SATA Error in Receive Set Device Bit FIS", /* 09h */ 7700 "SATA Error in Receive Set Device Bit FIS", /* 09h */
7701 "Receive Frame Invalid Message", /* 0Ah */ 7701 "Receive Frame Invalid Message", /* 0Ah */
7702 "Receive Context Message Valid Error", /* 0Bh */ 7702 "Receive Context Message Valid Error", /* 0Bh */
7703 "Receive Frame Current Frame Error", /* 0Ch */ 7703 "Receive Frame Current Frame Error", /* 0Ch */
7704 "SATA Link Down", /* 0Dh */ 7704 "SATA Link Down", /* 0Dh */
7705 "Discovery SATA Init W IOS", /* 0Eh */ 7705 "Discovery SATA Init W IOS", /* 0Eh */
7706 "Config Invalid Page", /* 0Fh */ 7706 "Config Invalid Page", /* 0Fh */
7707 "Discovery SATA Init Timeout", /* 10h */ 7707 "Discovery SATA Init Timeout", /* 10h */
7708 "Reset", /* 11h */ 7708 "Reset", /* 11h */
7709 "Abort", /* 12h */ 7709 "Abort", /* 12h */
7710 "IO Not Yet Executed", /* 13h */ 7710 "IO Not Yet Executed", /* 13h */
7711 "IO Executed", /* 14h */ 7711 "IO Executed", /* 14h */
7712 "Persistent Reservation Out Not Affiliation " 7712 "Persistent Reservation Out Not Affiliation "
7713 "Owner", /* 15h */ 7713 "Owner", /* 15h */
7714 "Open Transmit DMA Abort", /* 16h */ 7714 "Open Transmit DMA Abort", /* 16h */
7715 "IO Device Missing Delay Retry", /* 17h */ 7715 "IO Device Missing Delay Retry", /* 17h */
7716 "IO Cancelled Due to Recieve Error", /* 18h */ 7716 "IO Cancelled Due to Recieve Error", /* 18h */
7717 NULL, /* 19h */ 7717 NULL, /* 19h */
7718 NULL, /* 1Ah */ 7718 NULL, /* 1Ah */
7719 NULL, /* 1Bh */ 7719 NULL, /* 1Bh */
7720 NULL, /* 1Ch */ 7720 NULL, /* 1Ch */
7721 NULL, /* 1Dh */ 7721 NULL, /* 1Dh */
7722 NULL, /* 1Eh */ 7722 NULL, /* 1Eh */
7723 NULL, /* 1Fh */ 7723 NULL, /* 1Fh */
7724 "Enclosure Management" /* 20h */ 7724 "Enclosure Management" /* 20h */
7725 }; 7725 };
7726 static char *ir_code_str[] = { 7726 static char *ir_code_str[] = {
7727 "Raid Action Error", /* 00h */ 7727 "Raid Action Error", /* 00h */
7728 NULL, /* 00h */ 7728 NULL, /* 00h */
7729 NULL, /* 01h */ 7729 NULL, /* 01h */
7730 NULL, /* 02h */ 7730 NULL, /* 02h */
7731 NULL, /* 03h */ 7731 NULL, /* 03h */
7732 NULL, /* 04h */ 7732 NULL, /* 04h */
7733 NULL, /* 05h */ 7733 NULL, /* 05h */
7734 NULL, /* 06h */ 7734 NULL, /* 06h */
7735 NULL /* 07h */ 7735 NULL /* 07h */
7736 }; 7736 };
7737 static char *raid_sub_code_str[] = { 7737 static char *raid_sub_code_str[] = {
7738 NULL, /* 00h */ 7738 NULL, /* 00h */
7739 "Volume Creation Failed: Data Passed too " 7739 "Volume Creation Failed: Data Passed too "
7740 "Large", /* 01h */ 7740 "Large", /* 01h */
7741 "Volume Creation Failed: Duplicate Volumes " 7741 "Volume Creation Failed: Duplicate Volumes "
7742 "Attempted", /* 02h */ 7742 "Attempted", /* 02h */
7743 "Volume Creation Failed: Max Number " 7743 "Volume Creation Failed: Max Number "
7744 "Supported Volumes Exceeded", /* 03h */ 7744 "Supported Volumes Exceeded", /* 03h */
7745 "Volume Creation Failed: DMA Error", /* 04h */ 7745 "Volume Creation Failed: DMA Error", /* 04h */
7746 "Volume Creation Failed: Invalid Volume Type", /* 05h */ 7746 "Volume Creation Failed: Invalid Volume Type", /* 05h */
7747 "Volume Creation Failed: Error Reading " 7747 "Volume Creation Failed: Error Reading "
7748 "MFG Page 4", /* 06h */ 7748 "MFG Page 4", /* 06h */
7749 "Volume Creation Failed: Creating Internal " 7749 "Volume Creation Failed: Creating Internal "
7750 "Structures", /* 07h */ 7750 "Structures", /* 07h */
7751 NULL, /* 08h */ 7751 NULL, /* 08h */
7752 NULL, /* 09h */ 7752 NULL, /* 09h */
7753 NULL, /* 0Ah */ 7753 NULL, /* 0Ah */
7754 NULL, /* 0Bh */ 7754 NULL, /* 0Bh */
7755 NULL, /* 0Ch */ 7755 NULL, /* 0Ch */
7756 NULL, /* 0Dh */ 7756 NULL, /* 0Dh */
7757 NULL, /* 0Eh */ 7757 NULL, /* 0Eh */
7758 NULL, /* 0Fh */ 7758 NULL, /* 0Fh */
7759 "Activation failed: Already Active Volume", /* 10h */ 7759 "Activation failed: Already Active Volume", /* 10h */
7760 "Activation failed: Unsupported Volume Type", /* 11h */ 7760 "Activation failed: Unsupported Volume Type", /* 11h */
7761 "Activation failed: Too Many Active Volumes", /* 12h */ 7761 "Activation failed: Too Many Active Volumes", /* 12h */
7762 "Activation failed: Volume ID in Use", /* 13h */ 7762 "Activation failed: Volume ID in Use", /* 13h */
7763 "Activation failed: Reported Failure", /* 14h */ 7763 "Activation failed: Reported Failure", /* 14h */
7764 "Activation failed: Importing a Volume", /* 15h */ 7764 "Activation failed: Importing a Volume", /* 15h */
7765 NULL, /* 16h */ 7765 NULL, /* 16h */
7766 NULL, /* 17h */ 7766 NULL, /* 17h */
7767 NULL, /* 18h */ 7767 NULL, /* 18h */
7768 NULL, /* 19h */ 7768 NULL, /* 19h */
7769 NULL, /* 1Ah */ 7769 NULL, /* 1Ah */
7770 NULL, /* 1Bh */ 7770 NULL, /* 1Bh */
7771 NULL, /* 1Ch */ 7771 NULL, /* 1Ch */
7772 NULL, /* 1Dh */ 7772 NULL, /* 1Dh */
7773 NULL, /* 1Eh */ 7773 NULL, /* 1Eh */
7774 NULL, /* 1Fh */ 7774 NULL, /* 1Fh */
7775 "Phys Disk failed: Too Many Phys Disks", /* 20h */ 7775 "Phys Disk failed: Too Many Phys Disks", /* 20h */
7776 "Phys Disk failed: Data Passed too Large", /* 21h */ 7776 "Phys Disk failed: Data Passed too Large", /* 21h */
7777 "Phys Disk failed: DMA Error", /* 22h */ 7777 "Phys Disk failed: DMA Error", /* 22h */
7778 "Phys Disk failed: Invalid <channel:id>", /* 23h */ 7778 "Phys Disk failed: Invalid <channel:id>", /* 23h */
7779 "Phys Disk failed: Creating Phys Disk Config " 7779 "Phys Disk failed: Creating Phys Disk Config "
7780 "Page", /* 24h */ 7780 "Page", /* 24h */
7781 NULL, /* 25h */ 7781 NULL, /* 25h */
7782 NULL, /* 26h */ 7782 NULL, /* 26h */
7783 NULL, /* 27h */ 7783 NULL, /* 27h */
7784 NULL, /* 28h */ 7784 NULL, /* 28h */
7785 NULL, /* 29h */ 7785 NULL, /* 29h */
7786 NULL, /* 2Ah */ 7786 NULL, /* 2Ah */
7787 NULL, /* 2Bh */ 7787 NULL, /* 2Bh */
7788 NULL, /* 2Ch */ 7788 NULL, /* 2Ch */
7789 NULL, /* 2Dh */ 7789 NULL, /* 2Dh */
7790 NULL, /* 2Eh */ 7790 NULL, /* 2Eh */
7791 NULL, /* 2Fh */ 7791 NULL, /* 2Fh */
7792 "Compatibility Error: IR Disabled", /* 30h */ 7792 "Compatibility Error: IR Disabled", /* 30h */
7793 "Compatibility Error: Inquiry Comand Failed", /* 31h */ 7793 "Compatibility Error: Inquiry Comand Failed", /* 31h */
7794 "Compatibility Error: Device not Direct Access " 7794 "Compatibility Error: Device not Direct Access "
7795 "Device ", /* 32h */ 7795 "Device ", /* 32h */
7796 "Compatibility Error: Removable Device Found", /* 33h */ 7796 "Compatibility Error: Removable Device Found", /* 33h */
7797 "Compatibility Error: Device SCSI Version not " 7797 "Compatibility Error: Device SCSI Version not "
7798 "2 or Higher", /* 34h */ 7798 "2 or Higher", /* 34h */
7799 "Compatibility Error: SATA Device, 48 BIT LBA " 7799 "Compatibility Error: SATA Device, 48 BIT LBA "
7800 "not Supported", /* 35h */ 7800 "not Supported", /* 35h */
7801 "Compatibility Error: Device doesn't have " 7801 "Compatibility Error: Device doesn't have "
7802 "512 Byte Block Sizes", /* 36h */ 7802 "512 Byte Block Sizes", /* 36h */
7803 "Compatibility Error: Volume Type Check Failed", /* 37h */ 7803 "Compatibility Error: Volume Type Check Failed", /* 37h */
7804 "Compatibility Error: Volume Type is " 7804 "Compatibility Error: Volume Type is "
7805 "Unsupported by FW", /* 38h */ 7805 "Unsupported by FW", /* 38h */
7806 "Compatibility Error: Disk Drive too Small for " 7806 "Compatibility Error: Disk Drive too Small for "
7807 "use in Volume", /* 39h */ 7807 "use in Volume", /* 39h */
7808 "Compatibility Error: Phys Disk for Create " 7808 "Compatibility Error: Phys Disk for Create "
7809 "Volume not Found", /* 3Ah */ 7809 "Volume not Found", /* 3Ah */
7810 "Compatibility Error: Too Many or too Few " 7810 "Compatibility Error: Too Many or too Few "
7811 "Disks for Volume Type", /* 3Bh */ 7811 "Disks for Volume Type", /* 3Bh */
7812 "Compatibility Error: Disk stripe Sizes " 7812 "Compatibility Error: Disk stripe Sizes "
7813 "Must be 64KB", /* 3Ch */ 7813 "Must be 64KB", /* 3Ch */
7814 "Compatibility Error: IME Size Limited to < 2TB", /* 3Dh */ 7814 "Compatibility Error: IME Size Limited to < 2TB", /* 3Dh */
7815 }; 7815 };
7816 7816
7817 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 7817 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7818 /** 7818 /**
7819 * mpt_sas_log_info - Log information returned from SAS IOC. 7819 * mpt_sas_log_info - Log information returned from SAS IOC.
7820 * @ioc: Pointer to MPT_ADAPTER structure 7820 * @ioc: Pointer to MPT_ADAPTER structure
7821 * @log_info: U32 LogInfo reply word from the IOC 7821 * @log_info: U32 LogInfo reply word from the IOC
7822 * 7822 *
7823 * Refer to lsi/mpi_log_sas.h. 7823 * Refer to lsi/mpi_log_sas.h.
7824 **/ 7824 **/
7825 static void 7825 static void
7826 mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info) 7826 mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info)
7827 { 7827 {
7828 union loginfo_type { 7828 union loginfo_type {
7829 u32 loginfo; 7829 u32 loginfo;
7830 struct { 7830 struct {
7831 u32 subcode:16; 7831 u32 subcode:16;
7832 u32 code:8; 7832 u32 code:8;
7833 u32 originator:4; 7833 u32 originator:4;
7834 u32 bus_type:4; 7834 u32 bus_type:4;
7835 }dw; 7835 }dw;
7836 }; 7836 };
7837 union loginfo_type sas_loginfo; 7837 union loginfo_type sas_loginfo;
7838 char *originator_desc = NULL; 7838 char *originator_desc = NULL;
7839 char *code_desc = NULL; 7839 char *code_desc = NULL;
7840 char *sub_code_desc = NULL; 7840 char *sub_code_desc = NULL;
7841 7841
7842 sas_loginfo.loginfo = log_info; 7842 sas_loginfo.loginfo = log_info;
7843 if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) && 7843 if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) &&
7844 (sas_loginfo.dw.originator < ARRAY_SIZE(originator_str))) 7844 (sas_loginfo.dw.originator < ARRAY_SIZE(originator_str)))
7845 return; 7845 return;
7846 7846
7847 originator_desc = originator_str[sas_loginfo.dw.originator]; 7847 originator_desc = originator_str[sas_loginfo.dw.originator];
7848 7848
7849 switch (sas_loginfo.dw.originator) { 7849 switch (sas_loginfo.dw.originator) {
7850 7850
7851 case 0: /* IOP */ 7851 case 0: /* IOP */
7852 if (sas_loginfo.dw.code < 7852 if (sas_loginfo.dw.code <
7853 ARRAY_SIZE(iop_code_str)) 7853 ARRAY_SIZE(iop_code_str))
7854 code_desc = iop_code_str[sas_loginfo.dw.code]; 7854 code_desc = iop_code_str[sas_loginfo.dw.code];
7855 break; 7855 break;
7856 case 1: /* PL */ 7856 case 1: /* PL */
7857 if (sas_loginfo.dw.code < 7857 if (sas_loginfo.dw.code <
7858 ARRAY_SIZE(pl_code_str)) 7858 ARRAY_SIZE(pl_code_str))
7859 code_desc = pl_code_str[sas_loginfo.dw.code]; 7859 code_desc = pl_code_str[sas_loginfo.dw.code];
7860 break; 7860 break;
7861 case 2: /* IR */ 7861 case 2: /* IR */
7862 if (sas_loginfo.dw.code >= 7862 if (sas_loginfo.dw.code >=
7863 ARRAY_SIZE(ir_code_str)) 7863 ARRAY_SIZE(ir_code_str))
7864 break; 7864 break;
7865 code_desc = ir_code_str[sas_loginfo.dw.code]; 7865 code_desc = ir_code_str[sas_loginfo.dw.code];
7866 if (sas_loginfo.dw.subcode >= 7866 if (sas_loginfo.dw.subcode >=
7867 ARRAY_SIZE(raid_sub_code_str)) 7867 ARRAY_SIZE(raid_sub_code_str))
7868 break; 7868 break;
7869 if (sas_loginfo.dw.code == 0) 7869 if (sas_loginfo.dw.code == 0)
7870 sub_code_desc = 7870 sub_code_desc =
7871 raid_sub_code_str[sas_loginfo.dw.subcode]; 7871 raid_sub_code_str[sas_loginfo.dw.subcode];
7872 break; 7872 break;
7873 default: 7873 default:
7874 return; 7874 return;
7875 } 7875 }
7876 7876
7877 if (sub_code_desc != NULL) 7877 if (sub_code_desc != NULL)
7878 printk(MYIOC_s_INFO_FMT 7878 printk(MYIOC_s_INFO_FMT
7879 "LogInfo(0x%08x): Originator={%s}, Code={%s}," 7879 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
7880 " SubCode={%s}\n", 7880 " SubCode={%s}\n",
7881 ioc->name, log_info, originator_desc, code_desc, 7881 ioc->name, log_info, originator_desc, code_desc,
7882 sub_code_desc); 7882 sub_code_desc);
7883 else if (code_desc != NULL) 7883 else if (code_desc != NULL)
7884 printk(MYIOC_s_INFO_FMT 7884 printk(MYIOC_s_INFO_FMT
7885 "LogInfo(0x%08x): Originator={%s}, Code={%s}," 7885 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
7886 " SubCode(0x%04x)\n", 7886 " SubCode(0x%04x)\n",
7887 ioc->name, log_info, originator_desc, code_desc, 7887 ioc->name, log_info, originator_desc, code_desc,
7888 sas_loginfo.dw.subcode); 7888 sas_loginfo.dw.subcode);
7889 else 7889 else
7890 printk(MYIOC_s_INFO_FMT 7890 printk(MYIOC_s_INFO_FMT
7891 "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x)," 7891 "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
7892 " SubCode(0x%04x)\n", 7892 " SubCode(0x%04x)\n",
7893 ioc->name, log_info, originator_desc, 7893 ioc->name, log_info, originator_desc,
7894 sas_loginfo.dw.code, sas_loginfo.dw.subcode); 7894 sas_loginfo.dw.code, sas_loginfo.dw.subcode);
7895 } 7895 }
7896 7896
7897 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 7897 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7898 /** 7898 /**
7899 * mpt_iocstatus_info_config - IOCSTATUS information for config pages 7899 * mpt_iocstatus_info_config - IOCSTATUS information for config pages
7900 * @ioc: Pointer to MPT_ADAPTER structure 7900 * @ioc: Pointer to MPT_ADAPTER structure
7901 * @ioc_status: U32 IOCStatus word from IOC 7901 * @ioc_status: U32 IOCStatus word from IOC
7902 * @mf: Pointer to MPT request frame 7902 * @mf: Pointer to MPT request frame
7903 * 7903 *
7904 * Refer to lsi/mpi.h. 7904 * Refer to lsi/mpi.h.
7905 **/ 7905 **/
7906 static void 7906 static void
7907 mpt_iocstatus_info_config(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf) 7907 mpt_iocstatus_info_config(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
7908 { 7908 {
7909 Config_t *pReq = (Config_t *)mf; 7909 Config_t *pReq = (Config_t *)mf;
7910 char extend_desc[EVENT_DESCR_STR_SZ]; 7910 char extend_desc[EVENT_DESCR_STR_SZ];
7911 char *desc = NULL; 7911 char *desc = NULL;
7912 u32 form; 7912 u32 form;
7913 u8 page_type; 7913 u8 page_type;
7914 7914
7915 if (pReq->Header.PageType == MPI_CONFIG_PAGETYPE_EXTENDED) 7915 if (pReq->Header.PageType == MPI_CONFIG_PAGETYPE_EXTENDED)
7916 page_type = pReq->ExtPageType; 7916 page_type = pReq->ExtPageType;
7917 else 7917 else
7918 page_type = pReq->Header.PageType; 7918 page_type = pReq->Header.PageType;
7919 7919
7920 /* 7920 /*
7921 * ignore invalid page messages for GET_NEXT_HANDLE 7921 * ignore invalid page messages for GET_NEXT_HANDLE
7922 */ 7922 */
7923 form = le32_to_cpu(pReq->PageAddress); 7923 form = le32_to_cpu(pReq->PageAddress);
7924 if (ioc_status == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) { 7924 if (ioc_status == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
7925 if (page_type == MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE || 7925 if (page_type == MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE ||
7926 page_type == MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER || 7926 page_type == MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER ||
7927 page_type == MPI_CONFIG_EXTPAGETYPE_ENCLOSURE) { 7927 page_type == MPI_CONFIG_EXTPAGETYPE_ENCLOSURE) {
7928 if ((form >> MPI_SAS_DEVICE_PGAD_FORM_SHIFT) == 7928 if ((form >> MPI_SAS_DEVICE_PGAD_FORM_SHIFT) ==
7929 MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE) 7929 MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE)
7930 return; 7930 return;
7931 } 7931 }
7932 if (page_type == MPI_CONFIG_PAGETYPE_FC_DEVICE) 7932 if (page_type == MPI_CONFIG_PAGETYPE_FC_DEVICE)
7933 if ((form & MPI_FC_DEVICE_PGAD_FORM_MASK) == 7933 if ((form & MPI_FC_DEVICE_PGAD_FORM_MASK) ==
7934 MPI_FC_DEVICE_PGAD_FORM_NEXT_DID) 7934 MPI_FC_DEVICE_PGAD_FORM_NEXT_DID)
7935 return; 7935 return;
7936 } 7936 }
7937 7937
7938 snprintf(extend_desc, EVENT_DESCR_STR_SZ, 7938 snprintf(extend_desc, EVENT_DESCR_STR_SZ,
7939 "type=%02Xh, page=%02Xh, action=%02Xh, form=%08Xh", 7939 "type=%02Xh, page=%02Xh, action=%02Xh, form=%08Xh",
7940 page_type, pReq->Header.PageNumber, pReq->Action, form); 7940 page_type, pReq->Header.PageNumber, pReq->Action, form);
7941 7941
7942 switch (ioc_status) { 7942 switch (ioc_status) {
7943 7943
7944 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */ 7944 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
7945 desc = "Config Page Invalid Action"; 7945 desc = "Config Page Invalid Action";
7946 break; 7946 break;
7947 7947
7948 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */ 7948 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
7949 desc = "Config Page Invalid Type"; 7949 desc = "Config Page Invalid Type";
7950 break; 7950 break;
7951 7951
7952 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */ 7952 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
7953 desc = "Config Page Invalid Page"; 7953 desc = "Config Page Invalid Page";
7954 break; 7954 break;
7955 7955
7956 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */ 7956 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
7957 desc = "Config Page Invalid Data"; 7957 desc = "Config Page Invalid Data";
7958 break; 7958 break;
7959 7959
7960 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */ 7960 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
7961 desc = "Config Page No Defaults"; 7961 desc = "Config Page No Defaults";
7962 break; 7962 break;
7963 7963
7964 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */ 7964 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
7965 desc = "Config Page Can't Commit"; 7965 desc = "Config Page Can't Commit";
7966 break; 7966 break;
7967 } 7967 }
7968 7968
7969 if (!desc) 7969 if (!desc)
7970 return; 7970 return;
7971 7971
7972 dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s: %s\n", 7972 dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s: %s\n",
7973 ioc->name, ioc_status, desc, extend_desc)); 7973 ioc->name, ioc_status, desc, extend_desc));
7974 } 7974 }
7975 7975
7976 /** 7976 /**
7977 * mpt_iocstatus_info - IOCSTATUS information returned from IOC. 7977 * mpt_iocstatus_info - IOCSTATUS information returned from IOC.
7978 * @ioc: Pointer to MPT_ADAPTER structure 7978 * @ioc: Pointer to MPT_ADAPTER structure
7979 * @ioc_status: U32 IOCStatus word from IOC 7979 * @ioc_status: U32 IOCStatus word from IOC
7980 * @mf: Pointer to MPT request frame 7980 * @mf: Pointer to MPT request frame
7981 * 7981 *
7982 * Refer to lsi/mpi.h. 7982 * Refer to lsi/mpi.h.
7983 **/ 7983 **/
7984 static void 7984 static void
7985 mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf) 7985 mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
7986 { 7986 {
7987 u32 status = ioc_status & MPI_IOCSTATUS_MASK; 7987 u32 status = ioc_status & MPI_IOCSTATUS_MASK;
7988 char *desc = NULL; 7988 char *desc = NULL;
7989 7989
7990 switch (status) { 7990 switch (status) {
7991 7991
7992 /****************************************************************************/ 7992 /****************************************************************************/
7993 /* Common IOCStatus values for all replies */ 7993 /* Common IOCStatus values for all replies */
7994 /****************************************************************************/ 7994 /****************************************************************************/
7995 7995
7996 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */ 7996 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
7997 desc = "Invalid Function"; 7997 desc = "Invalid Function";
7998 break; 7998 break;
7999 7999
8000 case MPI_IOCSTATUS_BUSY: /* 0x0002 */ 8000 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
8001 desc = "Busy"; 8001 desc = "Busy";
8002 break; 8002 break;
8003 8003
8004 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */ 8004 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
8005 desc = "Invalid SGL"; 8005 desc = "Invalid SGL";
8006 break; 8006 break;
8007 8007
8008 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */ 8008 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
8009 desc = "Internal Error"; 8009 desc = "Internal Error";
8010 break; 8010 break;
8011 8011
8012 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */ 8012 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
8013 desc = "Reserved"; 8013 desc = "Reserved";
8014 break; 8014 break;
8015 8015
8016 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */ 8016 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
8017 desc = "Insufficient Resources"; 8017 desc = "Insufficient Resources";
8018 break; 8018 break;
8019 8019
8020 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */ 8020 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
8021 desc = "Invalid Field"; 8021 desc = "Invalid Field";
8022 break; 8022 break;
8023 8023
8024 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */ 8024 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
8025 desc = "Invalid State"; 8025 desc = "Invalid State";
8026 break; 8026 break;
8027 8027
8028 /****************************************************************************/ 8028 /****************************************************************************/
8029 /* Config IOCStatus values */ 8029 /* Config IOCStatus values */
8030 /****************************************************************************/ 8030 /****************************************************************************/
8031 8031
8032 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */ 8032 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
8033 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */ 8033 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
8034 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */ 8034 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
8035 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */ 8035 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
8036 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */ 8036 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
8037 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */ 8037 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
8038 mpt_iocstatus_info_config(ioc, status, mf); 8038 mpt_iocstatus_info_config(ioc, status, mf);
8039 break; 8039 break;
8040 8040
8041 /****************************************************************************/ 8041 /****************************************************************************/
8042 /* SCSIIO Reply (SPI, FCP, SAS) initiator values */ 8042 /* SCSIIO Reply (SPI, FCP, SAS) initiator values */
8043 /* */ 8043 /* */
8044 /* Look at mptscsih_iocstatus_info_scsiio in mptscsih.c */ 8044 /* Look at mptscsih_iocstatus_info_scsiio in mptscsih.c */
8045 /* */ 8045 /* */
8046 /****************************************************************************/ 8046 /****************************************************************************/
8047 8047
8048 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */ 8048 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
8049 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */ 8049 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
8050 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */ 8050 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
8051 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */ 8051 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
8052 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */ 8052 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
8053 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */ 8053 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
8054 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */ 8054 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
8055 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */ 8055 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
8056 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */ 8056 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
8057 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */ 8057 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
8058 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */ 8058 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
8059 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */ 8059 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
8060 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */ 8060 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
8061 break; 8061 break;
8062 8062
8063 /****************************************************************************/ 8063 /****************************************************************************/
8064 /* SCSI Target values */ 8064 /* SCSI Target values */
8065 /****************************************************************************/ 8065 /****************************************************************************/
8066 8066
8067 case MPI_IOCSTATUS_TARGET_PRIORITY_IO: /* 0x0060 */ 8067 case MPI_IOCSTATUS_TARGET_PRIORITY_IO: /* 0x0060 */
8068 desc = "Target: Priority IO"; 8068 desc = "Target: Priority IO";
8069 break; 8069 break;
8070 8070
8071 case MPI_IOCSTATUS_TARGET_INVALID_PORT: /* 0x0061 */ 8071 case MPI_IOCSTATUS_TARGET_INVALID_PORT: /* 0x0061 */
8072 desc = "Target: Invalid Port"; 8072 desc = "Target: Invalid Port";
8073 break; 8073 break;
8074 8074
8075 case MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX: /* 0x0062 */ 8075 case MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX: /* 0x0062 */
8076 desc = "Target Invalid IO Index:"; 8076 desc = "Target Invalid IO Index:";
8077 break; 8077 break;
8078 8078
8079 case MPI_IOCSTATUS_TARGET_ABORTED: /* 0x0063 */ 8079 case MPI_IOCSTATUS_TARGET_ABORTED: /* 0x0063 */
8080 desc = "Target: Aborted"; 8080 desc = "Target: Aborted";
8081 break; 8081 break;
8082 8082
8083 case MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE: /* 0x0064 */ 8083 case MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE: /* 0x0064 */
8084 desc = "Target: No Conn Retryable"; 8084 desc = "Target: No Conn Retryable";
8085 break; 8085 break;
8086 8086
8087 case MPI_IOCSTATUS_TARGET_NO_CONNECTION: /* 0x0065 */ 8087 case MPI_IOCSTATUS_TARGET_NO_CONNECTION: /* 0x0065 */
8088 desc = "Target: No Connection"; 8088 desc = "Target: No Connection";
8089 break; 8089 break;
8090 8090
8091 case MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH: /* 0x006A */ 8091 case MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH: /* 0x006A */
8092 desc = "Target: Transfer Count Mismatch"; 8092 desc = "Target: Transfer Count Mismatch";
8093 break; 8093 break;
8094 8094
8095 case MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT: /* 0x006B */ 8095 case MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT: /* 0x006B */
8096 desc = "Target: STS Data not Sent"; 8096 desc = "Target: STS Data not Sent";
8097 break; 8097 break;
8098 8098
8099 case MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR: /* 0x006D */ 8099 case MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR: /* 0x006D */
8100 desc = "Target: Data Offset Error"; 8100 desc = "Target: Data Offset Error";
8101 break; 8101 break;
8102 8102
8103 case MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA: /* 0x006E */ 8103 case MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA: /* 0x006E */
8104 desc = "Target: Too Much Write Data"; 8104 desc = "Target: Too Much Write Data";
8105 break; 8105 break;
8106 8106
8107 case MPI_IOCSTATUS_TARGET_IU_TOO_SHORT: /* 0x006F */ 8107 case MPI_IOCSTATUS_TARGET_IU_TOO_SHORT: /* 0x006F */
8108 desc = "Target: IU Too Short"; 8108 desc = "Target: IU Too Short";
8109 break; 8109 break;
8110 8110
8111 case MPI_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT: /* 0x0070 */ 8111 case MPI_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT: /* 0x0070 */
8112 desc = "Target: ACK NAK Timeout"; 8112 desc = "Target: ACK NAK Timeout";
8113 break; 8113 break;
8114 8114
8115 case MPI_IOCSTATUS_TARGET_NAK_RECEIVED: /* 0x0071 */ 8115 case MPI_IOCSTATUS_TARGET_NAK_RECEIVED: /* 0x0071 */
8116 desc = "Target: Nak Received"; 8116 desc = "Target: Nak Received";
8117 break; 8117 break;
8118 8118
8119 /****************************************************************************/ 8119 /****************************************************************************/
8120 /* Fibre Channel Direct Access values */ 8120 /* Fibre Channel Direct Access values */
8121 /****************************************************************************/ 8121 /****************************************************************************/
8122 8122
8123 case MPI_IOCSTATUS_FC_ABORTED: /* 0x0066 */ 8123 case MPI_IOCSTATUS_FC_ABORTED: /* 0x0066 */
8124 desc = "FC: Aborted"; 8124 desc = "FC: Aborted";
8125 break; 8125 break;
8126 8126
8127 case MPI_IOCSTATUS_FC_RX_ID_INVALID: /* 0x0067 */ 8127 case MPI_IOCSTATUS_FC_RX_ID_INVALID: /* 0x0067 */
8128 desc = "FC: RX ID Invalid"; 8128 desc = "FC: RX ID Invalid";
8129 break; 8129 break;
8130 8130
8131 case MPI_IOCSTATUS_FC_DID_INVALID: /* 0x0068 */ 8131 case MPI_IOCSTATUS_FC_DID_INVALID: /* 0x0068 */
8132 desc = "FC: DID Invalid"; 8132 desc = "FC: DID Invalid";
8133 break; 8133 break;
8134 8134
8135 case MPI_IOCSTATUS_FC_NODE_LOGGED_OUT: /* 0x0069 */ 8135 case MPI_IOCSTATUS_FC_NODE_LOGGED_OUT: /* 0x0069 */
8136 desc = "FC: Node Logged Out"; 8136 desc = "FC: Node Logged Out";
8137 break; 8137 break;
8138 8138
8139 case MPI_IOCSTATUS_FC_EXCHANGE_CANCELED: /* 0x006C */ 8139 case MPI_IOCSTATUS_FC_EXCHANGE_CANCELED: /* 0x006C */
8140 desc = "FC: Exchange Canceled"; 8140 desc = "FC: Exchange Canceled";
8141 break; 8141 break;
8142 8142
8143 /****************************************************************************/ 8143 /****************************************************************************/
8144 /* LAN values */ 8144 /* LAN values */
8145 /****************************************************************************/ 8145 /****************************************************************************/
8146 8146
8147 case MPI_IOCSTATUS_LAN_DEVICE_NOT_FOUND: /* 0x0080 */ 8147 case MPI_IOCSTATUS_LAN_DEVICE_NOT_FOUND: /* 0x0080 */
8148 desc = "LAN: Device not Found"; 8148 desc = "LAN: Device not Found";
8149 break; 8149 break;
8150 8150
8151 case MPI_IOCSTATUS_LAN_DEVICE_FAILURE: /* 0x0081 */ 8151 case MPI_IOCSTATUS_LAN_DEVICE_FAILURE: /* 0x0081 */
8152 desc = "LAN: Device Failure"; 8152 desc = "LAN: Device Failure";
8153 break; 8153 break;
8154 8154
8155 case MPI_IOCSTATUS_LAN_TRANSMIT_ERROR: /* 0x0082 */ 8155 case MPI_IOCSTATUS_LAN_TRANSMIT_ERROR: /* 0x0082 */
8156 desc = "LAN: Transmit Error"; 8156 desc = "LAN: Transmit Error";
8157 break; 8157 break;
8158 8158
8159 case MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED: /* 0x0083 */ 8159 case MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED: /* 0x0083 */
8160 desc = "LAN: Transmit Aborted"; 8160 desc = "LAN: Transmit Aborted";
8161 break; 8161 break;
8162 8162
8163 case MPI_IOCSTATUS_LAN_RECEIVE_ERROR: /* 0x0084 */ 8163 case MPI_IOCSTATUS_LAN_RECEIVE_ERROR: /* 0x0084 */
8164 desc = "LAN: Receive Error"; 8164 desc = "LAN: Receive Error";
8165 break; 8165 break;
8166 8166
8167 case MPI_IOCSTATUS_LAN_RECEIVE_ABORTED: /* 0x0085 */ 8167 case MPI_IOCSTATUS_LAN_RECEIVE_ABORTED: /* 0x0085 */
8168 desc = "LAN: Receive Aborted"; 8168 desc = "LAN: Receive Aborted";
8169 break; 8169 break;
8170 8170
8171 case MPI_IOCSTATUS_LAN_PARTIAL_PACKET: /* 0x0086 */ 8171 case MPI_IOCSTATUS_LAN_PARTIAL_PACKET: /* 0x0086 */
8172 desc = "LAN: Partial Packet"; 8172 desc = "LAN: Partial Packet";
8173 break; 8173 break;
8174 8174
8175 case MPI_IOCSTATUS_LAN_CANCELED: /* 0x0087 */ 8175 case MPI_IOCSTATUS_LAN_CANCELED: /* 0x0087 */
8176 desc = "LAN: Canceled"; 8176 desc = "LAN: Canceled";
8177 break; 8177 break;
8178 8178
8179 /****************************************************************************/ 8179 /****************************************************************************/
8180 /* Serial Attached SCSI values */ 8180 /* Serial Attached SCSI values */
8181 /****************************************************************************/ 8181 /****************************************************************************/
8182 8182
8183 case MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED: /* 0x0090 */ 8183 case MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED: /* 0x0090 */
8184 desc = "SAS: SMP Request Failed"; 8184 desc = "SAS: SMP Request Failed";
8185 break; 8185 break;
8186 8186
8187 case MPI_IOCSTATUS_SAS_SMP_DATA_OVERRUN: /* 0x0090 */ 8187 case MPI_IOCSTATUS_SAS_SMP_DATA_OVERRUN: /* 0x0090 */
8188 desc = "SAS: SMP Data Overrun"; 8188 desc = "SAS: SMP Data Overrun";
8189 break; 8189 break;
8190 8190
8191 default: 8191 default:
8192 desc = "Others"; 8192 desc = "Others";
8193 break; 8193 break;
8194 } 8194 }
8195 8195
8196 if (!desc) 8196 if (!desc)
8197 return; 8197 return;
8198 8198
8199 dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s\n", 8199 dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s\n",
8200 ioc->name, status, desc)); 8200 ioc->name, status, desc));
8201 } 8201 }
8202 8202
8203 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 8203 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8204 EXPORT_SYMBOL(mpt_attach); 8204 EXPORT_SYMBOL(mpt_attach);
8205 EXPORT_SYMBOL(mpt_detach); 8205 EXPORT_SYMBOL(mpt_detach);
8206 #ifdef CONFIG_PM 8206 #ifdef CONFIG_PM
8207 EXPORT_SYMBOL(mpt_resume); 8207 EXPORT_SYMBOL(mpt_resume);
8208 EXPORT_SYMBOL(mpt_suspend); 8208 EXPORT_SYMBOL(mpt_suspend);
8209 #endif 8209 #endif
8210 EXPORT_SYMBOL(ioc_list); 8210 EXPORT_SYMBOL(ioc_list);
8211 EXPORT_SYMBOL(mpt_register); 8211 EXPORT_SYMBOL(mpt_register);
8212 EXPORT_SYMBOL(mpt_deregister); 8212 EXPORT_SYMBOL(mpt_deregister);
8213 EXPORT_SYMBOL(mpt_event_register); 8213 EXPORT_SYMBOL(mpt_event_register);
8214 EXPORT_SYMBOL(mpt_event_deregister); 8214 EXPORT_SYMBOL(mpt_event_deregister);
8215 EXPORT_SYMBOL(mpt_reset_register); 8215 EXPORT_SYMBOL(mpt_reset_register);
8216 EXPORT_SYMBOL(mpt_reset_deregister); 8216 EXPORT_SYMBOL(mpt_reset_deregister);
8217 EXPORT_SYMBOL(mpt_device_driver_register); 8217 EXPORT_SYMBOL(mpt_device_driver_register);
8218 EXPORT_SYMBOL(mpt_device_driver_deregister); 8218 EXPORT_SYMBOL(mpt_device_driver_deregister);
8219 EXPORT_SYMBOL(mpt_get_msg_frame); 8219 EXPORT_SYMBOL(mpt_get_msg_frame);
8220 EXPORT_SYMBOL(mpt_put_msg_frame); 8220 EXPORT_SYMBOL(mpt_put_msg_frame);
8221 EXPORT_SYMBOL(mpt_put_msg_frame_hi_pri); 8221 EXPORT_SYMBOL(mpt_put_msg_frame_hi_pri);
8222 EXPORT_SYMBOL(mpt_free_msg_frame); 8222 EXPORT_SYMBOL(mpt_free_msg_frame);
8223 EXPORT_SYMBOL(mpt_send_handshake_request); 8223 EXPORT_SYMBOL(mpt_send_handshake_request);
8224 EXPORT_SYMBOL(mpt_verify_adapter); 8224 EXPORT_SYMBOL(mpt_verify_adapter);
8225 EXPORT_SYMBOL(mpt_GetIocState); 8225 EXPORT_SYMBOL(mpt_GetIocState);
8226 EXPORT_SYMBOL(mpt_print_ioc_summary); 8226 EXPORT_SYMBOL(mpt_print_ioc_summary);
8227 EXPORT_SYMBOL(mpt_HardResetHandler); 8227 EXPORT_SYMBOL(mpt_HardResetHandler);
8228 EXPORT_SYMBOL(mpt_config); 8228 EXPORT_SYMBOL(mpt_config);
8229 EXPORT_SYMBOL(mpt_findImVolumes); 8229 EXPORT_SYMBOL(mpt_findImVolumes);
8230 EXPORT_SYMBOL(mpt_alloc_fw_memory); 8230 EXPORT_SYMBOL(mpt_alloc_fw_memory);
8231 EXPORT_SYMBOL(mpt_free_fw_memory); 8231 EXPORT_SYMBOL(mpt_free_fw_memory);
8232 EXPORT_SYMBOL(mptbase_sas_persist_operation); 8232 EXPORT_SYMBOL(mptbase_sas_persist_operation);
8233 EXPORT_SYMBOL(mpt_raid_phys_disk_pg0); 8233 EXPORT_SYMBOL(mpt_raid_phys_disk_pg0);
8234 8234
8235 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 8235 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8236 /** 8236 /**
8237 * fusion_init - Fusion MPT base driver initialization routine. 8237 * fusion_init - Fusion MPT base driver initialization routine.
8238 * 8238 *
8239 * Returns 0 for success, non-zero for failure. 8239 * Returns 0 for success, non-zero for failure.
8240 */ 8240 */
8241 static int __init 8241 static int __init
8242 fusion_init(void) 8242 fusion_init(void)
8243 { 8243 {
8244 u8 cb_idx; 8244 u8 cb_idx;
8245 8245
8246 show_mptmod_ver(my_NAME, my_VERSION); 8246 show_mptmod_ver(my_NAME, my_VERSION);
8247 printk(KERN_INFO COPYRIGHT "\n"); 8247 printk(KERN_INFO COPYRIGHT "\n");
8248 8248
8249 for (cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) { 8249 for (cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
8250 MptCallbacks[cb_idx] = NULL; 8250 MptCallbacks[cb_idx] = NULL;
8251 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER; 8251 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
8252 MptEvHandlers[cb_idx] = NULL; 8252 MptEvHandlers[cb_idx] = NULL;
8253 MptResetHandlers[cb_idx] = NULL; 8253 MptResetHandlers[cb_idx] = NULL;
8254 } 8254 }
8255 8255
8256 /* Register ourselves (mptbase) in order to facilitate 8256 /* Register ourselves (mptbase) in order to facilitate
8257 * EventNotification handling. 8257 * EventNotification handling.
8258 */ 8258 */
8259 mpt_base_index = mpt_register(mptbase_reply, MPTBASE_DRIVER); 8259 mpt_base_index = mpt_register(mptbase_reply, MPTBASE_DRIVER);
8260 8260
8261 /* Register for hard reset handling callbacks. 8261 /* Register for hard reset handling callbacks.
8262 */ 8262 */
8263 mpt_reset_register(mpt_base_index, mpt_ioc_reset); 8263 mpt_reset_register(mpt_base_index, mpt_ioc_reset);
8264 8264
8265 #ifdef CONFIG_PROC_FS 8265 #ifdef CONFIG_PROC_FS
8266 (void) procmpt_create(); 8266 (void) procmpt_create();
8267 #endif 8267 #endif
8268 return 0; 8268 return 0;
8269 } 8269 }
8270 8270
8271 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 8271 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8272 /** 8272 /**
8273 * fusion_exit - Perform driver unload cleanup. 8273 * fusion_exit - Perform driver unload cleanup.
8274 * 8274 *
8275 * This routine frees all resources associated with each MPT adapter 8275 * This routine frees all resources associated with each MPT adapter
8276 * and removes all %MPT_PROCFS_MPTBASEDIR entries. 8276 * and removes all %MPT_PROCFS_MPTBASEDIR entries.
8277 */ 8277 */
8278 static void __exit 8278 static void __exit
8279 fusion_exit(void) 8279 fusion_exit(void)
8280 { 8280 {
8281 8281
8282 mpt_reset_deregister(mpt_base_index); 8282 mpt_reset_deregister(mpt_base_index);
8283 8283
8284 #ifdef CONFIG_PROC_FS 8284 #ifdef CONFIG_PROC_FS
8285 procmpt_destroy(); 8285 procmpt_destroy();
8286 #endif 8286 #endif
8287 } 8287 }
8288 8288
8289 module_init(fusion_init); 8289 module_init(fusion_init);
8290 module_exit(fusion_exit); 8290 module_exit(fusion_exit);
8291 8291
1 /* 1 /*
2 * Atmel MACB Ethernet Controller driver 2 * Atmel MACB Ethernet Controller driver
3 * 3 *
4 * Copyright (C) 2004-2006 Atmel Corporation 4 * Copyright (C) 2004-2006 Atmel Corporation
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 version 2 as 7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation. 8 * published by the Free Software Foundation.
9 */ 9 */
10 10
11 #include <linux/clk.h> 11 #include <linux/clk.h>
12 #include <linux/module.h> 12 #include <linux/module.h>
13 #include <linux/moduleparam.h> 13 #include <linux/moduleparam.h>
14 #include <linux/kernel.h> 14 #include <linux/kernel.h>
15 #include <linux/types.h> 15 #include <linux/types.h>
16 #include <linux/slab.h> 16 #include <linux/slab.h>
17 #include <linux/init.h> 17 #include <linux/init.h>
18 #include <linux/netdevice.h> 18 #include <linux/netdevice.h>
19 #include <linux/etherdevice.h> 19 #include <linux/etherdevice.h>
20 #include <linux/dma-mapping.h> 20 #include <linux/dma-mapping.h>
21 #include <linux/platform_device.h> 21 #include <linux/platform_device.h>
22 #include <linux/phy.h> 22 #include <linux/phy.h>
23 23
24 #include <mach/board.h> 24 #include <mach/board.h>
25 #include <mach/cpu.h> 25 #include <mach/cpu.h>
26 26
27 #include "macb.h" 27 #include "macb.h"
28 28
29 #define RX_BUFFER_SIZE 128 29 #define RX_BUFFER_SIZE 128
30 #define RX_RING_SIZE 512 30 #define RX_RING_SIZE 512
31 #define RX_RING_BYTES (sizeof(struct dma_desc) * RX_RING_SIZE) 31 #define RX_RING_BYTES (sizeof(struct dma_desc) * RX_RING_SIZE)
32 32
33 /* Make the IP header word-aligned (the ethernet header is 14 bytes) */ 33 /* Make the IP header word-aligned (the ethernet header is 14 bytes) */
34 #define RX_OFFSET 2 34 #define RX_OFFSET 2
35 35
36 #define TX_RING_SIZE 128 36 #define TX_RING_SIZE 128
37 #define DEF_TX_RING_PENDING (TX_RING_SIZE - 1) 37 #define DEF_TX_RING_PENDING (TX_RING_SIZE - 1)
38 #define TX_RING_BYTES (sizeof(struct dma_desc) * TX_RING_SIZE) 38 #define TX_RING_BYTES (sizeof(struct dma_desc) * TX_RING_SIZE)
39 39
40 #define TX_RING_GAP(bp) \ 40 #define TX_RING_GAP(bp) \
41 (TX_RING_SIZE - (bp)->tx_pending) 41 (TX_RING_SIZE - (bp)->tx_pending)
42 #define TX_BUFFS_AVAIL(bp) \ 42 #define TX_BUFFS_AVAIL(bp) \
43 (((bp)->tx_tail <= (bp)->tx_head) ? \ 43 (((bp)->tx_tail <= (bp)->tx_head) ? \
44 (bp)->tx_tail + (bp)->tx_pending - (bp)->tx_head : \ 44 (bp)->tx_tail + (bp)->tx_pending - (bp)->tx_head : \
45 (bp)->tx_tail - (bp)->tx_head - TX_RING_GAP(bp)) 45 (bp)->tx_tail - (bp)->tx_head - TX_RING_GAP(bp))
46 #define NEXT_TX(n) (((n) + 1) & (TX_RING_SIZE - 1)) 46 #define NEXT_TX(n) (((n) + 1) & (TX_RING_SIZE - 1))
47 47
48 #define NEXT_RX(n) (((n) + 1) & (RX_RING_SIZE - 1)) 48 #define NEXT_RX(n) (((n) + 1) & (RX_RING_SIZE - 1))
49 49
50 /* minimum number of free TX descriptors before waking up TX process */ 50 /* minimum number of free TX descriptors before waking up TX process */
51 #define MACB_TX_WAKEUP_THRESH (TX_RING_SIZE / 4) 51 #define MACB_TX_WAKEUP_THRESH (TX_RING_SIZE / 4)
52 52
53 #define MACB_RX_INT_FLAGS (MACB_BIT(RCOMP) | MACB_BIT(RXUBR) \ 53 #define MACB_RX_INT_FLAGS (MACB_BIT(RCOMP) | MACB_BIT(RXUBR) \
54 | MACB_BIT(ISR_ROVR)) 54 | MACB_BIT(ISR_ROVR))
55 55
56 static void __macb_set_hwaddr(struct macb *bp) 56 static void __macb_set_hwaddr(struct macb *bp)
57 { 57 {
58 u32 bottom; 58 u32 bottom;
59 u16 top; 59 u16 top;
60 60
61 bottom = cpu_to_le32(*((u32 *)bp->dev->dev_addr)); 61 bottom = cpu_to_le32(*((u32 *)bp->dev->dev_addr));
62 macb_writel(bp, SA1B, bottom); 62 macb_writel(bp, SA1B, bottom);
63 top = cpu_to_le16(*((u16 *)(bp->dev->dev_addr + 4))); 63 top = cpu_to_le16(*((u16 *)(bp->dev->dev_addr + 4)));
64 macb_writel(bp, SA1T, top); 64 macb_writel(bp, SA1T, top);
65 } 65 }
66 66
67 static void __init macb_get_hwaddr(struct macb *bp) 67 static void __init macb_get_hwaddr(struct macb *bp)
68 { 68 {
69 u32 bottom; 69 u32 bottom;
70 u16 top; 70 u16 top;
71 u8 addr[6]; 71 u8 addr[6];
72 72
73 bottom = macb_readl(bp, SA1B); 73 bottom = macb_readl(bp, SA1B);
74 top = macb_readl(bp, SA1T); 74 top = macb_readl(bp, SA1T);
75 75
76 addr[0] = bottom & 0xff; 76 addr[0] = bottom & 0xff;
77 addr[1] = (bottom >> 8) & 0xff; 77 addr[1] = (bottom >> 8) & 0xff;
78 addr[2] = (bottom >> 16) & 0xff; 78 addr[2] = (bottom >> 16) & 0xff;
79 addr[3] = (bottom >> 24) & 0xff; 79 addr[3] = (bottom >> 24) & 0xff;
80 addr[4] = top & 0xff; 80 addr[4] = top & 0xff;
81 addr[5] = (top >> 8) & 0xff; 81 addr[5] = (top >> 8) & 0xff;
82 82
83 if (is_valid_ether_addr(addr)) { 83 if (is_valid_ether_addr(addr)) {
84 memcpy(bp->dev->dev_addr, addr, sizeof(addr)); 84 memcpy(bp->dev->dev_addr, addr, sizeof(addr));
85 } else { 85 } else {
86 dev_info(&bp->pdev->dev, "invalid hw address, using random\n"); 86 dev_info(&bp->pdev->dev, "invalid hw address, using random\n");
87 random_ether_addr(bp->dev->dev_addr); 87 random_ether_addr(bp->dev->dev_addr);
88 } 88 }
89 } 89 }
90 90
91 static int macb_mdio_read(struct mii_bus *bus, int mii_id, int regnum) 91 static int macb_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
92 { 92 {
93 struct macb *bp = bus->priv; 93 struct macb *bp = bus->priv;
94 int value; 94 int value;
95 95
96 macb_writel(bp, MAN, (MACB_BF(SOF, MACB_MAN_SOF) 96 macb_writel(bp, MAN, (MACB_BF(SOF, MACB_MAN_SOF)
97 | MACB_BF(RW, MACB_MAN_READ) 97 | MACB_BF(RW, MACB_MAN_READ)
98 | MACB_BF(PHYA, mii_id) 98 | MACB_BF(PHYA, mii_id)
99 | MACB_BF(REGA, regnum) 99 | MACB_BF(REGA, regnum)
100 | MACB_BF(CODE, MACB_MAN_CODE))); 100 | MACB_BF(CODE, MACB_MAN_CODE)));
101 101
102 /* wait for end of transfer */ 102 /* wait for end of transfer */
103 while (!MACB_BFEXT(IDLE, macb_readl(bp, NSR))) 103 while (!MACB_BFEXT(IDLE, macb_readl(bp, NSR)))
104 cpu_relax(); 104 cpu_relax();
105 105
106 value = MACB_BFEXT(DATA, macb_readl(bp, MAN)); 106 value = MACB_BFEXT(DATA, macb_readl(bp, MAN));
107 107
108 return value; 108 return value;
109 } 109 }
110 110
111 static int macb_mdio_write(struct mii_bus *bus, int mii_id, int regnum, 111 static int macb_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
112 u16 value) 112 u16 value)
113 { 113 {
114 struct macb *bp = bus->priv; 114 struct macb *bp = bus->priv;
115 115
116 macb_writel(bp, MAN, (MACB_BF(SOF, MACB_MAN_SOF) 116 macb_writel(bp, MAN, (MACB_BF(SOF, MACB_MAN_SOF)
117 | MACB_BF(RW, MACB_MAN_WRITE) 117 | MACB_BF(RW, MACB_MAN_WRITE)
118 | MACB_BF(PHYA, mii_id) 118 | MACB_BF(PHYA, mii_id)
119 | MACB_BF(REGA, regnum) 119 | MACB_BF(REGA, regnum)
120 | MACB_BF(CODE, MACB_MAN_CODE) 120 | MACB_BF(CODE, MACB_MAN_CODE)
121 | MACB_BF(DATA, value))); 121 | MACB_BF(DATA, value)));
122 122
123 /* wait for end of transfer */ 123 /* wait for end of transfer */
124 while (!MACB_BFEXT(IDLE, macb_readl(bp, NSR))) 124 while (!MACB_BFEXT(IDLE, macb_readl(bp, NSR)))
125 cpu_relax(); 125 cpu_relax();
126 126
127 return 0; 127 return 0;
128 } 128 }
129 129
130 static int macb_mdio_reset(struct mii_bus *bus) 130 static int macb_mdio_reset(struct mii_bus *bus)
131 { 131 {
132 return 0; 132 return 0;
133 } 133 }
134 134
135 static void macb_handle_link_change(struct net_device *dev) 135 static void macb_handle_link_change(struct net_device *dev)
136 { 136 {
137 struct macb *bp = netdev_priv(dev); 137 struct macb *bp = netdev_priv(dev);
138 struct phy_device *phydev = bp->phy_dev; 138 struct phy_device *phydev = bp->phy_dev;
139 unsigned long flags; 139 unsigned long flags;
140 140
141 int status_change = 0; 141 int status_change = 0;
142 142
143 spin_lock_irqsave(&bp->lock, flags); 143 spin_lock_irqsave(&bp->lock, flags);
144 144
145 if (phydev->link) { 145 if (phydev->link) {
146 if ((bp->speed != phydev->speed) || 146 if ((bp->speed != phydev->speed) ||
147 (bp->duplex != phydev->duplex)) { 147 (bp->duplex != phydev->duplex)) {
148 u32 reg; 148 u32 reg;
149 149
150 reg = macb_readl(bp, NCFGR); 150 reg = macb_readl(bp, NCFGR);
151 reg &= ~(MACB_BIT(SPD) | MACB_BIT(FD)); 151 reg &= ~(MACB_BIT(SPD) | MACB_BIT(FD));
152 152
153 if (phydev->duplex) 153 if (phydev->duplex)
154 reg |= MACB_BIT(FD); 154 reg |= MACB_BIT(FD);
155 if (phydev->speed == SPEED_100) 155 if (phydev->speed == SPEED_100)
156 reg |= MACB_BIT(SPD); 156 reg |= MACB_BIT(SPD);
157 157
158 macb_writel(bp, NCFGR, reg); 158 macb_writel(bp, NCFGR, reg);
159 159
160 bp->speed = phydev->speed; 160 bp->speed = phydev->speed;
161 bp->duplex = phydev->duplex; 161 bp->duplex = phydev->duplex;
162 status_change = 1; 162 status_change = 1;
163 } 163 }
164 } 164 }
165 165
166 if (phydev->link != bp->link) { 166 if (phydev->link != bp->link) {
167 if (!phydev->link) { 167 if (!phydev->link) {
168 bp->speed = 0; 168 bp->speed = 0;
169 bp->duplex = -1; 169 bp->duplex = -1;
170 } 170 }
171 bp->link = phydev->link; 171 bp->link = phydev->link;
172 172
173 status_change = 1; 173 status_change = 1;
174 } 174 }
175 175
176 spin_unlock_irqrestore(&bp->lock, flags); 176 spin_unlock_irqrestore(&bp->lock, flags);
177 177
178 if (status_change) { 178 if (status_change) {
179 if (phydev->link) 179 if (phydev->link)
180 printk(KERN_INFO "%s: link up (%d/%s)\n", 180 printk(KERN_INFO "%s: link up (%d/%s)\n",
181 dev->name, phydev->speed, 181 dev->name, phydev->speed,
182 DUPLEX_FULL == phydev->duplex ? "Full":"Half"); 182 DUPLEX_FULL == phydev->duplex ? "Full":"Half");
183 else 183 else
184 printk(KERN_INFO "%s: link down\n", dev->name); 184 printk(KERN_INFO "%s: link down\n", dev->name);
185 } 185 }
186 } 186 }
187 187
188 /* based on au1000_eth. c*/ 188 /* based on au1000_eth. c*/
189 static int macb_mii_probe(struct net_device *dev) 189 static int macb_mii_probe(struct net_device *dev)
190 { 190 {
191 struct macb *bp = netdev_priv(dev); 191 struct macb *bp = netdev_priv(dev);
192 struct phy_device *phydev = NULL; 192 struct phy_device *phydev = NULL;
193 struct eth_platform_data *pdata; 193 struct eth_platform_data *pdata;
194 int phy_addr; 194 int phy_addr;
195 195
196 /* find the first phy */ 196 /* find the first phy */
197 for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) { 197 for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
198 if (bp->mii_bus->phy_map[phy_addr]) { 198 if (bp->mii_bus->phy_map[phy_addr]) {
199 phydev = bp->mii_bus->phy_map[phy_addr]; 199 phydev = bp->mii_bus->phy_map[phy_addr];
200 break; 200 break;
201 } 201 }
202 } 202 }
203 203
204 if (!phydev) { 204 if (!phydev) {
205 printk (KERN_ERR "%s: no PHY found\n", dev->name); 205 printk (KERN_ERR "%s: no PHY found\n", dev->name);
206 return -1; 206 return -1;
207 } 207 }
208 208
209 pdata = bp->pdev->dev.platform_data; 209 pdata = bp->pdev->dev.platform_data;
210 /* TODO : add pin_irq */ 210 /* TODO : add pin_irq */
211 211
212 /* attach the mac to the phy */ 212 /* attach the mac to the phy */
213 if (pdata && pdata->is_rmii) { 213 if (pdata && pdata->is_rmii) {
214 phydev = phy_connect(dev, dev_name(&phydev->dev), 214 phydev = phy_connect(dev, dev_name(&phydev->dev),
215 &macb_handle_link_change, 0, PHY_INTERFACE_MODE_RMII); 215 &macb_handle_link_change, 0, PHY_INTERFACE_MODE_RMII);
216 } else { 216 } else {
217 phydev = phy_connect(dev, dev_name(&phydev->dev), 217 phydev = phy_connect(dev, dev_name(&phydev->dev),
218 &macb_handle_link_change, 0, PHY_INTERFACE_MODE_MII); 218 &macb_handle_link_change, 0, PHY_INTERFACE_MODE_MII);
219 } 219 }
220 220
221 if (IS_ERR(phydev)) { 221 if (IS_ERR(phydev)) {
222 printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name); 222 printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name);
223 return PTR_ERR(phydev); 223 return PTR_ERR(phydev);
224 } 224 }
225 225
226 /* mask with MAC supported features */ 226 /* mask with MAC supported features */
227 phydev->supported &= PHY_BASIC_FEATURES; 227 phydev->supported &= PHY_BASIC_FEATURES;
228 228
229 phydev->advertising = phydev->supported; 229 phydev->advertising = phydev->supported;
230 230
231 bp->link = 0; 231 bp->link = 0;
232 bp->speed = 0; 232 bp->speed = 0;
233 bp->duplex = -1; 233 bp->duplex = -1;
234 bp->phy_dev = phydev; 234 bp->phy_dev = phydev;
235 235
236 return 0; 236 return 0;
237 } 237 }
238 238
239 static int macb_mii_init(struct macb *bp) 239 static int macb_mii_init(struct macb *bp)
240 { 240 {
241 struct eth_platform_data *pdata; 241 struct eth_platform_data *pdata;
242 int err = -ENXIO, i; 242 int err = -ENXIO, i;
243 243
244 /* Enable managment port */ 244 /* Enable management port */
245 macb_writel(bp, NCR, MACB_BIT(MPE)); 245 macb_writel(bp, NCR, MACB_BIT(MPE));
246 246
247 bp->mii_bus = mdiobus_alloc(); 247 bp->mii_bus = mdiobus_alloc();
248 if (bp->mii_bus == NULL) { 248 if (bp->mii_bus == NULL) {
249 err = -ENOMEM; 249 err = -ENOMEM;
250 goto err_out; 250 goto err_out;
251 } 251 }
252 252
253 bp->mii_bus->name = "MACB_mii_bus"; 253 bp->mii_bus->name = "MACB_mii_bus";
254 bp->mii_bus->read = &macb_mdio_read; 254 bp->mii_bus->read = &macb_mdio_read;
255 bp->mii_bus->write = &macb_mdio_write; 255 bp->mii_bus->write = &macb_mdio_write;
256 bp->mii_bus->reset = &macb_mdio_reset; 256 bp->mii_bus->reset = &macb_mdio_reset;
257 snprintf(bp->mii_bus->id, MII_BUS_ID_SIZE, "%x", bp->pdev->id); 257 snprintf(bp->mii_bus->id, MII_BUS_ID_SIZE, "%x", bp->pdev->id);
258 bp->mii_bus->priv = bp; 258 bp->mii_bus->priv = bp;
259 bp->mii_bus->parent = &bp->dev->dev; 259 bp->mii_bus->parent = &bp->dev->dev;
260 pdata = bp->pdev->dev.platform_data; 260 pdata = bp->pdev->dev.platform_data;
261 261
262 if (pdata) 262 if (pdata)
263 bp->mii_bus->phy_mask = pdata->phy_mask; 263 bp->mii_bus->phy_mask = pdata->phy_mask;
264 264
265 bp->mii_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL); 265 bp->mii_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL);
266 if (!bp->mii_bus->irq) { 266 if (!bp->mii_bus->irq) {
267 err = -ENOMEM; 267 err = -ENOMEM;
268 goto err_out_free_mdiobus; 268 goto err_out_free_mdiobus;
269 } 269 }
270 270
271 for (i = 0; i < PHY_MAX_ADDR; i++) 271 for (i = 0; i < PHY_MAX_ADDR; i++)
272 bp->mii_bus->irq[i] = PHY_POLL; 272 bp->mii_bus->irq[i] = PHY_POLL;
273 273
274 platform_set_drvdata(bp->dev, bp->mii_bus); 274 platform_set_drvdata(bp->dev, bp->mii_bus);
275 275
276 if (mdiobus_register(bp->mii_bus)) 276 if (mdiobus_register(bp->mii_bus))
277 goto err_out_free_mdio_irq; 277 goto err_out_free_mdio_irq;
278 278
279 if (macb_mii_probe(bp->dev) != 0) { 279 if (macb_mii_probe(bp->dev) != 0) {
280 goto err_out_unregister_bus; 280 goto err_out_unregister_bus;
281 } 281 }
282 282
283 return 0; 283 return 0;
284 284
285 err_out_unregister_bus: 285 err_out_unregister_bus:
286 mdiobus_unregister(bp->mii_bus); 286 mdiobus_unregister(bp->mii_bus);
287 err_out_free_mdio_irq: 287 err_out_free_mdio_irq:
288 kfree(bp->mii_bus->irq); 288 kfree(bp->mii_bus->irq);
289 err_out_free_mdiobus: 289 err_out_free_mdiobus:
290 mdiobus_free(bp->mii_bus); 290 mdiobus_free(bp->mii_bus);
291 err_out: 291 err_out:
292 return err; 292 return err;
293 } 293 }
294 294
295 static void macb_update_stats(struct macb *bp) 295 static void macb_update_stats(struct macb *bp)
296 { 296 {
297 u32 __iomem *reg = bp->regs + MACB_PFR; 297 u32 __iomem *reg = bp->regs + MACB_PFR;
298 u32 *p = &bp->hw_stats.rx_pause_frames; 298 u32 *p = &bp->hw_stats.rx_pause_frames;
299 u32 *end = &bp->hw_stats.tx_pause_frames + 1; 299 u32 *end = &bp->hw_stats.tx_pause_frames + 1;
300 300
301 WARN_ON((unsigned long)(end - p - 1) != (MACB_TPF - MACB_PFR) / 4); 301 WARN_ON((unsigned long)(end - p - 1) != (MACB_TPF - MACB_PFR) / 4);
302 302
303 for(; p < end; p++, reg++) 303 for(; p < end; p++, reg++)
304 *p += __raw_readl(reg); 304 *p += __raw_readl(reg);
305 } 305 }
306 306
307 static void macb_tx(struct macb *bp) 307 static void macb_tx(struct macb *bp)
308 { 308 {
309 unsigned int tail; 309 unsigned int tail;
310 unsigned int head; 310 unsigned int head;
311 u32 status; 311 u32 status;
312 312
313 status = macb_readl(bp, TSR); 313 status = macb_readl(bp, TSR);
314 macb_writel(bp, TSR, status); 314 macb_writel(bp, TSR, status);
315 315
316 dev_dbg(&bp->pdev->dev, "macb_tx status = %02lx\n", 316 dev_dbg(&bp->pdev->dev, "macb_tx status = %02lx\n",
317 (unsigned long)status); 317 (unsigned long)status);
318 318
319 if (status & (MACB_BIT(UND) | MACB_BIT(TSR_RLE))) { 319 if (status & (MACB_BIT(UND) | MACB_BIT(TSR_RLE))) {
320 int i; 320 int i;
321 printk(KERN_ERR "%s: TX %s, resetting buffers\n", 321 printk(KERN_ERR "%s: TX %s, resetting buffers\n",
322 bp->dev->name, status & MACB_BIT(UND) ? 322 bp->dev->name, status & MACB_BIT(UND) ?
323 "underrun" : "retry limit exceeded"); 323 "underrun" : "retry limit exceeded");
324 324
325 /* Transfer ongoing, disable transmitter, to avoid confusion */ 325 /* Transfer ongoing, disable transmitter, to avoid confusion */
326 if (status & MACB_BIT(TGO)) 326 if (status & MACB_BIT(TGO))
327 macb_writel(bp, NCR, macb_readl(bp, NCR) & ~MACB_BIT(TE)); 327 macb_writel(bp, NCR, macb_readl(bp, NCR) & ~MACB_BIT(TE));
328 328
329 head = bp->tx_head; 329 head = bp->tx_head;
330 330
331 /*Mark all the buffer as used to avoid sending a lost buffer*/ 331 /*Mark all the buffer as used to avoid sending a lost buffer*/
332 for (i = 0; i < TX_RING_SIZE; i++) 332 for (i = 0; i < TX_RING_SIZE; i++)
333 bp->tx_ring[i].ctrl = MACB_BIT(TX_USED); 333 bp->tx_ring[i].ctrl = MACB_BIT(TX_USED);
334 334
335 /* free transmit buffer in upper layer*/ 335 /* free transmit buffer in upper layer*/
336 for (tail = bp->tx_tail; tail != head; tail = NEXT_TX(tail)) { 336 for (tail = bp->tx_tail; tail != head; tail = NEXT_TX(tail)) {
337 struct ring_info *rp = &bp->tx_skb[tail]; 337 struct ring_info *rp = &bp->tx_skb[tail];
338 struct sk_buff *skb = rp->skb; 338 struct sk_buff *skb = rp->skb;
339 339
340 BUG_ON(skb == NULL); 340 BUG_ON(skb == NULL);
341 341
342 rmb(); 342 rmb();
343 343
344 dma_unmap_single(&bp->pdev->dev, rp->mapping, skb->len, 344 dma_unmap_single(&bp->pdev->dev, rp->mapping, skb->len,
345 DMA_TO_DEVICE); 345 DMA_TO_DEVICE);
346 rp->skb = NULL; 346 rp->skb = NULL;
347 dev_kfree_skb_irq(skb); 347 dev_kfree_skb_irq(skb);
348 } 348 }
349 349
350 bp->tx_head = bp->tx_tail = 0; 350 bp->tx_head = bp->tx_tail = 0;
351 351
352 /* Enable the transmitter again */ 352 /* Enable the transmitter again */
353 if (status & MACB_BIT(TGO)) 353 if (status & MACB_BIT(TGO))
354 macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TE)); 354 macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TE));
355 } 355 }
356 356
357 if (!(status & MACB_BIT(COMP))) 357 if (!(status & MACB_BIT(COMP)))
358 /* 358 /*
359 * This may happen when a buffer becomes complete 359 * This may happen when a buffer becomes complete
360 * between reading the ISR and scanning the 360 * between reading the ISR and scanning the
361 * descriptors. Nothing to worry about. 361 * descriptors. Nothing to worry about.
362 */ 362 */
363 return; 363 return;
364 364
365 head = bp->tx_head; 365 head = bp->tx_head;
366 for (tail = bp->tx_tail; tail != head; tail = NEXT_TX(tail)) { 366 for (tail = bp->tx_tail; tail != head; tail = NEXT_TX(tail)) {
367 struct ring_info *rp = &bp->tx_skb[tail]; 367 struct ring_info *rp = &bp->tx_skb[tail];
368 struct sk_buff *skb = rp->skb; 368 struct sk_buff *skb = rp->skb;
369 u32 bufstat; 369 u32 bufstat;
370 370
371 BUG_ON(skb == NULL); 371 BUG_ON(skb == NULL);
372 372
373 rmb(); 373 rmb();
374 bufstat = bp->tx_ring[tail].ctrl; 374 bufstat = bp->tx_ring[tail].ctrl;
375 375
376 if (!(bufstat & MACB_BIT(TX_USED))) 376 if (!(bufstat & MACB_BIT(TX_USED)))
377 break; 377 break;
378 378
379 dev_dbg(&bp->pdev->dev, "skb %u (data %p) TX complete\n", 379 dev_dbg(&bp->pdev->dev, "skb %u (data %p) TX complete\n",
380 tail, skb->data); 380 tail, skb->data);
381 dma_unmap_single(&bp->pdev->dev, rp->mapping, skb->len, 381 dma_unmap_single(&bp->pdev->dev, rp->mapping, skb->len,
382 DMA_TO_DEVICE); 382 DMA_TO_DEVICE);
383 bp->stats.tx_packets++; 383 bp->stats.tx_packets++;
384 bp->stats.tx_bytes += skb->len; 384 bp->stats.tx_bytes += skb->len;
385 rp->skb = NULL; 385 rp->skb = NULL;
386 dev_kfree_skb_irq(skb); 386 dev_kfree_skb_irq(skb);
387 } 387 }
388 388
389 bp->tx_tail = tail; 389 bp->tx_tail = tail;
390 if (netif_queue_stopped(bp->dev) && 390 if (netif_queue_stopped(bp->dev) &&
391 TX_BUFFS_AVAIL(bp) > MACB_TX_WAKEUP_THRESH) 391 TX_BUFFS_AVAIL(bp) > MACB_TX_WAKEUP_THRESH)
392 netif_wake_queue(bp->dev); 392 netif_wake_queue(bp->dev);
393 } 393 }
394 394
395 static int macb_rx_frame(struct macb *bp, unsigned int first_frag, 395 static int macb_rx_frame(struct macb *bp, unsigned int first_frag,
396 unsigned int last_frag) 396 unsigned int last_frag)
397 { 397 {
398 unsigned int len; 398 unsigned int len;
399 unsigned int frag; 399 unsigned int frag;
400 unsigned int offset = 0; 400 unsigned int offset = 0;
401 struct sk_buff *skb; 401 struct sk_buff *skb;
402 402
403 len = MACB_BFEXT(RX_FRMLEN, bp->rx_ring[last_frag].ctrl); 403 len = MACB_BFEXT(RX_FRMLEN, bp->rx_ring[last_frag].ctrl);
404 404
405 dev_dbg(&bp->pdev->dev, "macb_rx_frame frags %u - %u (len %u)\n", 405 dev_dbg(&bp->pdev->dev, "macb_rx_frame frags %u - %u (len %u)\n",
406 first_frag, last_frag, len); 406 first_frag, last_frag, len);
407 407
408 skb = dev_alloc_skb(len + RX_OFFSET); 408 skb = dev_alloc_skb(len + RX_OFFSET);
409 if (!skb) { 409 if (!skb) {
410 bp->stats.rx_dropped++; 410 bp->stats.rx_dropped++;
411 for (frag = first_frag; ; frag = NEXT_RX(frag)) { 411 for (frag = first_frag; ; frag = NEXT_RX(frag)) {
412 bp->rx_ring[frag].addr &= ~MACB_BIT(RX_USED); 412 bp->rx_ring[frag].addr &= ~MACB_BIT(RX_USED);
413 if (frag == last_frag) 413 if (frag == last_frag)
414 break; 414 break;
415 } 415 }
416 wmb(); 416 wmb();
417 return 1; 417 return 1;
418 } 418 }
419 419
420 skb_reserve(skb, RX_OFFSET); 420 skb_reserve(skb, RX_OFFSET);
421 skb->ip_summed = CHECKSUM_NONE; 421 skb->ip_summed = CHECKSUM_NONE;
422 skb_put(skb, len); 422 skb_put(skb, len);
423 423
424 for (frag = first_frag; ; frag = NEXT_RX(frag)) { 424 for (frag = first_frag; ; frag = NEXT_RX(frag)) {
425 unsigned int frag_len = RX_BUFFER_SIZE; 425 unsigned int frag_len = RX_BUFFER_SIZE;
426 426
427 if (offset + frag_len > len) { 427 if (offset + frag_len > len) {
428 BUG_ON(frag != last_frag); 428 BUG_ON(frag != last_frag);
429 frag_len = len - offset; 429 frag_len = len - offset;
430 } 430 }
431 skb_copy_to_linear_data_offset(skb, offset, 431 skb_copy_to_linear_data_offset(skb, offset,
432 (bp->rx_buffers + 432 (bp->rx_buffers +
433 (RX_BUFFER_SIZE * frag)), 433 (RX_BUFFER_SIZE * frag)),
434 frag_len); 434 frag_len);
435 offset += RX_BUFFER_SIZE; 435 offset += RX_BUFFER_SIZE;
436 bp->rx_ring[frag].addr &= ~MACB_BIT(RX_USED); 436 bp->rx_ring[frag].addr &= ~MACB_BIT(RX_USED);
437 wmb(); 437 wmb();
438 438
439 if (frag == last_frag) 439 if (frag == last_frag)
440 break; 440 break;
441 } 441 }
442 442
443 skb->protocol = eth_type_trans(skb, bp->dev); 443 skb->protocol = eth_type_trans(skb, bp->dev);
444 444
445 bp->stats.rx_packets++; 445 bp->stats.rx_packets++;
446 bp->stats.rx_bytes += len; 446 bp->stats.rx_bytes += len;
447 dev_dbg(&bp->pdev->dev, "received skb of length %u, csum: %08x\n", 447 dev_dbg(&bp->pdev->dev, "received skb of length %u, csum: %08x\n",
448 skb->len, skb->csum); 448 skb->len, skb->csum);
449 netif_receive_skb(skb); 449 netif_receive_skb(skb);
450 450
451 return 0; 451 return 0;
452 } 452 }
453 453
454 /* Mark DMA descriptors from begin up to and not including end as unused */ 454 /* Mark DMA descriptors from begin up to and not including end as unused */
455 static void discard_partial_frame(struct macb *bp, unsigned int begin, 455 static void discard_partial_frame(struct macb *bp, unsigned int begin,
456 unsigned int end) 456 unsigned int end)
457 { 457 {
458 unsigned int frag; 458 unsigned int frag;
459 459
460 for (frag = begin; frag != end; frag = NEXT_RX(frag)) 460 for (frag = begin; frag != end; frag = NEXT_RX(frag))
461 bp->rx_ring[frag].addr &= ~MACB_BIT(RX_USED); 461 bp->rx_ring[frag].addr &= ~MACB_BIT(RX_USED);
462 wmb(); 462 wmb();
463 463
464 /* 464 /*
465 * When this happens, the hardware stats registers for 465 * When this happens, the hardware stats registers for
466 * whatever caused this is updated, so we don't have to record 466 * whatever caused this is updated, so we don't have to record
467 * anything. 467 * anything.
468 */ 468 */
469 } 469 }
470 470
471 static int macb_rx(struct macb *bp, int budget) 471 static int macb_rx(struct macb *bp, int budget)
472 { 472 {
473 int received = 0; 473 int received = 0;
474 unsigned int tail = bp->rx_tail; 474 unsigned int tail = bp->rx_tail;
475 int first_frag = -1; 475 int first_frag = -1;
476 476
477 for (; budget > 0; tail = NEXT_RX(tail)) { 477 for (; budget > 0; tail = NEXT_RX(tail)) {
478 u32 addr, ctrl; 478 u32 addr, ctrl;
479 479
480 rmb(); 480 rmb();
481 addr = bp->rx_ring[tail].addr; 481 addr = bp->rx_ring[tail].addr;
482 ctrl = bp->rx_ring[tail].ctrl; 482 ctrl = bp->rx_ring[tail].ctrl;
483 483
484 if (!(addr & MACB_BIT(RX_USED))) 484 if (!(addr & MACB_BIT(RX_USED)))
485 break; 485 break;
486 486
487 if (ctrl & MACB_BIT(RX_SOF)) { 487 if (ctrl & MACB_BIT(RX_SOF)) {
488 if (first_frag != -1) 488 if (first_frag != -1)
489 discard_partial_frame(bp, first_frag, tail); 489 discard_partial_frame(bp, first_frag, tail);
490 first_frag = tail; 490 first_frag = tail;
491 } 491 }
492 492
493 if (ctrl & MACB_BIT(RX_EOF)) { 493 if (ctrl & MACB_BIT(RX_EOF)) {
494 int dropped; 494 int dropped;
495 BUG_ON(first_frag == -1); 495 BUG_ON(first_frag == -1);
496 496
497 dropped = macb_rx_frame(bp, first_frag, tail); 497 dropped = macb_rx_frame(bp, first_frag, tail);
498 first_frag = -1; 498 first_frag = -1;
499 if (!dropped) { 499 if (!dropped) {
500 received++; 500 received++;
501 budget--; 501 budget--;
502 } 502 }
503 } 503 }
504 } 504 }
505 505
506 if (first_frag != -1) 506 if (first_frag != -1)
507 bp->rx_tail = first_frag; 507 bp->rx_tail = first_frag;
508 else 508 else
509 bp->rx_tail = tail; 509 bp->rx_tail = tail;
510 510
511 return received; 511 return received;
512 } 512 }
513 513
514 static int macb_poll(struct napi_struct *napi, int budget) 514 static int macb_poll(struct napi_struct *napi, int budget)
515 { 515 {
516 struct macb *bp = container_of(napi, struct macb, napi); 516 struct macb *bp = container_of(napi, struct macb, napi);
517 int work_done; 517 int work_done;
518 u32 status; 518 u32 status;
519 519
520 status = macb_readl(bp, RSR); 520 status = macb_readl(bp, RSR);
521 macb_writel(bp, RSR, status); 521 macb_writel(bp, RSR, status);
522 522
523 work_done = 0; 523 work_done = 0;
524 524
525 dev_dbg(&bp->pdev->dev, "poll: status = %08lx, budget = %d\n", 525 dev_dbg(&bp->pdev->dev, "poll: status = %08lx, budget = %d\n",
526 (unsigned long)status, budget); 526 (unsigned long)status, budget);
527 527
528 work_done = macb_rx(bp, budget); 528 work_done = macb_rx(bp, budget);
529 if (work_done < budget) 529 if (work_done < budget)
530 napi_complete(napi); 530 napi_complete(napi);
531 531
532 /* 532 /*
533 * We've done what we can to clean the buffers. Make sure we 533 * We've done what we can to clean the buffers. Make sure we
534 * get notified when new packets arrive. 534 * get notified when new packets arrive.
535 */ 535 */
536 macb_writel(bp, IER, MACB_RX_INT_FLAGS); 536 macb_writel(bp, IER, MACB_RX_INT_FLAGS);
537 537
538 /* TODO: Handle errors */ 538 /* TODO: Handle errors */
539 539
540 return work_done; 540 return work_done;
541 } 541 }
542 542
543 static irqreturn_t macb_interrupt(int irq, void *dev_id) 543 static irqreturn_t macb_interrupt(int irq, void *dev_id)
544 { 544 {
545 struct net_device *dev = dev_id; 545 struct net_device *dev = dev_id;
546 struct macb *bp = netdev_priv(dev); 546 struct macb *bp = netdev_priv(dev);
547 u32 status; 547 u32 status;
548 548
549 status = macb_readl(bp, ISR); 549 status = macb_readl(bp, ISR);
550 550
551 if (unlikely(!status)) 551 if (unlikely(!status))
552 return IRQ_NONE; 552 return IRQ_NONE;
553 553
554 spin_lock(&bp->lock); 554 spin_lock(&bp->lock);
555 555
556 while (status) { 556 while (status) {
557 /* close possible race with dev_close */ 557 /* close possible race with dev_close */
558 if (unlikely(!netif_running(dev))) { 558 if (unlikely(!netif_running(dev))) {
559 macb_writel(bp, IDR, ~0UL); 559 macb_writel(bp, IDR, ~0UL);
560 break; 560 break;
561 } 561 }
562 562
563 if (status & MACB_RX_INT_FLAGS) { 563 if (status & MACB_RX_INT_FLAGS) {
564 if (napi_schedule_prep(&bp->napi)) { 564 if (napi_schedule_prep(&bp->napi)) {
565 /* 565 /*
566 * There's no point taking any more interrupts 566 * There's no point taking any more interrupts
567 * until we have processed the buffers 567 * until we have processed the buffers
568 */ 568 */
569 macb_writel(bp, IDR, MACB_RX_INT_FLAGS); 569 macb_writel(bp, IDR, MACB_RX_INT_FLAGS);
570 dev_dbg(&bp->pdev->dev, 570 dev_dbg(&bp->pdev->dev,
571 "scheduling RX softirq\n"); 571 "scheduling RX softirq\n");
572 __napi_schedule(&bp->napi); 572 __napi_schedule(&bp->napi);
573 } 573 }
574 } 574 }
575 575
576 if (status & (MACB_BIT(TCOMP) | MACB_BIT(ISR_TUND) | 576 if (status & (MACB_BIT(TCOMP) | MACB_BIT(ISR_TUND) |
577 MACB_BIT(ISR_RLE))) 577 MACB_BIT(ISR_RLE)))
578 macb_tx(bp); 578 macb_tx(bp);
579 579
580 /* 580 /*
581 * Link change detection isn't possible with RMII, so we'll 581 * Link change detection isn't possible with RMII, so we'll
582 * add that if/when we get our hands on a full-blown MII PHY. 582 * add that if/when we get our hands on a full-blown MII PHY.
583 */ 583 */
584 584
585 if (status & MACB_BIT(HRESP)) { 585 if (status & MACB_BIT(HRESP)) {
586 /* 586 /*
587 * TODO: Reset the hardware, and maybe move the printk 587 * TODO: Reset the hardware, and maybe move the printk
588 * to a lower-priority context as well (work queue?) 588 * to a lower-priority context as well (work queue?)
589 */ 589 */
590 printk(KERN_ERR "%s: DMA bus error: HRESP not OK\n", 590 printk(KERN_ERR "%s: DMA bus error: HRESP not OK\n",
591 dev->name); 591 dev->name);
592 } 592 }
593 593
594 status = macb_readl(bp, ISR); 594 status = macb_readl(bp, ISR);
595 } 595 }
596 596
597 spin_unlock(&bp->lock); 597 spin_unlock(&bp->lock);
598 598
599 return IRQ_HANDLED; 599 return IRQ_HANDLED;
600 } 600 }
601 601
602 #ifdef CONFIG_NET_POLL_CONTROLLER 602 #ifdef CONFIG_NET_POLL_CONTROLLER
603 /* 603 /*
604 * Polling receive - used by netconsole and other diagnostic tools 604 * Polling receive - used by netconsole and other diagnostic tools
605 * to allow network i/o with interrupts disabled. 605 * to allow network i/o with interrupts disabled.
606 */ 606 */
607 static void macb_poll_controller(struct net_device *dev) 607 static void macb_poll_controller(struct net_device *dev)
608 { 608 {
609 unsigned long flags; 609 unsigned long flags;
610 610
611 local_irq_save(flags); 611 local_irq_save(flags);
612 macb_interrupt(dev->irq, dev); 612 macb_interrupt(dev->irq, dev);
613 local_irq_restore(flags); 613 local_irq_restore(flags);
614 } 614 }
615 #endif 615 #endif
616 616
617 static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev) 617 static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
618 { 618 {
619 struct macb *bp = netdev_priv(dev); 619 struct macb *bp = netdev_priv(dev);
620 dma_addr_t mapping; 620 dma_addr_t mapping;
621 unsigned int len, entry; 621 unsigned int len, entry;
622 u32 ctrl; 622 u32 ctrl;
623 unsigned long flags; 623 unsigned long flags;
624 624
625 #ifdef DEBUG 625 #ifdef DEBUG
626 int i; 626 int i;
627 dev_dbg(&bp->pdev->dev, 627 dev_dbg(&bp->pdev->dev,
628 "start_xmit: len %u head %p data %p tail %p end %p\n", 628 "start_xmit: len %u head %p data %p tail %p end %p\n",
629 skb->len, skb->head, skb->data, 629 skb->len, skb->head, skb->data,
630 skb_tail_pointer(skb), skb_end_pointer(skb)); 630 skb_tail_pointer(skb), skb_end_pointer(skb));
631 dev_dbg(&bp->pdev->dev, 631 dev_dbg(&bp->pdev->dev,
632 "data:"); 632 "data:");
633 for (i = 0; i < 16; i++) 633 for (i = 0; i < 16; i++)
634 printk(" %02x", (unsigned int)skb->data[i]); 634 printk(" %02x", (unsigned int)skb->data[i]);
635 printk("\n"); 635 printk("\n");
636 #endif 636 #endif
637 637
638 len = skb->len; 638 len = skb->len;
639 spin_lock_irqsave(&bp->lock, flags); 639 spin_lock_irqsave(&bp->lock, flags);
640 640
641 /* This is a hard error, log it. */ 641 /* This is a hard error, log it. */
642 if (TX_BUFFS_AVAIL(bp) < 1) { 642 if (TX_BUFFS_AVAIL(bp) < 1) {
643 netif_stop_queue(dev); 643 netif_stop_queue(dev);
644 spin_unlock_irqrestore(&bp->lock, flags); 644 spin_unlock_irqrestore(&bp->lock, flags);
645 dev_err(&bp->pdev->dev, 645 dev_err(&bp->pdev->dev,
646 "BUG! Tx Ring full when queue awake!\n"); 646 "BUG! Tx Ring full when queue awake!\n");
647 dev_dbg(&bp->pdev->dev, "tx_head = %u, tx_tail = %u\n", 647 dev_dbg(&bp->pdev->dev, "tx_head = %u, tx_tail = %u\n",
648 bp->tx_head, bp->tx_tail); 648 bp->tx_head, bp->tx_tail);
649 return NETDEV_TX_BUSY; 649 return NETDEV_TX_BUSY;
650 } 650 }
651 651
652 entry = bp->tx_head; 652 entry = bp->tx_head;
653 dev_dbg(&bp->pdev->dev, "Allocated ring entry %u\n", entry); 653 dev_dbg(&bp->pdev->dev, "Allocated ring entry %u\n", entry);
654 mapping = dma_map_single(&bp->pdev->dev, skb->data, 654 mapping = dma_map_single(&bp->pdev->dev, skb->data,
655 len, DMA_TO_DEVICE); 655 len, DMA_TO_DEVICE);
656 bp->tx_skb[entry].skb = skb; 656 bp->tx_skb[entry].skb = skb;
657 bp->tx_skb[entry].mapping = mapping; 657 bp->tx_skb[entry].mapping = mapping;
658 dev_dbg(&bp->pdev->dev, "Mapped skb data %p to DMA addr %08lx\n", 658 dev_dbg(&bp->pdev->dev, "Mapped skb data %p to DMA addr %08lx\n",
659 skb->data, (unsigned long)mapping); 659 skb->data, (unsigned long)mapping);
660 660
661 ctrl = MACB_BF(TX_FRMLEN, len); 661 ctrl = MACB_BF(TX_FRMLEN, len);
662 ctrl |= MACB_BIT(TX_LAST); 662 ctrl |= MACB_BIT(TX_LAST);
663 if (entry == (TX_RING_SIZE - 1)) 663 if (entry == (TX_RING_SIZE - 1))
664 ctrl |= MACB_BIT(TX_WRAP); 664 ctrl |= MACB_BIT(TX_WRAP);
665 665
666 bp->tx_ring[entry].addr = mapping; 666 bp->tx_ring[entry].addr = mapping;
667 bp->tx_ring[entry].ctrl = ctrl; 667 bp->tx_ring[entry].ctrl = ctrl;
668 wmb(); 668 wmb();
669 669
670 entry = NEXT_TX(entry); 670 entry = NEXT_TX(entry);
671 bp->tx_head = entry; 671 bp->tx_head = entry;
672 672
673 macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TSTART)); 673 macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TSTART));
674 674
675 if (TX_BUFFS_AVAIL(bp) < 1) 675 if (TX_BUFFS_AVAIL(bp) < 1)
676 netif_stop_queue(dev); 676 netif_stop_queue(dev);
677 677
678 spin_unlock_irqrestore(&bp->lock, flags); 678 spin_unlock_irqrestore(&bp->lock, flags);
679 679
680 dev->trans_start = jiffies; 680 dev->trans_start = jiffies;
681 681
682 return NETDEV_TX_OK; 682 return NETDEV_TX_OK;
683 } 683 }
684 684
685 static void macb_free_consistent(struct macb *bp) 685 static void macb_free_consistent(struct macb *bp)
686 { 686 {
687 if (bp->tx_skb) { 687 if (bp->tx_skb) {
688 kfree(bp->tx_skb); 688 kfree(bp->tx_skb);
689 bp->tx_skb = NULL; 689 bp->tx_skb = NULL;
690 } 690 }
691 if (bp->rx_ring) { 691 if (bp->rx_ring) {
692 dma_free_coherent(&bp->pdev->dev, RX_RING_BYTES, 692 dma_free_coherent(&bp->pdev->dev, RX_RING_BYTES,
693 bp->rx_ring, bp->rx_ring_dma); 693 bp->rx_ring, bp->rx_ring_dma);
694 bp->rx_ring = NULL; 694 bp->rx_ring = NULL;
695 } 695 }
696 if (bp->tx_ring) { 696 if (bp->tx_ring) {
697 dma_free_coherent(&bp->pdev->dev, TX_RING_BYTES, 697 dma_free_coherent(&bp->pdev->dev, TX_RING_BYTES,
698 bp->tx_ring, bp->tx_ring_dma); 698 bp->tx_ring, bp->tx_ring_dma);
699 bp->tx_ring = NULL; 699 bp->tx_ring = NULL;
700 } 700 }
701 if (bp->rx_buffers) { 701 if (bp->rx_buffers) {
702 dma_free_coherent(&bp->pdev->dev, 702 dma_free_coherent(&bp->pdev->dev,
703 RX_RING_SIZE * RX_BUFFER_SIZE, 703 RX_RING_SIZE * RX_BUFFER_SIZE,
704 bp->rx_buffers, bp->rx_buffers_dma); 704 bp->rx_buffers, bp->rx_buffers_dma);
705 bp->rx_buffers = NULL; 705 bp->rx_buffers = NULL;
706 } 706 }
707 } 707 }
708 708
709 static int macb_alloc_consistent(struct macb *bp) 709 static int macb_alloc_consistent(struct macb *bp)
710 { 710 {
711 int size; 711 int size;
712 712
713 size = TX_RING_SIZE * sizeof(struct ring_info); 713 size = TX_RING_SIZE * sizeof(struct ring_info);
714 bp->tx_skb = kmalloc(size, GFP_KERNEL); 714 bp->tx_skb = kmalloc(size, GFP_KERNEL);
715 if (!bp->tx_skb) 715 if (!bp->tx_skb)
716 goto out_err; 716 goto out_err;
717 717
718 size = RX_RING_BYTES; 718 size = RX_RING_BYTES;
719 bp->rx_ring = dma_alloc_coherent(&bp->pdev->dev, size, 719 bp->rx_ring = dma_alloc_coherent(&bp->pdev->dev, size,
720 &bp->rx_ring_dma, GFP_KERNEL); 720 &bp->rx_ring_dma, GFP_KERNEL);
721 if (!bp->rx_ring) 721 if (!bp->rx_ring)
722 goto out_err; 722 goto out_err;
723 dev_dbg(&bp->pdev->dev, 723 dev_dbg(&bp->pdev->dev,
724 "Allocated RX ring of %d bytes at %08lx (mapped %p)\n", 724 "Allocated RX ring of %d bytes at %08lx (mapped %p)\n",
725 size, (unsigned long)bp->rx_ring_dma, bp->rx_ring); 725 size, (unsigned long)bp->rx_ring_dma, bp->rx_ring);
726 726
727 size = TX_RING_BYTES; 727 size = TX_RING_BYTES;
728 bp->tx_ring = dma_alloc_coherent(&bp->pdev->dev, size, 728 bp->tx_ring = dma_alloc_coherent(&bp->pdev->dev, size,
729 &bp->tx_ring_dma, GFP_KERNEL); 729 &bp->tx_ring_dma, GFP_KERNEL);
730 if (!bp->tx_ring) 730 if (!bp->tx_ring)
731 goto out_err; 731 goto out_err;
732 dev_dbg(&bp->pdev->dev, 732 dev_dbg(&bp->pdev->dev,
733 "Allocated TX ring of %d bytes at %08lx (mapped %p)\n", 733 "Allocated TX ring of %d bytes at %08lx (mapped %p)\n",
734 size, (unsigned long)bp->tx_ring_dma, bp->tx_ring); 734 size, (unsigned long)bp->tx_ring_dma, bp->tx_ring);
735 735
736 size = RX_RING_SIZE * RX_BUFFER_SIZE; 736 size = RX_RING_SIZE * RX_BUFFER_SIZE;
737 bp->rx_buffers = dma_alloc_coherent(&bp->pdev->dev, size, 737 bp->rx_buffers = dma_alloc_coherent(&bp->pdev->dev, size,
738 &bp->rx_buffers_dma, GFP_KERNEL); 738 &bp->rx_buffers_dma, GFP_KERNEL);
739 if (!bp->rx_buffers) 739 if (!bp->rx_buffers)
740 goto out_err; 740 goto out_err;
741 dev_dbg(&bp->pdev->dev, 741 dev_dbg(&bp->pdev->dev,
742 "Allocated RX buffers of %d bytes at %08lx (mapped %p)\n", 742 "Allocated RX buffers of %d bytes at %08lx (mapped %p)\n",
743 size, (unsigned long)bp->rx_buffers_dma, bp->rx_buffers); 743 size, (unsigned long)bp->rx_buffers_dma, bp->rx_buffers);
744 744
745 return 0; 745 return 0;
746 746
747 out_err: 747 out_err:
748 macb_free_consistent(bp); 748 macb_free_consistent(bp);
749 return -ENOMEM; 749 return -ENOMEM;
750 } 750 }
751 751
752 static void macb_init_rings(struct macb *bp) 752 static void macb_init_rings(struct macb *bp)
753 { 753 {
754 int i; 754 int i;
755 dma_addr_t addr; 755 dma_addr_t addr;
756 756
757 addr = bp->rx_buffers_dma; 757 addr = bp->rx_buffers_dma;
758 for (i = 0; i < RX_RING_SIZE; i++) { 758 for (i = 0; i < RX_RING_SIZE; i++) {
759 bp->rx_ring[i].addr = addr; 759 bp->rx_ring[i].addr = addr;
760 bp->rx_ring[i].ctrl = 0; 760 bp->rx_ring[i].ctrl = 0;
761 addr += RX_BUFFER_SIZE; 761 addr += RX_BUFFER_SIZE;
762 } 762 }
763 bp->rx_ring[RX_RING_SIZE - 1].addr |= MACB_BIT(RX_WRAP); 763 bp->rx_ring[RX_RING_SIZE - 1].addr |= MACB_BIT(RX_WRAP);
764 764
765 for (i = 0; i < TX_RING_SIZE; i++) { 765 for (i = 0; i < TX_RING_SIZE; i++) {
766 bp->tx_ring[i].addr = 0; 766 bp->tx_ring[i].addr = 0;
767 bp->tx_ring[i].ctrl = MACB_BIT(TX_USED); 767 bp->tx_ring[i].ctrl = MACB_BIT(TX_USED);
768 } 768 }
769 bp->tx_ring[TX_RING_SIZE - 1].ctrl |= MACB_BIT(TX_WRAP); 769 bp->tx_ring[TX_RING_SIZE - 1].ctrl |= MACB_BIT(TX_WRAP);
770 770
771 bp->rx_tail = bp->tx_head = bp->tx_tail = 0; 771 bp->rx_tail = bp->tx_head = bp->tx_tail = 0;
772 } 772 }
773 773
774 static void macb_reset_hw(struct macb *bp) 774 static void macb_reset_hw(struct macb *bp)
775 { 775 {
776 /* Make sure we have the write buffer for ourselves */ 776 /* Make sure we have the write buffer for ourselves */
777 wmb(); 777 wmb();
778 778
779 /* 779 /*
780 * Disable RX and TX (XXX: Should we halt the transmission 780 * Disable RX and TX (XXX: Should we halt the transmission
781 * more gracefully?) 781 * more gracefully?)
782 */ 782 */
783 macb_writel(bp, NCR, 0); 783 macb_writel(bp, NCR, 0);
784 784
785 /* Clear the stats registers (XXX: Update stats first?) */ 785 /* Clear the stats registers (XXX: Update stats first?) */
786 macb_writel(bp, NCR, MACB_BIT(CLRSTAT)); 786 macb_writel(bp, NCR, MACB_BIT(CLRSTAT));
787 787
788 /* Clear all status flags */ 788 /* Clear all status flags */
789 macb_writel(bp, TSR, ~0UL); 789 macb_writel(bp, TSR, ~0UL);
790 macb_writel(bp, RSR, ~0UL); 790 macb_writel(bp, RSR, ~0UL);
791 791
792 /* Disable all interrupts */ 792 /* Disable all interrupts */
793 macb_writel(bp, IDR, ~0UL); 793 macb_writel(bp, IDR, ~0UL);
794 macb_readl(bp, ISR); 794 macb_readl(bp, ISR);
795 } 795 }
796 796
797 static void macb_init_hw(struct macb *bp) 797 static void macb_init_hw(struct macb *bp)
798 { 798 {
799 u32 config; 799 u32 config;
800 800
801 macb_reset_hw(bp); 801 macb_reset_hw(bp);
802 __macb_set_hwaddr(bp); 802 __macb_set_hwaddr(bp);
803 803
804 config = macb_readl(bp, NCFGR) & MACB_BF(CLK, -1L); 804 config = macb_readl(bp, NCFGR) & MACB_BF(CLK, -1L);
805 config |= MACB_BIT(PAE); /* PAuse Enable */ 805 config |= MACB_BIT(PAE); /* PAuse Enable */
806 config |= MACB_BIT(DRFCS); /* Discard Rx FCS */ 806 config |= MACB_BIT(DRFCS); /* Discard Rx FCS */
807 if (bp->dev->flags & IFF_PROMISC) 807 if (bp->dev->flags & IFF_PROMISC)
808 config |= MACB_BIT(CAF); /* Copy All Frames */ 808 config |= MACB_BIT(CAF); /* Copy All Frames */
809 if (!(bp->dev->flags & IFF_BROADCAST)) 809 if (!(bp->dev->flags & IFF_BROADCAST))
810 config |= MACB_BIT(NBC); /* No BroadCast */ 810 config |= MACB_BIT(NBC); /* No BroadCast */
811 macb_writel(bp, NCFGR, config); 811 macb_writel(bp, NCFGR, config);
812 812
813 /* Initialize TX and RX buffers */ 813 /* Initialize TX and RX buffers */
814 macb_writel(bp, RBQP, bp->rx_ring_dma); 814 macb_writel(bp, RBQP, bp->rx_ring_dma);
815 macb_writel(bp, TBQP, bp->tx_ring_dma); 815 macb_writel(bp, TBQP, bp->tx_ring_dma);
816 816
817 /* Enable TX and RX */ 817 /* Enable TX and RX */
818 macb_writel(bp, NCR, MACB_BIT(RE) | MACB_BIT(TE) | MACB_BIT(MPE)); 818 macb_writel(bp, NCR, MACB_BIT(RE) | MACB_BIT(TE) | MACB_BIT(MPE));
819 819
820 /* Enable interrupts */ 820 /* Enable interrupts */
821 macb_writel(bp, IER, (MACB_BIT(RCOMP) 821 macb_writel(bp, IER, (MACB_BIT(RCOMP)
822 | MACB_BIT(RXUBR) 822 | MACB_BIT(RXUBR)
823 | MACB_BIT(ISR_TUND) 823 | MACB_BIT(ISR_TUND)
824 | MACB_BIT(ISR_RLE) 824 | MACB_BIT(ISR_RLE)
825 | MACB_BIT(TXERR) 825 | MACB_BIT(TXERR)
826 | MACB_BIT(TCOMP) 826 | MACB_BIT(TCOMP)
827 | MACB_BIT(ISR_ROVR) 827 | MACB_BIT(ISR_ROVR)
828 | MACB_BIT(HRESP))); 828 | MACB_BIT(HRESP)));
829 829
830 } 830 }
831 831
832 /* 832 /*
833 * The hash address register is 64 bits long and takes up two 833 * The hash address register is 64 bits long and takes up two
834 * locations in the memory map. The least significant bits are stored 834 * locations in the memory map. The least significant bits are stored
835 * in EMAC_HSL and the most significant bits in EMAC_HSH. 835 * in EMAC_HSL and the most significant bits in EMAC_HSH.
836 * 836 *
837 * The unicast hash enable and the multicast hash enable bits in the 837 * The unicast hash enable and the multicast hash enable bits in the
838 * network configuration register enable the reception of hash matched 838 * network configuration register enable the reception of hash matched
839 * frames. The destination address is reduced to a 6 bit index into 839 * frames. The destination address is reduced to a 6 bit index into
840 * the 64 bit hash register using the following hash function. The 840 * the 64 bit hash register using the following hash function. The
841 * hash function is an exclusive or of every sixth bit of the 841 * hash function is an exclusive or of every sixth bit of the
842 * destination address. 842 * destination address.
843 * 843 *
844 * hi[5] = da[5] ^ da[11] ^ da[17] ^ da[23] ^ da[29] ^ da[35] ^ da[41] ^ da[47] 844 * hi[5] = da[5] ^ da[11] ^ da[17] ^ da[23] ^ da[29] ^ da[35] ^ da[41] ^ da[47]
845 * hi[4] = da[4] ^ da[10] ^ da[16] ^ da[22] ^ da[28] ^ da[34] ^ da[40] ^ da[46] 845 * hi[4] = da[4] ^ da[10] ^ da[16] ^ da[22] ^ da[28] ^ da[34] ^ da[40] ^ da[46]
846 * hi[3] = da[3] ^ da[09] ^ da[15] ^ da[21] ^ da[27] ^ da[33] ^ da[39] ^ da[45] 846 * hi[3] = da[3] ^ da[09] ^ da[15] ^ da[21] ^ da[27] ^ da[33] ^ da[39] ^ da[45]
847 * hi[2] = da[2] ^ da[08] ^ da[14] ^ da[20] ^ da[26] ^ da[32] ^ da[38] ^ da[44] 847 * hi[2] = da[2] ^ da[08] ^ da[14] ^ da[20] ^ da[26] ^ da[32] ^ da[38] ^ da[44]
848 * hi[1] = da[1] ^ da[07] ^ da[13] ^ da[19] ^ da[25] ^ da[31] ^ da[37] ^ da[43] 848 * hi[1] = da[1] ^ da[07] ^ da[13] ^ da[19] ^ da[25] ^ da[31] ^ da[37] ^ da[43]
849 * hi[0] = da[0] ^ da[06] ^ da[12] ^ da[18] ^ da[24] ^ da[30] ^ da[36] ^ da[42] 849 * hi[0] = da[0] ^ da[06] ^ da[12] ^ da[18] ^ da[24] ^ da[30] ^ da[36] ^ da[42]
850 * 850 *
851 * da[0] represents the least significant bit of the first byte 851 * da[0] represents the least significant bit of the first byte
852 * received, that is, the multicast/unicast indicator, and da[47] 852 * received, that is, the multicast/unicast indicator, and da[47]
853 * represents the most significant bit of the last byte received. If 853 * represents the most significant bit of the last byte received. If
854 * the hash index, hi[n], points to a bit that is set in the hash 854 * the hash index, hi[n], points to a bit that is set in the hash
855 * register then the frame will be matched according to whether the 855 * register then the frame will be matched according to whether the
856 * frame is multicast or unicast. A multicast match will be signalled 856 * frame is multicast or unicast. A multicast match will be signalled
857 * if the multicast hash enable bit is set, da[0] is 1 and the hash 857 * if the multicast hash enable bit is set, da[0] is 1 and the hash
858 * index points to a bit set in the hash register. A unicast match 858 * index points to a bit set in the hash register. A unicast match
859 * will be signalled if the unicast hash enable bit is set, da[0] is 0 859 * will be signalled if the unicast hash enable bit is set, da[0] is 0
860 * and the hash index points to a bit set in the hash register. To 860 * and the hash index points to a bit set in the hash register. To
861 * receive all multicast frames, the hash register should be set with 861 * receive all multicast frames, the hash register should be set with
862 * all ones and the multicast hash enable bit should be set in the 862 * all ones and the multicast hash enable bit should be set in the
863 * network configuration register. 863 * network configuration register.
864 */ 864 */
865 865
866 static inline int hash_bit_value(int bitnr, __u8 *addr) 866 static inline int hash_bit_value(int bitnr, __u8 *addr)
867 { 867 {
868 if (addr[bitnr / 8] & (1 << (bitnr % 8))) 868 if (addr[bitnr / 8] & (1 << (bitnr % 8)))
869 return 1; 869 return 1;
870 return 0; 870 return 0;
871 } 871 }
872 872
873 /* 873 /*
874 * Return the hash index value for the specified address. 874 * Return the hash index value for the specified address.
875 */ 875 */
876 static int hash_get_index(__u8 *addr) 876 static int hash_get_index(__u8 *addr)
877 { 877 {
878 int i, j, bitval; 878 int i, j, bitval;
879 int hash_index = 0; 879 int hash_index = 0;
880 880
881 for (j = 0; j < 6; j++) { 881 for (j = 0; j < 6; j++) {
882 for (i = 0, bitval = 0; i < 8; i++) 882 for (i = 0, bitval = 0; i < 8; i++)
883 bitval ^= hash_bit_value(i*6 + j, addr); 883 bitval ^= hash_bit_value(i*6 + j, addr);
884 884
885 hash_index |= (bitval << j); 885 hash_index |= (bitval << j);
886 } 886 }
887 887
888 return hash_index; 888 return hash_index;
889 } 889 }
890 890
891 /* 891 /*
892 * Add multicast addresses to the internal multicast-hash table. 892 * Add multicast addresses to the internal multicast-hash table.
893 */ 893 */
894 static void macb_sethashtable(struct net_device *dev) 894 static void macb_sethashtable(struct net_device *dev)
895 { 895 {
896 struct dev_mc_list *curr; 896 struct dev_mc_list *curr;
897 unsigned long mc_filter[2]; 897 unsigned long mc_filter[2];
898 unsigned int i, bitnr; 898 unsigned int i, bitnr;
899 struct macb *bp = netdev_priv(dev); 899 struct macb *bp = netdev_priv(dev);
900 900
901 mc_filter[0] = mc_filter[1] = 0; 901 mc_filter[0] = mc_filter[1] = 0;
902 902
903 curr = dev->mc_list; 903 curr = dev->mc_list;
904 for (i = 0; i < dev->mc_count; i++, curr = curr->next) { 904 for (i = 0; i < dev->mc_count; i++, curr = curr->next) {
905 if (!curr) break; /* unexpected end of list */ 905 if (!curr) break; /* unexpected end of list */
906 906
907 bitnr = hash_get_index(curr->dmi_addr); 907 bitnr = hash_get_index(curr->dmi_addr);
908 mc_filter[bitnr >> 5] |= 1 << (bitnr & 31); 908 mc_filter[bitnr >> 5] |= 1 << (bitnr & 31);
909 } 909 }
910 910
911 macb_writel(bp, HRB, mc_filter[0]); 911 macb_writel(bp, HRB, mc_filter[0]);
912 macb_writel(bp, HRT, mc_filter[1]); 912 macb_writel(bp, HRT, mc_filter[1]);
913 } 913 }
914 914
915 /* 915 /*
916 * Enable/Disable promiscuous and multicast modes. 916 * Enable/Disable promiscuous and multicast modes.
917 */ 917 */
918 static void macb_set_rx_mode(struct net_device *dev) 918 static void macb_set_rx_mode(struct net_device *dev)
919 { 919 {
920 unsigned long cfg; 920 unsigned long cfg;
921 struct macb *bp = netdev_priv(dev); 921 struct macb *bp = netdev_priv(dev);
922 922
923 cfg = macb_readl(bp, NCFGR); 923 cfg = macb_readl(bp, NCFGR);
924 924
925 if (dev->flags & IFF_PROMISC) 925 if (dev->flags & IFF_PROMISC)
926 /* Enable promiscuous mode */ 926 /* Enable promiscuous mode */
927 cfg |= MACB_BIT(CAF); 927 cfg |= MACB_BIT(CAF);
928 else if (dev->flags & (~IFF_PROMISC)) 928 else if (dev->flags & (~IFF_PROMISC))
929 /* Disable promiscuous mode */ 929 /* Disable promiscuous mode */
930 cfg &= ~MACB_BIT(CAF); 930 cfg &= ~MACB_BIT(CAF);
931 931
932 if (dev->flags & IFF_ALLMULTI) { 932 if (dev->flags & IFF_ALLMULTI) {
933 /* Enable all multicast mode */ 933 /* Enable all multicast mode */
934 macb_writel(bp, HRB, -1); 934 macb_writel(bp, HRB, -1);
935 macb_writel(bp, HRT, -1); 935 macb_writel(bp, HRT, -1);
936 cfg |= MACB_BIT(NCFGR_MTI); 936 cfg |= MACB_BIT(NCFGR_MTI);
937 } else if (dev->mc_count > 0) { 937 } else if (dev->mc_count > 0) {
938 /* Enable specific multicasts */ 938 /* Enable specific multicasts */
939 macb_sethashtable(dev); 939 macb_sethashtable(dev);
940 cfg |= MACB_BIT(NCFGR_MTI); 940 cfg |= MACB_BIT(NCFGR_MTI);
941 } else if (dev->flags & (~IFF_ALLMULTI)) { 941 } else if (dev->flags & (~IFF_ALLMULTI)) {
942 /* Disable all multicast mode */ 942 /* Disable all multicast mode */
943 macb_writel(bp, HRB, 0); 943 macb_writel(bp, HRB, 0);
944 macb_writel(bp, HRT, 0); 944 macb_writel(bp, HRT, 0);
945 cfg &= ~MACB_BIT(NCFGR_MTI); 945 cfg &= ~MACB_BIT(NCFGR_MTI);
946 } 946 }
947 947
948 macb_writel(bp, NCFGR, cfg); 948 macb_writel(bp, NCFGR, cfg);
949 } 949 }
950 950
951 static int macb_open(struct net_device *dev) 951 static int macb_open(struct net_device *dev)
952 { 952 {
953 struct macb *bp = netdev_priv(dev); 953 struct macb *bp = netdev_priv(dev);
954 int err; 954 int err;
955 955
956 dev_dbg(&bp->pdev->dev, "open\n"); 956 dev_dbg(&bp->pdev->dev, "open\n");
957 957
958 /* if the phy is not yet register, retry later*/ 958 /* if the phy is not yet register, retry later*/
959 if (!bp->phy_dev) 959 if (!bp->phy_dev)
960 return -EAGAIN; 960 return -EAGAIN;
961 961
962 if (!is_valid_ether_addr(dev->dev_addr)) 962 if (!is_valid_ether_addr(dev->dev_addr))
963 return -EADDRNOTAVAIL; 963 return -EADDRNOTAVAIL;
964 964
965 err = macb_alloc_consistent(bp); 965 err = macb_alloc_consistent(bp);
966 if (err) { 966 if (err) {
967 printk(KERN_ERR 967 printk(KERN_ERR
968 "%s: Unable to allocate DMA memory (error %d)\n", 968 "%s: Unable to allocate DMA memory (error %d)\n",
969 dev->name, err); 969 dev->name, err);
970 return err; 970 return err;
971 } 971 }
972 972
973 napi_enable(&bp->napi); 973 napi_enable(&bp->napi);
974 974
975 macb_init_rings(bp); 975 macb_init_rings(bp);
976 macb_init_hw(bp); 976 macb_init_hw(bp);
977 977
978 /* schedule a link state check */ 978 /* schedule a link state check */
979 phy_start(bp->phy_dev); 979 phy_start(bp->phy_dev);
980 980
981 netif_start_queue(dev); 981 netif_start_queue(dev);
982 982
983 return 0; 983 return 0;
984 } 984 }
985 985
986 static int macb_close(struct net_device *dev) 986 static int macb_close(struct net_device *dev)
987 { 987 {
988 struct macb *bp = netdev_priv(dev); 988 struct macb *bp = netdev_priv(dev);
989 unsigned long flags; 989 unsigned long flags;
990 990
991 netif_stop_queue(dev); 991 netif_stop_queue(dev);
992 napi_disable(&bp->napi); 992 napi_disable(&bp->napi);
993 993
994 if (bp->phy_dev) 994 if (bp->phy_dev)
995 phy_stop(bp->phy_dev); 995 phy_stop(bp->phy_dev);
996 996
997 spin_lock_irqsave(&bp->lock, flags); 997 spin_lock_irqsave(&bp->lock, flags);
998 macb_reset_hw(bp); 998 macb_reset_hw(bp);
999 netif_carrier_off(dev); 999 netif_carrier_off(dev);
1000 spin_unlock_irqrestore(&bp->lock, flags); 1000 spin_unlock_irqrestore(&bp->lock, flags);
1001 1001
1002 macb_free_consistent(bp); 1002 macb_free_consistent(bp);
1003 1003
1004 return 0; 1004 return 0;
1005 } 1005 }
1006 1006
1007 static struct net_device_stats *macb_get_stats(struct net_device *dev) 1007 static struct net_device_stats *macb_get_stats(struct net_device *dev)
1008 { 1008 {
1009 struct macb *bp = netdev_priv(dev); 1009 struct macb *bp = netdev_priv(dev);
1010 struct net_device_stats *nstat = &bp->stats; 1010 struct net_device_stats *nstat = &bp->stats;
1011 struct macb_stats *hwstat = &bp->hw_stats; 1011 struct macb_stats *hwstat = &bp->hw_stats;
1012 1012
1013 /* read stats from hardware */ 1013 /* read stats from hardware */
1014 macb_update_stats(bp); 1014 macb_update_stats(bp);
1015 1015
1016 /* Convert HW stats into netdevice stats */ 1016 /* Convert HW stats into netdevice stats */
1017 nstat->rx_errors = (hwstat->rx_fcs_errors + 1017 nstat->rx_errors = (hwstat->rx_fcs_errors +
1018 hwstat->rx_align_errors + 1018 hwstat->rx_align_errors +
1019 hwstat->rx_resource_errors + 1019 hwstat->rx_resource_errors +
1020 hwstat->rx_overruns + 1020 hwstat->rx_overruns +
1021 hwstat->rx_oversize_pkts + 1021 hwstat->rx_oversize_pkts +
1022 hwstat->rx_jabbers + 1022 hwstat->rx_jabbers +
1023 hwstat->rx_undersize_pkts + 1023 hwstat->rx_undersize_pkts +
1024 hwstat->sqe_test_errors + 1024 hwstat->sqe_test_errors +
1025 hwstat->rx_length_mismatch); 1025 hwstat->rx_length_mismatch);
1026 nstat->tx_errors = (hwstat->tx_late_cols + 1026 nstat->tx_errors = (hwstat->tx_late_cols +
1027 hwstat->tx_excessive_cols + 1027 hwstat->tx_excessive_cols +
1028 hwstat->tx_underruns + 1028 hwstat->tx_underruns +
1029 hwstat->tx_carrier_errors); 1029 hwstat->tx_carrier_errors);
1030 nstat->collisions = (hwstat->tx_single_cols + 1030 nstat->collisions = (hwstat->tx_single_cols +
1031 hwstat->tx_multiple_cols + 1031 hwstat->tx_multiple_cols +
1032 hwstat->tx_excessive_cols); 1032 hwstat->tx_excessive_cols);
1033 nstat->rx_length_errors = (hwstat->rx_oversize_pkts + 1033 nstat->rx_length_errors = (hwstat->rx_oversize_pkts +
1034 hwstat->rx_jabbers + 1034 hwstat->rx_jabbers +
1035 hwstat->rx_undersize_pkts + 1035 hwstat->rx_undersize_pkts +
1036 hwstat->rx_length_mismatch); 1036 hwstat->rx_length_mismatch);
1037 nstat->rx_over_errors = hwstat->rx_resource_errors; 1037 nstat->rx_over_errors = hwstat->rx_resource_errors;
1038 nstat->rx_crc_errors = hwstat->rx_fcs_errors; 1038 nstat->rx_crc_errors = hwstat->rx_fcs_errors;
1039 nstat->rx_frame_errors = hwstat->rx_align_errors; 1039 nstat->rx_frame_errors = hwstat->rx_align_errors;
1040 nstat->rx_fifo_errors = hwstat->rx_overruns; 1040 nstat->rx_fifo_errors = hwstat->rx_overruns;
1041 /* XXX: What does "missed" mean? */ 1041 /* XXX: What does "missed" mean? */
1042 nstat->tx_aborted_errors = hwstat->tx_excessive_cols; 1042 nstat->tx_aborted_errors = hwstat->tx_excessive_cols;
1043 nstat->tx_carrier_errors = hwstat->tx_carrier_errors; 1043 nstat->tx_carrier_errors = hwstat->tx_carrier_errors;
1044 nstat->tx_fifo_errors = hwstat->tx_underruns; 1044 nstat->tx_fifo_errors = hwstat->tx_underruns;
1045 /* Don't know about heartbeat or window errors... */ 1045 /* Don't know about heartbeat or window errors... */
1046 1046
1047 return nstat; 1047 return nstat;
1048 } 1048 }
1049 1049
1050 static int macb_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) 1050 static int macb_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
1051 { 1051 {
1052 struct macb *bp = netdev_priv(dev); 1052 struct macb *bp = netdev_priv(dev);
1053 struct phy_device *phydev = bp->phy_dev; 1053 struct phy_device *phydev = bp->phy_dev;
1054 1054
1055 if (!phydev) 1055 if (!phydev)
1056 return -ENODEV; 1056 return -ENODEV;
1057 1057
1058 return phy_ethtool_gset(phydev, cmd); 1058 return phy_ethtool_gset(phydev, cmd);
1059 } 1059 }
1060 1060
1061 static int macb_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) 1061 static int macb_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
1062 { 1062 {
1063 struct macb *bp = netdev_priv(dev); 1063 struct macb *bp = netdev_priv(dev);
1064 struct phy_device *phydev = bp->phy_dev; 1064 struct phy_device *phydev = bp->phy_dev;
1065 1065
1066 if (!phydev) 1066 if (!phydev)
1067 return -ENODEV; 1067 return -ENODEV;
1068 1068
1069 return phy_ethtool_sset(phydev, cmd); 1069 return phy_ethtool_sset(phydev, cmd);
1070 } 1070 }
1071 1071
1072 static void macb_get_drvinfo(struct net_device *dev, 1072 static void macb_get_drvinfo(struct net_device *dev,
1073 struct ethtool_drvinfo *info) 1073 struct ethtool_drvinfo *info)
1074 { 1074 {
1075 struct macb *bp = netdev_priv(dev); 1075 struct macb *bp = netdev_priv(dev);
1076 1076
1077 strcpy(info->driver, bp->pdev->dev.driver->name); 1077 strcpy(info->driver, bp->pdev->dev.driver->name);
1078 strcpy(info->version, "$Revision: 1.14 $"); 1078 strcpy(info->version, "$Revision: 1.14 $");
1079 strcpy(info->bus_info, dev_name(&bp->pdev->dev)); 1079 strcpy(info->bus_info, dev_name(&bp->pdev->dev));
1080 } 1080 }
1081 1081
1082 static const struct ethtool_ops macb_ethtool_ops = { 1082 static const struct ethtool_ops macb_ethtool_ops = {
1083 .get_settings = macb_get_settings, 1083 .get_settings = macb_get_settings,
1084 .set_settings = macb_set_settings, 1084 .set_settings = macb_set_settings,
1085 .get_drvinfo = macb_get_drvinfo, 1085 .get_drvinfo = macb_get_drvinfo,
1086 .get_link = ethtool_op_get_link, 1086 .get_link = ethtool_op_get_link,
1087 }; 1087 };
1088 1088
1089 static int macb_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) 1089 static int macb_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
1090 { 1090 {
1091 struct macb *bp = netdev_priv(dev); 1091 struct macb *bp = netdev_priv(dev);
1092 struct phy_device *phydev = bp->phy_dev; 1092 struct phy_device *phydev = bp->phy_dev;
1093 1093
1094 if (!netif_running(dev)) 1094 if (!netif_running(dev))
1095 return -EINVAL; 1095 return -EINVAL;
1096 1096
1097 if (!phydev) 1097 if (!phydev)
1098 return -ENODEV; 1098 return -ENODEV;
1099 1099
1100 return phy_mii_ioctl(phydev, if_mii(rq), cmd); 1100 return phy_mii_ioctl(phydev, if_mii(rq), cmd);
1101 } 1101 }
1102 1102
1103 static const struct net_device_ops macb_netdev_ops = { 1103 static const struct net_device_ops macb_netdev_ops = {
1104 .ndo_open = macb_open, 1104 .ndo_open = macb_open,
1105 .ndo_stop = macb_close, 1105 .ndo_stop = macb_close,
1106 .ndo_start_xmit = macb_start_xmit, 1106 .ndo_start_xmit = macb_start_xmit,
1107 .ndo_set_multicast_list = macb_set_rx_mode, 1107 .ndo_set_multicast_list = macb_set_rx_mode,
1108 .ndo_get_stats = macb_get_stats, 1108 .ndo_get_stats = macb_get_stats,
1109 .ndo_do_ioctl = macb_ioctl, 1109 .ndo_do_ioctl = macb_ioctl,
1110 .ndo_validate_addr = eth_validate_addr, 1110 .ndo_validate_addr = eth_validate_addr,
1111 .ndo_change_mtu = eth_change_mtu, 1111 .ndo_change_mtu = eth_change_mtu,
1112 .ndo_set_mac_address = eth_mac_addr, 1112 .ndo_set_mac_address = eth_mac_addr,
1113 #ifdef CONFIG_NET_POLL_CONTROLLER 1113 #ifdef CONFIG_NET_POLL_CONTROLLER
1114 .ndo_poll_controller = macb_poll_controller, 1114 .ndo_poll_controller = macb_poll_controller,
1115 #endif 1115 #endif
1116 }; 1116 };
1117 1117
1118 static int __init macb_probe(struct platform_device *pdev) 1118 static int __init macb_probe(struct platform_device *pdev)
1119 { 1119 {
1120 struct eth_platform_data *pdata; 1120 struct eth_platform_data *pdata;
1121 struct resource *regs; 1121 struct resource *regs;
1122 struct net_device *dev; 1122 struct net_device *dev;
1123 struct macb *bp; 1123 struct macb *bp;
1124 struct phy_device *phydev; 1124 struct phy_device *phydev;
1125 unsigned long pclk_hz; 1125 unsigned long pclk_hz;
1126 u32 config; 1126 u32 config;
1127 int err = -ENXIO; 1127 int err = -ENXIO;
1128 1128
1129 regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1129 regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1130 if (!regs) { 1130 if (!regs) {
1131 dev_err(&pdev->dev, "no mmio resource defined\n"); 1131 dev_err(&pdev->dev, "no mmio resource defined\n");
1132 goto err_out; 1132 goto err_out;
1133 } 1133 }
1134 1134
1135 err = -ENOMEM; 1135 err = -ENOMEM;
1136 dev = alloc_etherdev(sizeof(*bp)); 1136 dev = alloc_etherdev(sizeof(*bp));
1137 if (!dev) { 1137 if (!dev) {
1138 dev_err(&pdev->dev, "etherdev alloc failed, aborting.\n"); 1138 dev_err(&pdev->dev, "etherdev alloc failed, aborting.\n");
1139 goto err_out; 1139 goto err_out;
1140 } 1140 }
1141 1141
1142 SET_NETDEV_DEV(dev, &pdev->dev); 1142 SET_NETDEV_DEV(dev, &pdev->dev);
1143 1143
1144 /* TODO: Actually, we have some interesting features... */ 1144 /* TODO: Actually, we have some interesting features... */
1145 dev->features |= 0; 1145 dev->features |= 0;
1146 1146
1147 bp = netdev_priv(dev); 1147 bp = netdev_priv(dev);
1148 bp->pdev = pdev; 1148 bp->pdev = pdev;
1149 bp->dev = dev; 1149 bp->dev = dev;
1150 1150
1151 spin_lock_init(&bp->lock); 1151 spin_lock_init(&bp->lock);
1152 1152
1153 #if defined(CONFIG_ARCH_AT91) 1153 #if defined(CONFIG_ARCH_AT91)
1154 bp->pclk = clk_get(&pdev->dev, "macb_clk"); 1154 bp->pclk = clk_get(&pdev->dev, "macb_clk");
1155 if (IS_ERR(bp->pclk)) { 1155 if (IS_ERR(bp->pclk)) {
1156 dev_err(&pdev->dev, "failed to get macb_clk\n"); 1156 dev_err(&pdev->dev, "failed to get macb_clk\n");
1157 goto err_out_free_dev; 1157 goto err_out_free_dev;
1158 } 1158 }
1159 clk_enable(bp->pclk); 1159 clk_enable(bp->pclk);
1160 #else 1160 #else
1161 bp->pclk = clk_get(&pdev->dev, "pclk"); 1161 bp->pclk = clk_get(&pdev->dev, "pclk");
1162 if (IS_ERR(bp->pclk)) { 1162 if (IS_ERR(bp->pclk)) {
1163 dev_err(&pdev->dev, "failed to get pclk\n"); 1163 dev_err(&pdev->dev, "failed to get pclk\n");
1164 goto err_out_free_dev; 1164 goto err_out_free_dev;
1165 } 1165 }
1166 bp->hclk = clk_get(&pdev->dev, "hclk"); 1166 bp->hclk = clk_get(&pdev->dev, "hclk");
1167 if (IS_ERR(bp->hclk)) { 1167 if (IS_ERR(bp->hclk)) {
1168 dev_err(&pdev->dev, "failed to get hclk\n"); 1168 dev_err(&pdev->dev, "failed to get hclk\n");
1169 goto err_out_put_pclk; 1169 goto err_out_put_pclk;
1170 } 1170 }
1171 1171
1172 clk_enable(bp->pclk); 1172 clk_enable(bp->pclk);
1173 clk_enable(bp->hclk); 1173 clk_enable(bp->hclk);
1174 #endif 1174 #endif
1175 1175
1176 bp->regs = ioremap(regs->start, regs->end - regs->start + 1); 1176 bp->regs = ioremap(regs->start, regs->end - regs->start + 1);
1177 if (!bp->regs) { 1177 if (!bp->regs) {
1178 dev_err(&pdev->dev, "failed to map registers, aborting.\n"); 1178 dev_err(&pdev->dev, "failed to map registers, aborting.\n");
1179 err = -ENOMEM; 1179 err = -ENOMEM;
1180 goto err_out_disable_clocks; 1180 goto err_out_disable_clocks;
1181 } 1181 }
1182 1182
1183 dev->irq = platform_get_irq(pdev, 0); 1183 dev->irq = platform_get_irq(pdev, 0);
1184 err = request_irq(dev->irq, macb_interrupt, IRQF_SAMPLE_RANDOM, 1184 err = request_irq(dev->irq, macb_interrupt, IRQF_SAMPLE_RANDOM,
1185 dev->name, dev); 1185 dev->name, dev);
1186 if (err) { 1186 if (err) {
1187 printk(KERN_ERR 1187 printk(KERN_ERR
1188 "%s: Unable to request IRQ %d (error %d)\n", 1188 "%s: Unable to request IRQ %d (error %d)\n",
1189 dev->name, dev->irq, err); 1189 dev->name, dev->irq, err);
1190 goto err_out_iounmap; 1190 goto err_out_iounmap;
1191 } 1191 }
1192 1192
1193 dev->netdev_ops = &macb_netdev_ops; 1193 dev->netdev_ops = &macb_netdev_ops;
1194 netif_napi_add(dev, &bp->napi, macb_poll, 64); 1194 netif_napi_add(dev, &bp->napi, macb_poll, 64);
1195 dev->ethtool_ops = &macb_ethtool_ops; 1195 dev->ethtool_ops = &macb_ethtool_ops;
1196 1196
1197 dev->base_addr = regs->start; 1197 dev->base_addr = regs->start;
1198 1198
1199 /* Set MII management clock divider */ 1199 /* Set MII management clock divider */
1200 pclk_hz = clk_get_rate(bp->pclk); 1200 pclk_hz = clk_get_rate(bp->pclk);
1201 if (pclk_hz <= 20000000) 1201 if (pclk_hz <= 20000000)
1202 config = MACB_BF(CLK, MACB_CLK_DIV8); 1202 config = MACB_BF(CLK, MACB_CLK_DIV8);
1203 else if (pclk_hz <= 40000000) 1203 else if (pclk_hz <= 40000000)
1204 config = MACB_BF(CLK, MACB_CLK_DIV16); 1204 config = MACB_BF(CLK, MACB_CLK_DIV16);
1205 else if (pclk_hz <= 80000000) 1205 else if (pclk_hz <= 80000000)
1206 config = MACB_BF(CLK, MACB_CLK_DIV32); 1206 config = MACB_BF(CLK, MACB_CLK_DIV32);
1207 else 1207 else
1208 config = MACB_BF(CLK, MACB_CLK_DIV64); 1208 config = MACB_BF(CLK, MACB_CLK_DIV64);
1209 macb_writel(bp, NCFGR, config); 1209 macb_writel(bp, NCFGR, config);
1210 1210
1211 macb_get_hwaddr(bp); 1211 macb_get_hwaddr(bp);
1212 pdata = pdev->dev.platform_data; 1212 pdata = pdev->dev.platform_data;
1213 1213
1214 if (pdata && pdata->is_rmii) 1214 if (pdata && pdata->is_rmii)
1215 #if defined(CONFIG_ARCH_AT91) 1215 #if defined(CONFIG_ARCH_AT91)
1216 macb_writel(bp, USRIO, (MACB_BIT(RMII) | MACB_BIT(CLKEN)) ); 1216 macb_writel(bp, USRIO, (MACB_BIT(RMII) | MACB_BIT(CLKEN)) );
1217 #else 1217 #else
1218 macb_writel(bp, USRIO, 0); 1218 macb_writel(bp, USRIO, 0);
1219 #endif 1219 #endif
1220 else 1220 else
1221 #if defined(CONFIG_ARCH_AT91) 1221 #if defined(CONFIG_ARCH_AT91)
1222 macb_writel(bp, USRIO, MACB_BIT(CLKEN)); 1222 macb_writel(bp, USRIO, MACB_BIT(CLKEN));
1223 #else 1223 #else
1224 macb_writel(bp, USRIO, MACB_BIT(MII)); 1224 macb_writel(bp, USRIO, MACB_BIT(MII));
1225 #endif 1225 #endif
1226 1226
1227 bp->tx_pending = DEF_TX_RING_PENDING; 1227 bp->tx_pending = DEF_TX_RING_PENDING;
1228 1228
1229 err = register_netdev(dev); 1229 err = register_netdev(dev);
1230 if (err) { 1230 if (err) {
1231 dev_err(&pdev->dev, "Cannot register net device, aborting.\n"); 1231 dev_err(&pdev->dev, "Cannot register net device, aborting.\n");
1232 goto err_out_free_irq; 1232 goto err_out_free_irq;
1233 } 1233 }
1234 1234
1235 if (macb_mii_init(bp) != 0) { 1235 if (macb_mii_init(bp) != 0) {
1236 goto err_out_unregister_netdev; 1236 goto err_out_unregister_netdev;
1237 } 1237 }
1238 1238
1239 platform_set_drvdata(pdev, dev); 1239 platform_set_drvdata(pdev, dev);
1240 1240
1241 printk(KERN_INFO "%s: Atmel MACB at 0x%08lx irq %d (%pM)\n", 1241 printk(KERN_INFO "%s: Atmel MACB at 0x%08lx irq %d (%pM)\n",
1242 dev->name, dev->base_addr, dev->irq, dev->dev_addr); 1242 dev->name, dev->base_addr, dev->irq, dev->dev_addr);
1243 1243
1244 phydev = bp->phy_dev; 1244 phydev = bp->phy_dev;
1245 printk(KERN_INFO "%s: attached PHY driver [%s] " 1245 printk(KERN_INFO "%s: attached PHY driver [%s] "
1246 "(mii_bus:phy_addr=%s, irq=%d)\n", dev->name, 1246 "(mii_bus:phy_addr=%s, irq=%d)\n", dev->name,
1247 phydev->drv->name, dev_name(&phydev->dev), phydev->irq); 1247 phydev->drv->name, dev_name(&phydev->dev), phydev->irq);
1248 1248
1249 return 0; 1249 return 0;
1250 1250
1251 err_out_unregister_netdev: 1251 err_out_unregister_netdev:
1252 unregister_netdev(dev); 1252 unregister_netdev(dev);
1253 err_out_free_irq: 1253 err_out_free_irq:
1254 free_irq(dev->irq, dev); 1254 free_irq(dev->irq, dev);
1255 err_out_iounmap: 1255 err_out_iounmap:
1256 iounmap(bp->regs); 1256 iounmap(bp->regs);
1257 err_out_disable_clocks: 1257 err_out_disable_clocks:
1258 #ifndef CONFIG_ARCH_AT91 1258 #ifndef CONFIG_ARCH_AT91
1259 clk_disable(bp->hclk); 1259 clk_disable(bp->hclk);
1260 clk_put(bp->hclk); 1260 clk_put(bp->hclk);
1261 #endif 1261 #endif
1262 clk_disable(bp->pclk); 1262 clk_disable(bp->pclk);
1263 #ifndef CONFIG_ARCH_AT91 1263 #ifndef CONFIG_ARCH_AT91
1264 err_out_put_pclk: 1264 err_out_put_pclk:
1265 #endif 1265 #endif
1266 clk_put(bp->pclk); 1266 clk_put(bp->pclk);
1267 err_out_free_dev: 1267 err_out_free_dev:
1268 free_netdev(dev); 1268 free_netdev(dev);
1269 err_out: 1269 err_out:
1270 platform_set_drvdata(pdev, NULL); 1270 platform_set_drvdata(pdev, NULL);
1271 return err; 1271 return err;
1272 } 1272 }
1273 1273
1274 static int __exit macb_remove(struct platform_device *pdev) 1274 static int __exit macb_remove(struct platform_device *pdev)
1275 { 1275 {
1276 struct net_device *dev; 1276 struct net_device *dev;
1277 struct macb *bp; 1277 struct macb *bp;
1278 1278
1279 dev = platform_get_drvdata(pdev); 1279 dev = platform_get_drvdata(pdev);
1280 1280
1281 if (dev) { 1281 if (dev) {
1282 bp = netdev_priv(dev); 1282 bp = netdev_priv(dev);
1283 if (bp->phy_dev) 1283 if (bp->phy_dev)
1284 phy_disconnect(bp->phy_dev); 1284 phy_disconnect(bp->phy_dev);
1285 mdiobus_unregister(bp->mii_bus); 1285 mdiobus_unregister(bp->mii_bus);
1286 kfree(bp->mii_bus->irq); 1286 kfree(bp->mii_bus->irq);
1287 mdiobus_free(bp->mii_bus); 1287 mdiobus_free(bp->mii_bus);
1288 unregister_netdev(dev); 1288 unregister_netdev(dev);
1289 free_irq(dev->irq, dev); 1289 free_irq(dev->irq, dev);
1290 iounmap(bp->regs); 1290 iounmap(bp->regs);
1291 #ifndef CONFIG_ARCH_AT91 1291 #ifndef CONFIG_ARCH_AT91
1292 clk_disable(bp->hclk); 1292 clk_disable(bp->hclk);
1293 clk_put(bp->hclk); 1293 clk_put(bp->hclk);
1294 #endif 1294 #endif
1295 clk_disable(bp->pclk); 1295 clk_disable(bp->pclk);
1296 clk_put(bp->pclk); 1296 clk_put(bp->pclk);
1297 free_netdev(dev); 1297 free_netdev(dev);
1298 platform_set_drvdata(pdev, NULL); 1298 platform_set_drvdata(pdev, NULL);
1299 } 1299 }
1300 1300
1301 return 0; 1301 return 0;
1302 } 1302 }
1303 1303
1304 #ifdef CONFIG_PM 1304 #ifdef CONFIG_PM
1305 static int macb_suspend(struct platform_device *pdev, pm_message_t state) 1305 static int macb_suspend(struct platform_device *pdev, pm_message_t state)
1306 { 1306 {
1307 struct net_device *netdev = platform_get_drvdata(pdev); 1307 struct net_device *netdev = platform_get_drvdata(pdev);
1308 struct macb *bp = netdev_priv(netdev); 1308 struct macb *bp = netdev_priv(netdev);
1309 1309
1310 netif_device_detach(netdev); 1310 netif_device_detach(netdev);
1311 1311
1312 #ifndef CONFIG_ARCH_AT91 1312 #ifndef CONFIG_ARCH_AT91
1313 clk_disable(bp->hclk); 1313 clk_disable(bp->hclk);
1314 #endif 1314 #endif
1315 clk_disable(bp->pclk); 1315 clk_disable(bp->pclk);
1316 1316
1317 return 0; 1317 return 0;
1318 } 1318 }
1319 1319
1320 static int macb_resume(struct platform_device *pdev) 1320 static int macb_resume(struct platform_device *pdev)
1321 { 1321 {
1322 struct net_device *netdev = platform_get_drvdata(pdev); 1322 struct net_device *netdev = platform_get_drvdata(pdev);
1323 struct macb *bp = netdev_priv(netdev); 1323 struct macb *bp = netdev_priv(netdev);
1324 1324
1325 clk_enable(bp->pclk); 1325 clk_enable(bp->pclk);
1326 #ifndef CONFIG_ARCH_AT91 1326 #ifndef CONFIG_ARCH_AT91
1327 clk_enable(bp->hclk); 1327 clk_enable(bp->hclk);
1328 #endif 1328 #endif
1329 1329
1330 netif_device_attach(netdev); 1330 netif_device_attach(netdev);
1331 1331
1332 return 0; 1332 return 0;
1333 } 1333 }
1334 #else 1334 #else
1335 #define macb_suspend NULL 1335 #define macb_suspend NULL
1336 #define macb_resume NULL 1336 #define macb_resume NULL
1337 #endif 1337 #endif
1338 1338
1339 static struct platform_driver macb_driver = { 1339 static struct platform_driver macb_driver = {
1340 .remove = __exit_p(macb_remove), 1340 .remove = __exit_p(macb_remove),
1341 .suspend = macb_suspend, 1341 .suspend = macb_suspend,
1342 .resume = macb_resume, 1342 .resume = macb_resume,
1343 .driver = { 1343 .driver = {
1344 .name = "macb", 1344 .name = "macb",
1345 .owner = THIS_MODULE, 1345 .owner = THIS_MODULE,
1346 }, 1346 },
1347 }; 1347 };
1348 1348
1349 static int __init macb_init(void) 1349 static int __init macb_init(void)
1350 { 1350 {
1351 return platform_driver_probe(&macb_driver, macb_probe); 1351 return platform_driver_probe(&macb_driver, macb_probe);
1352 } 1352 }
1353 1353
1354 static void __exit macb_exit(void) 1354 static void __exit macb_exit(void)
1355 { 1355 {
1356 platform_driver_unregister(&macb_driver); 1356 platform_driver_unregister(&macb_driver);
1357 } 1357 }
1358 1358
1359 module_init(macb_init); 1359 module_init(macb_init);
1360 module_exit(macb_exit); 1360 module_exit(macb_exit);
1361 1361
1362 MODULE_LICENSE("GPL"); 1362 MODULE_LICENSE("GPL");
1363 MODULE_DESCRIPTION("Atmel MACB Ethernet driver"); 1363 MODULE_DESCRIPTION("Atmel MACB Ethernet driver");
1364 MODULE_AUTHOR("Haavard Skinnemoen <hskinnemoen@atmel.com>"); 1364 MODULE_AUTHOR("Haavard Skinnemoen <hskinnemoen@atmel.com>");
1365 MODULE_ALIAS("platform:macb"); 1365 MODULE_ALIAS("platform:macb");
1366 1366
drivers/net/wireless/ath/ath5k/reg.h
1 /* 1 /*
2 * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com> 2 * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
3 * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org> 3 * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
4 * Copyright (c) 2007-2008 Michael Taylor <mike.taylor@apprion.com> 4 * Copyright (c) 2007-2008 Michael Taylor <mike.taylor@apprion.com>
5 * 5 *
6 * Permission to use, copy, modify, and distribute this software for any 6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above 7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies. 8 * copyright notice and this permission notice appear in all copies.
9 * 9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 * 17 *
18 */ 18 */
19 19
20 /* 20 /*
21 * Register values for Atheros 5210/5211/5212 cards from OpenBSD's ar5k 21 * Register values for Atheros 5210/5211/5212 cards from OpenBSD's ar5k
22 * maintained by Reyk Floeter 22 * maintained by Reyk Floeter
23 * 23 *
24 * I tried to document those registers by looking at ar5k code, some 24 * I tried to document those registers by looking at ar5k code, some
25 * 802.11 (802.11e mostly) papers and by reading various public available 25 * 802.11 (802.11e mostly) papers and by reading various public available
26 * Atheros presentations and papers like these: 26 * Atheros presentations and papers like these:
27 * 27 *
28 * 5210 - http://nova.stanford.edu/~bbaas/ps/isscc2002_slides.pdf 28 * 5210 - http://nova.stanford.edu/~bbaas/ps/isscc2002_slides.pdf
29 * http://www.it.iitb.ac.in/~janak/wifire/01222734.pdf 29 * http://www.it.iitb.ac.in/~janak/wifire/01222734.pdf
30 * 30 *
31 * 5211 - http://www.hotchips.org/archives/hc14/3_Tue/16_mcfarland.pdf 31 * 5211 - http://www.hotchips.org/archives/hc14/3_Tue/16_mcfarland.pdf
32 * 32 *
33 * This file also contains register values found on a memory dump of 33 * This file also contains register values found on a memory dump of
34 * Atheros's ART program (Atheros Radio Test), on ath9k, on legacy-hal 34 * Atheros's ART program (Atheros Radio Test), on ath9k, on legacy-hal
35 * released by Atheros and on various debug messages found on the net. 35 * released by Atheros and on various debug messages found on the net.
36 */ 36 */
37 37
38 38
39 39
40 /*====MAC DMA REGISTERS====*/ 40 /*====MAC DMA REGISTERS====*/
41 41
42 /* 42 /*
43 * AR5210-Specific TXDP registers 43 * AR5210-Specific TXDP registers
44 * 5210 has only 2 transmit queues so no DCU/QCU, just 44 * 5210 has only 2 transmit queues so no DCU/QCU, just
45 * 2 transmit descriptor pointers... 45 * 2 transmit descriptor pointers...
46 */ 46 */
47 #define AR5K_NOQCU_TXDP0 0x0000 /* Queue 0 - data */ 47 #define AR5K_NOQCU_TXDP0 0x0000 /* Queue 0 - data */
48 #define AR5K_NOQCU_TXDP1 0x0004 /* Queue 1 - beacons */ 48 #define AR5K_NOQCU_TXDP1 0x0004 /* Queue 1 - beacons */
49 49
50 /* 50 /*
51 * Mac Control Register 51 * Mac Control Register
52 */ 52 */
53 #define AR5K_CR 0x0008 /* Register Address */ 53 #define AR5K_CR 0x0008 /* Register Address */
54 #define AR5K_CR_TXE0 0x00000001 /* TX Enable for queue 0 on 5210 */ 54 #define AR5K_CR_TXE0 0x00000001 /* TX Enable for queue 0 on 5210 */
55 #define AR5K_CR_TXE1 0x00000002 /* TX Enable for queue 1 on 5210 */ 55 #define AR5K_CR_TXE1 0x00000002 /* TX Enable for queue 1 on 5210 */
56 #define AR5K_CR_RXE 0x00000004 /* RX Enable */ 56 #define AR5K_CR_RXE 0x00000004 /* RX Enable */
57 #define AR5K_CR_TXD0 0x00000008 /* TX Disable for queue 0 on 5210 */ 57 #define AR5K_CR_TXD0 0x00000008 /* TX Disable for queue 0 on 5210 */
58 #define AR5K_CR_TXD1 0x00000010 /* TX Disable for queue 1 on 5210 */ 58 #define AR5K_CR_TXD1 0x00000010 /* TX Disable for queue 1 on 5210 */
59 #define AR5K_CR_RXD 0x00000020 /* RX Disable */ 59 #define AR5K_CR_RXD 0x00000020 /* RX Disable */
60 #define AR5K_CR_SWI 0x00000040 /* Software Interrupt */ 60 #define AR5K_CR_SWI 0x00000040 /* Software Interrupt */
61 61
62 /* 62 /*
63 * RX Descriptor Pointer register 63 * RX Descriptor Pointer register
64 */ 64 */
65 #define AR5K_RXDP 0x000c 65 #define AR5K_RXDP 0x000c
66 66
67 /* 67 /*
68 * Configuration and status register 68 * Configuration and status register
69 */ 69 */
70 #define AR5K_CFG 0x0014 /* Register Address */ 70 #define AR5K_CFG 0x0014 /* Register Address */
71 #define AR5K_CFG_SWTD 0x00000001 /* Byte-swap TX descriptor (for big endian archs) */ 71 #define AR5K_CFG_SWTD 0x00000001 /* Byte-swap TX descriptor (for big endian archs) */
72 #define AR5K_CFG_SWTB 0x00000002 /* Byte-swap TX buffer */ 72 #define AR5K_CFG_SWTB 0x00000002 /* Byte-swap TX buffer */
73 #define AR5K_CFG_SWRD 0x00000004 /* Byte-swap RX descriptor */ 73 #define AR5K_CFG_SWRD 0x00000004 /* Byte-swap RX descriptor */
74 #define AR5K_CFG_SWRB 0x00000008 /* Byte-swap RX buffer */ 74 #define AR5K_CFG_SWRB 0x00000008 /* Byte-swap RX buffer */
75 #define AR5K_CFG_SWRG 0x00000010 /* Byte-swap Register access */ 75 #define AR5K_CFG_SWRG 0x00000010 /* Byte-swap Register access */
76 #define AR5K_CFG_IBSS 0x00000020 /* 0-BSS, 1-IBSS [5211+] */ 76 #define AR5K_CFG_IBSS 0x00000020 /* 0-BSS, 1-IBSS [5211+] */
77 #define AR5K_CFG_PHY_OK 0x00000100 /* [5211+] */ 77 #define AR5K_CFG_PHY_OK 0x00000100 /* [5211+] */
78 #define AR5K_CFG_EEBS 0x00000200 /* EEPROM is busy */ 78 #define AR5K_CFG_EEBS 0x00000200 /* EEPROM is busy */
79 #define AR5K_CFG_CLKGD 0x00000400 /* Clock gated (Disable dynamic clock) */ 79 #define AR5K_CFG_CLKGD 0x00000400 /* Clock gated (Disable dynamic clock) */
80 #define AR5K_CFG_TXCNT 0x00007800 /* Tx frame count (?) [5210] */ 80 #define AR5K_CFG_TXCNT 0x00007800 /* Tx frame count (?) [5210] */
81 #define AR5K_CFG_TXCNT_S 11 81 #define AR5K_CFG_TXCNT_S 11
82 #define AR5K_CFG_TXFSTAT 0x00008000 /* Tx frame status (?) [5210] */ 82 #define AR5K_CFG_TXFSTAT 0x00008000 /* Tx frame status (?) [5210] */
83 #define AR5K_CFG_TXFSTRT 0x00010000 /* [5210] */ 83 #define AR5K_CFG_TXFSTRT 0x00010000 /* [5210] */
84 #define AR5K_CFG_PCI_THRES 0x00060000 /* PCI Master req q threshold [5211+] */ 84 #define AR5K_CFG_PCI_THRES 0x00060000 /* PCI Master req q threshold [5211+] */
85 #define AR5K_CFG_PCI_THRES_S 17 85 #define AR5K_CFG_PCI_THRES_S 17
86 86
87 /* 87 /*
88 * Interrupt enable register 88 * Interrupt enable register
89 */ 89 */
90 #define AR5K_IER 0x0024 /* Register Address */ 90 #define AR5K_IER 0x0024 /* Register Address */
91 #define AR5K_IER_DISABLE 0x00000000 /* Disable card interrupts */ 91 #define AR5K_IER_DISABLE 0x00000000 /* Disable card interrupts */
92 #define AR5K_IER_ENABLE 0x00000001 /* Enable card interrupts */ 92 #define AR5K_IER_ENABLE 0x00000001 /* Enable card interrupts */
93 93
94 94
95 /* 95 /*
96 * 0x0028 is Beacon Control Register on 5210 96 * 0x0028 is Beacon Control Register on 5210
97 * and first RTS duration register on 5211 97 * and first RTS duration register on 5211
98 */ 98 */
99 99
100 /* 100 /*
101 * Beacon control register [5210] 101 * Beacon control register [5210]
102 */ 102 */
103 #define AR5K_BCR 0x0028 /* Register Address */ 103 #define AR5K_BCR 0x0028 /* Register Address */
104 #define AR5K_BCR_AP 0x00000000 /* AP mode */ 104 #define AR5K_BCR_AP 0x00000000 /* AP mode */
105 #define AR5K_BCR_ADHOC 0x00000001 /* Ad-Hoc mode */ 105 #define AR5K_BCR_ADHOC 0x00000001 /* Ad-Hoc mode */
106 #define AR5K_BCR_BDMAE 0x00000002 /* DMA enable */ 106 #define AR5K_BCR_BDMAE 0x00000002 /* DMA enable */
107 #define AR5K_BCR_TQ1FV 0x00000004 /* Use Queue1 for CAB traffic */ 107 #define AR5K_BCR_TQ1FV 0x00000004 /* Use Queue1 for CAB traffic */
108 #define AR5K_BCR_TQ1V 0x00000008 /* Use Queue1 for Beacon traffic */ 108 #define AR5K_BCR_TQ1V 0x00000008 /* Use Queue1 for Beacon traffic */
109 #define AR5K_BCR_BCGET 0x00000010 109 #define AR5K_BCR_BCGET 0x00000010
110 110
111 /* 111 /*
112 * First RTS duration register [5211] 112 * First RTS duration register [5211]
113 */ 113 */
114 #define AR5K_RTSD0 0x0028 /* Register Address */ 114 #define AR5K_RTSD0 0x0028 /* Register Address */
115 #define AR5K_RTSD0_6 0x000000ff /* 6Mb RTS duration mask (?) */ 115 #define AR5K_RTSD0_6 0x000000ff /* 6Mb RTS duration mask (?) */
116 #define AR5K_RTSD0_6_S 0 /* 6Mb RTS duration shift (?) */ 116 #define AR5K_RTSD0_6_S 0 /* 6Mb RTS duration shift (?) */
117 #define AR5K_RTSD0_9 0x0000ff00 /* 9Mb*/ 117 #define AR5K_RTSD0_9 0x0000ff00 /* 9Mb*/
118 #define AR5K_RTSD0_9_S 8 118 #define AR5K_RTSD0_9_S 8
119 #define AR5K_RTSD0_12 0x00ff0000 /* 12Mb*/ 119 #define AR5K_RTSD0_12 0x00ff0000 /* 12Mb*/
120 #define AR5K_RTSD0_12_S 16 120 #define AR5K_RTSD0_12_S 16
121 #define AR5K_RTSD0_18 0xff000000 /* 16Mb*/ 121 #define AR5K_RTSD0_18 0xff000000 /* 16Mb*/
122 #define AR5K_RTSD0_18_S 24 122 #define AR5K_RTSD0_18_S 24
123 123
124 124
125 /* 125 /*
126 * 0x002c is Beacon Status Register on 5210 126 * 0x002c is Beacon Status Register on 5210
127 * and second RTS duration register on 5211 127 * and second RTS duration register on 5211
128 */ 128 */
129 129
130 /* 130 /*
131 * Beacon status register [5210] 131 * Beacon status register [5210]
132 * 132 *
133 * As i can see in ar5k_ar5210_tx_start Reyk uses some of the values of BCR 133 * As i can see in ar5k_ar5210_tx_start Reyk uses some of the values of BCR
134 * for this register, so i guess TQ1V,TQ1FV and BDMAE have the same meaning 134 * for this register, so i guess TQ1V,TQ1FV and BDMAE have the same meaning
135 * here and SNP/SNAP means "snapshot" (so this register gets synced with BCR). 135 * here and SNP/SNAP means "snapshot" (so this register gets synced with BCR).
136 * So SNAPPEDBCRVALID sould also stand for "snapped BCR -values- valid", so i 136 * So SNAPPEDBCRVALID sould also stand for "snapped BCR -values- valid", so i
137 * renamed it to SNAPSHOTSVALID to make more sense. I realy have no idea what 137 * renamed it to SNAPSHOTSVALID to make more sense. I realy have no idea what
138 * else can it be. I also renamed SNPBCMD to SNPADHOC to match BCR. 138 * else can it be. I also renamed SNPBCMD to SNPADHOC to match BCR.
139 */ 139 */
140 #define AR5K_BSR 0x002c /* Register Address */ 140 #define AR5K_BSR 0x002c /* Register Address */
141 #define AR5K_BSR_BDLYSW 0x00000001 /* SW Beacon delay (?) */ 141 #define AR5K_BSR_BDLYSW 0x00000001 /* SW Beacon delay (?) */
142 #define AR5K_BSR_BDLYDMA 0x00000002 /* DMA Beacon delay (?) */ 142 #define AR5K_BSR_BDLYDMA 0x00000002 /* DMA Beacon delay (?) */
143 #define AR5K_BSR_TXQ1F 0x00000004 /* Beacon queue (1) finished */ 143 #define AR5K_BSR_TXQ1F 0x00000004 /* Beacon queue (1) finished */
144 #define AR5K_BSR_ATIMDLY 0x00000008 /* ATIM delay (?) */ 144 #define AR5K_BSR_ATIMDLY 0x00000008 /* ATIM delay (?) */
145 #define AR5K_BSR_SNPADHOC 0x00000100 /* Ad-hoc mode set (?) */ 145 #define AR5K_BSR_SNPADHOC 0x00000100 /* Ad-hoc mode set (?) */
146 #define AR5K_BSR_SNPBDMAE 0x00000200 /* Beacon DMA enabled (?) */ 146 #define AR5K_BSR_SNPBDMAE 0x00000200 /* Beacon DMA enabled (?) */
147 #define AR5K_BSR_SNPTQ1FV 0x00000400 /* Queue1 is used for CAB traffic (?) */ 147 #define AR5K_BSR_SNPTQ1FV 0x00000400 /* Queue1 is used for CAB traffic (?) */
148 #define AR5K_BSR_SNPTQ1V 0x00000800 /* Queue1 is used for Beacon traffic (?) */ 148 #define AR5K_BSR_SNPTQ1V 0x00000800 /* Queue1 is used for Beacon traffic (?) */
149 #define AR5K_BSR_SNAPSHOTSVALID 0x00001000 /* BCR snapshots are valid (?) */ 149 #define AR5K_BSR_SNAPSHOTSVALID 0x00001000 /* BCR snapshots are valid (?) */
150 #define AR5K_BSR_SWBA_CNT 0x00ff0000 150 #define AR5K_BSR_SWBA_CNT 0x00ff0000
151 151
152 /* 152 /*
153 * Second RTS duration register [5211] 153 * Second RTS duration register [5211]
154 */ 154 */
155 #define AR5K_RTSD1 0x002c /* Register Address */ 155 #define AR5K_RTSD1 0x002c /* Register Address */
156 #define AR5K_RTSD1_24 0x000000ff /* 24Mb */ 156 #define AR5K_RTSD1_24 0x000000ff /* 24Mb */
157 #define AR5K_RTSD1_24_S 0 157 #define AR5K_RTSD1_24_S 0
158 #define AR5K_RTSD1_36 0x0000ff00 /* 36Mb */ 158 #define AR5K_RTSD1_36 0x0000ff00 /* 36Mb */
159 #define AR5K_RTSD1_36_S 8 159 #define AR5K_RTSD1_36_S 8
160 #define AR5K_RTSD1_48 0x00ff0000 /* 48Mb */ 160 #define AR5K_RTSD1_48 0x00ff0000 /* 48Mb */
161 #define AR5K_RTSD1_48_S 16 161 #define AR5K_RTSD1_48_S 16
162 #define AR5K_RTSD1_54 0xff000000 /* 54Mb */ 162 #define AR5K_RTSD1_54 0xff000000 /* 54Mb */
163 #define AR5K_RTSD1_54_S 24 163 #define AR5K_RTSD1_54_S 24
164 164
165 165
166 /* 166 /*
167 * Transmit configuration register 167 * Transmit configuration register
168 */ 168 */
169 #define AR5K_TXCFG 0x0030 /* Register Address */ 169 #define AR5K_TXCFG 0x0030 /* Register Address */
170 #define AR5K_TXCFG_SDMAMR 0x00000007 /* DMA size (read) */ 170 #define AR5K_TXCFG_SDMAMR 0x00000007 /* DMA size (read) */
171 #define AR5K_TXCFG_SDMAMR_S 0 171 #define AR5K_TXCFG_SDMAMR_S 0
172 #define AR5K_TXCFG_B_MODE 0x00000008 /* Set b mode for 5111 (enable 2111) */ 172 #define AR5K_TXCFG_B_MODE 0x00000008 /* Set b mode for 5111 (enable 2111) */
173 #define AR5K_TXCFG_TXFSTP 0x00000008 /* TX DMA full Stop [5210] */ 173 #define AR5K_TXCFG_TXFSTP 0x00000008 /* TX DMA full Stop [5210] */
174 #define AR5K_TXCFG_TXFULL 0x000003f0 /* TX Triger level mask */ 174 #define AR5K_TXCFG_TXFULL 0x000003f0 /* TX Triger level mask */
175 #define AR5K_TXCFG_TXFULL_S 4 175 #define AR5K_TXCFG_TXFULL_S 4
176 #define AR5K_TXCFG_TXFULL_0B 0x00000000 176 #define AR5K_TXCFG_TXFULL_0B 0x00000000
177 #define AR5K_TXCFG_TXFULL_64B 0x00000010 177 #define AR5K_TXCFG_TXFULL_64B 0x00000010
178 #define AR5K_TXCFG_TXFULL_128B 0x00000020 178 #define AR5K_TXCFG_TXFULL_128B 0x00000020
179 #define AR5K_TXCFG_TXFULL_192B 0x00000030 179 #define AR5K_TXCFG_TXFULL_192B 0x00000030
180 #define AR5K_TXCFG_TXFULL_256B 0x00000040 180 #define AR5K_TXCFG_TXFULL_256B 0x00000040
181 #define AR5K_TXCFG_TXCONT_EN 0x00000080 181 #define AR5K_TXCFG_TXCONT_EN 0x00000080
182 #define AR5K_TXCFG_DMASIZE 0x00000100 /* Flag for passing DMA size [5210] */ 182 #define AR5K_TXCFG_DMASIZE 0x00000100 /* Flag for passing DMA size [5210] */
183 #define AR5K_TXCFG_JUMBO_DESC_EN 0x00000400 /* Enable jumbo tx descriptors [5211+] */ 183 #define AR5K_TXCFG_JUMBO_DESC_EN 0x00000400 /* Enable jumbo tx descriptors [5211+] */
184 #define AR5K_TXCFG_ADHOC_BCN_ATIM 0x00000800 /* Adhoc Beacon ATIM Policy */ 184 #define AR5K_TXCFG_ADHOC_BCN_ATIM 0x00000800 /* Adhoc Beacon ATIM Policy */
185 #define AR5K_TXCFG_ATIM_WINDOW_DEF_DIS 0x00001000 /* Disable ATIM window defer [5211+] */ 185 #define AR5K_TXCFG_ATIM_WINDOW_DEF_DIS 0x00001000 /* Disable ATIM window defer [5211+] */
186 #define AR5K_TXCFG_RTSRND 0x00001000 /* [5211+] */ 186 #define AR5K_TXCFG_RTSRND 0x00001000 /* [5211+] */
187 #define AR5K_TXCFG_FRMPAD_DIS 0x00002000 /* [5211+] */ 187 #define AR5K_TXCFG_FRMPAD_DIS 0x00002000 /* [5211+] */
188 #define AR5K_TXCFG_RDY_CBR_DIS 0x00004000 /* Ready time CBR disable [5211+] */ 188 #define AR5K_TXCFG_RDY_CBR_DIS 0x00004000 /* Ready time CBR disable [5211+] */
189 #define AR5K_TXCFG_JUMBO_FRM_MODE 0x00008000 /* Jumbo frame mode [5211+] */ 189 #define AR5K_TXCFG_JUMBO_FRM_MODE 0x00008000 /* Jumbo frame mode [5211+] */
190 #define AR5K_TXCFG_DCU_DBL_BUF_DIS 0x00008000 /* Disable double buffering on DCU */ 190 #define AR5K_TXCFG_DCU_DBL_BUF_DIS 0x00008000 /* Disable double buffering on DCU */
191 #define AR5K_TXCFG_DCU_CACHING_DIS 0x00010000 /* Disable DCU caching */ 191 #define AR5K_TXCFG_DCU_CACHING_DIS 0x00010000 /* Disable DCU caching */
192 192
193 /* 193 /*
194 * Receive configuration register 194 * Receive configuration register
195 */ 195 */
196 #define AR5K_RXCFG 0x0034 /* Register Address */ 196 #define AR5K_RXCFG 0x0034 /* Register Address */
197 #define AR5K_RXCFG_SDMAMW 0x00000007 /* DMA size (write) */ 197 #define AR5K_RXCFG_SDMAMW 0x00000007 /* DMA size (write) */
198 #define AR5K_RXCFG_SDMAMW_S 0 198 #define AR5K_RXCFG_SDMAMW_S 0
199 #define AR5K_RXCFG_ZLFDMA 0x00000008 /* Enable Zero-length frame DMA */ 199 #define AR5K_RXCFG_ZLFDMA 0x00000008 /* Enable Zero-length frame DMA */
200 #define AR5K_RXCFG_DEF_ANTENNA 0x00000010 /* Default antenna (?) */ 200 #define AR5K_RXCFG_DEF_ANTENNA 0x00000010 /* Default antenna (?) */
201 #define AR5K_RXCFG_JUMBO_RXE 0x00000020 /* Enable jumbo rx descriptors [5211+] */ 201 #define AR5K_RXCFG_JUMBO_RXE 0x00000020 /* Enable jumbo rx descriptors [5211+] */
202 #define AR5K_RXCFG_JUMBO_WRAP 0x00000040 /* Wrap jumbo frames [5211+] */ 202 #define AR5K_RXCFG_JUMBO_WRAP 0x00000040 /* Wrap jumbo frames [5211+] */
203 #define AR5K_RXCFG_SLE_ENTRY 0x00000080 /* Sleep entry policy */ 203 #define AR5K_RXCFG_SLE_ENTRY 0x00000080 /* Sleep entry policy */
204 204
205 /* 205 /*
206 * Receive jumbo descriptor last address register 206 * Receive jumbo descriptor last address register
207 * Only found in 5211 (?) 207 * Only found in 5211 (?)
208 */ 208 */
209 #define AR5K_RXJLA 0x0038 209 #define AR5K_RXJLA 0x0038
210 210
211 /* 211 /*
212 * MIB control register 212 * MIB control register
213 */ 213 */
214 #define AR5K_MIBC 0x0040 /* Register Address */ 214 #define AR5K_MIBC 0x0040 /* Register Address */
215 #define AR5K_MIBC_COW 0x00000001 /* Warn test indicator */ 215 #define AR5K_MIBC_COW 0x00000001 /* Warn test indicator */
216 #define AR5K_MIBC_FMC 0x00000002 /* Freeze MIB Counters */ 216 #define AR5K_MIBC_FMC 0x00000002 /* Freeze MIB Counters */
217 #define AR5K_MIBC_CMC 0x00000004 /* Clean MIB Counters */ 217 #define AR5K_MIBC_CMC 0x00000004 /* Clean MIB Counters */
218 #define AR5K_MIBC_MCS 0x00000008 /* MIB counter strobe */ 218 #define AR5K_MIBC_MCS 0x00000008 /* MIB counter strobe */
219 219
220 /* 220 /*
221 * Timeout prescale register 221 * Timeout prescale register
222 */ 222 */
223 #define AR5K_TOPS 0x0044 223 #define AR5K_TOPS 0x0044
224 #define AR5K_TOPS_M 0x0000ffff 224 #define AR5K_TOPS_M 0x0000ffff
225 225
226 /* 226 /*
227 * Receive timeout register (no frame received) 227 * Receive timeout register (no frame received)
228 */ 228 */
229 #define AR5K_RXNOFRM 0x0048 229 #define AR5K_RXNOFRM 0x0048
230 #define AR5K_RXNOFRM_M 0x000003ff 230 #define AR5K_RXNOFRM_M 0x000003ff
231 231
232 /* 232 /*
233 * Transmit timeout register (no frame sent) 233 * Transmit timeout register (no frame sent)
234 */ 234 */
235 #define AR5K_TXNOFRM 0x004c 235 #define AR5K_TXNOFRM 0x004c
236 #define AR5K_TXNOFRM_M 0x000003ff 236 #define AR5K_TXNOFRM_M 0x000003ff
237 #define AR5K_TXNOFRM_QCU 0x000ffc00 237 #define AR5K_TXNOFRM_QCU 0x000ffc00
238 #define AR5K_TXNOFRM_QCU_S 10 238 #define AR5K_TXNOFRM_QCU_S 10
239 239
240 /* 240 /*
241 * Receive frame gap timeout register 241 * Receive frame gap timeout register
242 */ 242 */
243 #define AR5K_RPGTO 0x0050 243 #define AR5K_RPGTO 0x0050
244 #define AR5K_RPGTO_M 0x000003ff 244 #define AR5K_RPGTO_M 0x000003ff
245 245
246 /* 246 /*
247 * Receive frame count limit register 247 * Receive frame count limit register
248 */ 248 */
249 #define AR5K_RFCNT 0x0054 249 #define AR5K_RFCNT 0x0054
250 #define AR5K_RFCNT_M 0x0000001f /* [5211+] (?) */ 250 #define AR5K_RFCNT_M 0x0000001f /* [5211+] (?) */
251 #define AR5K_RFCNT_RFCL 0x0000000f /* [5210] */ 251 #define AR5K_RFCNT_RFCL 0x0000000f /* [5210] */
252 252
253 /* 253 /*
254 * Misc settings register 254 * Misc settings register
255 * (reserved0-3) 255 * (reserved0-3)
256 */ 256 */
257 #define AR5K_MISC 0x0058 /* Register Address */ 257 #define AR5K_MISC 0x0058 /* Register Address */
258 #define AR5K_MISC_DMA_OBS_M 0x000001e0 258 #define AR5K_MISC_DMA_OBS_M 0x000001e0
259 #define AR5K_MISC_DMA_OBS_S 5 259 #define AR5K_MISC_DMA_OBS_S 5
260 #define AR5K_MISC_MISC_OBS_M 0x00000e00 260 #define AR5K_MISC_MISC_OBS_M 0x00000e00
261 #define AR5K_MISC_MISC_OBS_S 9 261 #define AR5K_MISC_MISC_OBS_S 9
262 #define AR5K_MISC_MAC_OBS_LSB_M 0x00007000 262 #define AR5K_MISC_MAC_OBS_LSB_M 0x00007000
263 #define AR5K_MISC_MAC_OBS_LSB_S 12 263 #define AR5K_MISC_MAC_OBS_LSB_S 12
264 #define AR5K_MISC_MAC_OBS_MSB_M 0x00038000 264 #define AR5K_MISC_MAC_OBS_MSB_M 0x00038000
265 #define AR5K_MISC_MAC_OBS_MSB_S 15 265 #define AR5K_MISC_MAC_OBS_MSB_S 15
266 #define AR5K_MISC_LED_DECAY 0x001c0000 /* [5210] */ 266 #define AR5K_MISC_LED_DECAY 0x001c0000 /* [5210] */
267 #define AR5K_MISC_LED_BLINK 0x00e00000 /* [5210] */ 267 #define AR5K_MISC_LED_BLINK 0x00e00000 /* [5210] */
268 268
269 /* 269 /*
270 * QCU/DCU clock gating register (5311) 270 * QCU/DCU clock gating register (5311)
271 * (reserved4-5) 271 * (reserved4-5)
272 */ 272 */
273 #define AR5K_QCUDCU_CLKGT 0x005c /* Register Address (?) */ 273 #define AR5K_QCUDCU_CLKGT 0x005c /* Register Address (?) */
274 #define AR5K_QCUDCU_CLKGT_QCU 0x0000ffff /* Mask for QCU clock */ 274 #define AR5K_QCUDCU_CLKGT_QCU 0x0000ffff /* Mask for QCU clock */
275 #define AR5K_QCUDCU_CLKGT_DCU 0x07ff0000 /* Mask for DCU clock */ 275 #define AR5K_QCUDCU_CLKGT_DCU 0x07ff0000 /* Mask for DCU clock */
276 276
277 /* 277 /*
278 * Interrupt Status Registers 278 * Interrupt Status Registers
279 * 279 *
280 * For 5210 there is only one status register but for 280 * For 5210 there is only one status register but for
281 * 5211/5212 we have one primary and 4 secondary registers. 281 * 5211/5212 we have one primary and 4 secondary registers.
282 * So we have AR5K_ISR for 5210 and AR5K_PISR /SISRx for 5211/5212. 282 * So we have AR5K_ISR for 5210 and AR5K_PISR /SISRx for 5211/5212.
283 * Most of these bits are common for all chipsets. 283 * Most of these bits are common for all chipsets.
284 */ 284 */
285 #define AR5K_ISR 0x001c /* Register Address [5210] */ 285 #define AR5K_ISR 0x001c /* Register Address [5210] */
286 #define AR5K_PISR 0x0080 /* Register Address [5211+] */ 286 #define AR5K_PISR 0x0080 /* Register Address [5211+] */
287 #define AR5K_ISR_RXOK 0x00000001 /* Frame successfuly recieved */ 287 #define AR5K_ISR_RXOK 0x00000001 /* Frame successfuly recieved */
288 #define AR5K_ISR_RXDESC 0x00000002 /* RX descriptor request */ 288 #define AR5K_ISR_RXDESC 0x00000002 /* RX descriptor request */
289 #define AR5K_ISR_RXERR 0x00000004 /* Receive error */ 289 #define AR5K_ISR_RXERR 0x00000004 /* Receive error */
290 #define AR5K_ISR_RXNOFRM 0x00000008 /* No frame received (receive timeout) */ 290 #define AR5K_ISR_RXNOFRM 0x00000008 /* No frame received (receive timeout) */
291 #define AR5K_ISR_RXEOL 0x00000010 /* Empty RX descriptor */ 291 #define AR5K_ISR_RXEOL 0x00000010 /* Empty RX descriptor */
292 #define AR5K_ISR_RXORN 0x00000020 /* Receive FIFO overrun */ 292 #define AR5K_ISR_RXORN 0x00000020 /* Receive FIFO overrun */
293 #define AR5K_ISR_TXOK 0x00000040 /* Frame successfuly transmited */ 293 #define AR5K_ISR_TXOK 0x00000040 /* Frame successfuly transmited */
294 #define AR5K_ISR_TXDESC 0x00000080 /* TX descriptor request */ 294 #define AR5K_ISR_TXDESC 0x00000080 /* TX descriptor request */
295 #define AR5K_ISR_TXERR 0x00000100 /* Transmit error */ 295 #define AR5K_ISR_TXERR 0x00000100 /* Transmit error */
296 #define AR5K_ISR_TXNOFRM 0x00000200 /* No frame transmited (transmit timeout) */ 296 #define AR5K_ISR_TXNOFRM 0x00000200 /* No frame transmited (transmit timeout) */
297 #define AR5K_ISR_TXEOL 0x00000400 /* Empty TX descriptor */ 297 #define AR5K_ISR_TXEOL 0x00000400 /* Empty TX descriptor */
298 #define AR5K_ISR_TXURN 0x00000800 /* Transmit FIFO underrun */ 298 #define AR5K_ISR_TXURN 0x00000800 /* Transmit FIFO underrun */
299 #define AR5K_ISR_MIB 0x00001000 /* Update MIB counters */ 299 #define AR5K_ISR_MIB 0x00001000 /* Update MIB counters */
300 #define AR5K_ISR_SWI 0x00002000 /* Software interrupt */ 300 #define AR5K_ISR_SWI 0x00002000 /* Software interrupt */
301 #define AR5K_ISR_RXPHY 0x00004000 /* PHY error */ 301 #define AR5K_ISR_RXPHY 0x00004000 /* PHY error */
302 #define AR5K_ISR_RXKCM 0x00008000 /* RX Key cache miss */ 302 #define AR5K_ISR_RXKCM 0x00008000 /* RX Key cache miss */
303 #define AR5K_ISR_SWBA 0x00010000 /* Software beacon alert */ 303 #define AR5K_ISR_SWBA 0x00010000 /* Software beacon alert */
304 #define AR5K_ISR_BRSSI 0x00020000 /* Beacon rssi below threshold (?) */ 304 #define AR5K_ISR_BRSSI 0x00020000 /* Beacon rssi below threshold (?) */
305 #define AR5K_ISR_BMISS 0x00040000 /* Beacon missed */ 305 #define AR5K_ISR_BMISS 0x00040000 /* Beacon missed */
306 #define AR5K_ISR_HIUERR 0x00080000 /* Host Interface Unit error [5211+] */ 306 #define AR5K_ISR_HIUERR 0x00080000 /* Host Interface Unit error [5211+] */
307 #define AR5K_ISR_BNR 0x00100000 /* Beacon not ready [5211+] */ 307 #define AR5K_ISR_BNR 0x00100000 /* Beacon not ready [5211+] */
308 #define AR5K_ISR_MCABT 0x00100000 /* Master Cycle Abort [5210] */ 308 #define AR5K_ISR_MCABT 0x00100000 /* Master Cycle Abort [5210] */
309 #define AR5K_ISR_RXCHIRP 0x00200000 /* CHIRP Received [5212+] */ 309 #define AR5K_ISR_RXCHIRP 0x00200000 /* CHIRP Received [5212+] */
310 #define AR5K_ISR_SSERR 0x00200000 /* Signaled System Error [5210] */ 310 #define AR5K_ISR_SSERR 0x00200000 /* Signaled System Error [5210] */
311 #define AR5K_ISR_DPERR 0x00400000 /* Det par Error (?) [5210] */ 311 #define AR5K_ISR_DPERR 0x00400000 /* Det par Error (?) [5210] */
312 #define AR5K_ISR_RXDOPPLER 0x00400000 /* Doppler chirp received [5212+] */ 312 #define AR5K_ISR_RXDOPPLER 0x00400000 /* Doppler chirp received [5212+] */
313 #define AR5K_ISR_TIM 0x00800000 /* [5211+] */ 313 #define AR5K_ISR_TIM 0x00800000 /* [5211+] */
314 #define AR5K_ISR_BCNMISC 0x00800000 /* 'or' of TIM, CAB_END, DTIM_SYNC, BCN_TIMEOUT, 314 #define AR5K_ISR_BCNMISC 0x00800000 /* 'or' of TIM, CAB_END, DTIM_SYNC, BCN_TIMEOUT,
315 CAB_TIMEOUT and DTIM bits from SISR2 [5212+] */ 315 CAB_TIMEOUT and DTIM bits from SISR2 [5212+] */
316 #define AR5K_ISR_GPIO 0x01000000 /* GPIO (rf kill) */ 316 #define AR5K_ISR_GPIO 0x01000000 /* GPIO (rf kill) */
317 #define AR5K_ISR_QCBRORN 0x02000000 /* QCU CBR overrun [5211+] */ 317 #define AR5K_ISR_QCBRORN 0x02000000 /* QCU CBR overrun [5211+] */
318 #define AR5K_ISR_QCBRURN 0x04000000 /* QCU CBR underrun [5211+] */ 318 #define AR5K_ISR_QCBRURN 0x04000000 /* QCU CBR underrun [5211+] */
319 #define AR5K_ISR_QTRIG 0x08000000 /* QCU scheduling trigger [5211+] */ 319 #define AR5K_ISR_QTRIG 0x08000000 /* QCU scheduling trigger [5211+] */
320 320
321 /* 321 /*
322 * Secondary status registers [5211+] (0 - 4) 322 * Secondary status registers [5211+] (0 - 4)
323 * 323 *
324 * These give the status for each QCU, only QCUs 0-9 are 324 * These give the status for each QCU, only QCUs 0-9 are
325 * represented. 325 * represented.
326 */ 326 */
327 #define AR5K_SISR0 0x0084 /* Register Address [5211+] */ 327 #define AR5K_SISR0 0x0084 /* Register Address [5211+] */
328 #define AR5K_SISR0_QCU_TXOK 0x000003ff /* Mask for QCU_TXOK */ 328 #define AR5K_SISR0_QCU_TXOK 0x000003ff /* Mask for QCU_TXOK */
329 #define AR5K_SISR0_QCU_TXOK_S 0 329 #define AR5K_SISR0_QCU_TXOK_S 0
330 #define AR5K_SISR0_QCU_TXDESC 0x03ff0000 /* Mask for QCU_TXDESC */ 330 #define AR5K_SISR0_QCU_TXDESC 0x03ff0000 /* Mask for QCU_TXDESC */
331 #define AR5K_SISR0_QCU_TXDESC_S 16 331 #define AR5K_SISR0_QCU_TXDESC_S 16
332 332
333 #define AR5K_SISR1 0x0088 /* Register Address [5211+] */ 333 #define AR5K_SISR1 0x0088 /* Register Address [5211+] */
334 #define AR5K_SISR1_QCU_TXERR 0x000003ff /* Mask for QCU_TXERR */ 334 #define AR5K_SISR1_QCU_TXERR 0x000003ff /* Mask for QCU_TXERR */
335 #define AR5K_SISR1_QCU_TXERR_S 0 335 #define AR5K_SISR1_QCU_TXERR_S 0
336 #define AR5K_SISR1_QCU_TXEOL 0x03ff0000 /* Mask for QCU_TXEOL */ 336 #define AR5K_SISR1_QCU_TXEOL 0x03ff0000 /* Mask for QCU_TXEOL */
337 #define AR5K_SISR1_QCU_TXEOL_S 16 337 #define AR5K_SISR1_QCU_TXEOL_S 16
338 338
339 #define AR5K_SISR2 0x008c /* Register Address [5211+] */ 339 #define AR5K_SISR2 0x008c /* Register Address [5211+] */
340 #define AR5K_SISR2_QCU_TXURN 0x000003ff /* Mask for QCU_TXURN */ 340 #define AR5K_SISR2_QCU_TXURN 0x000003ff /* Mask for QCU_TXURN */
341 #define AR5K_SISR2_QCU_TXURN_S 0 341 #define AR5K_SISR2_QCU_TXURN_S 0
342 #define AR5K_SISR2_MCABT 0x00010000 /* Master Cycle Abort */ 342 #define AR5K_SISR2_MCABT 0x00010000 /* Master Cycle Abort */
343 #define AR5K_SISR2_SSERR 0x00020000 /* Signaled System Error */ 343 #define AR5K_SISR2_SSERR 0x00020000 /* Signaled System Error */
344 #define AR5K_SISR2_DPERR 0x00040000 /* Bus parity error */ 344 #define AR5K_SISR2_DPERR 0x00040000 /* Bus parity error */
345 #define AR5K_SISR2_TIM 0x01000000 /* [5212+] */ 345 #define AR5K_SISR2_TIM 0x01000000 /* [5212+] */
346 #define AR5K_SISR2_CAB_END 0x02000000 /* [5212+] */ 346 #define AR5K_SISR2_CAB_END 0x02000000 /* [5212+] */
347 #define AR5K_SISR2_DTIM_SYNC 0x04000000 /* DTIM sync lost [5212+] */ 347 #define AR5K_SISR2_DTIM_SYNC 0x04000000 /* DTIM sync lost [5212+] */
348 #define AR5K_SISR2_BCN_TIMEOUT 0x08000000 /* Beacon Timeout [5212+] */ 348 #define AR5K_SISR2_BCN_TIMEOUT 0x08000000 /* Beacon Timeout [5212+] */
349 #define AR5K_SISR2_CAB_TIMEOUT 0x10000000 /* CAB Timeout [5212+] */ 349 #define AR5K_SISR2_CAB_TIMEOUT 0x10000000 /* CAB Timeout [5212+] */
350 #define AR5K_SISR2_DTIM 0x20000000 /* [5212+] */ 350 #define AR5K_SISR2_DTIM 0x20000000 /* [5212+] */
351 #define AR5K_SISR2_TSFOOR 0x80000000 /* TSF OOR (?) */ 351 #define AR5K_SISR2_TSFOOR 0x80000000 /* TSF OOR (?) */
352 352
353 #define AR5K_SISR3 0x0090 /* Register Address [5211+] */ 353 #define AR5K_SISR3 0x0090 /* Register Address [5211+] */
354 #define AR5K_SISR3_QCBRORN 0x000003ff /* Mask for QCBRORN */ 354 #define AR5K_SISR3_QCBRORN 0x000003ff /* Mask for QCBRORN */
355 #define AR5K_SISR3_QCBRORN_S 0 355 #define AR5K_SISR3_QCBRORN_S 0
356 #define AR5K_SISR3_QCBRURN 0x03ff0000 /* Mask for QCBRURN */ 356 #define AR5K_SISR3_QCBRURN 0x03ff0000 /* Mask for QCBRURN */
357 #define AR5K_SISR3_QCBRURN_S 16 357 #define AR5K_SISR3_QCBRURN_S 16
358 358
359 #define AR5K_SISR4 0x0094 /* Register Address [5211+] */ 359 #define AR5K_SISR4 0x0094 /* Register Address [5211+] */
360 #define AR5K_SISR4_QTRIG 0x000003ff /* Mask for QTRIG */ 360 #define AR5K_SISR4_QTRIG 0x000003ff /* Mask for QTRIG */
361 #define AR5K_SISR4_QTRIG_S 0 361 #define AR5K_SISR4_QTRIG_S 0
362 362
363 /* 363 /*
364 * Shadow read-and-clear interrupt status registers [5211+] 364 * Shadow read-and-clear interrupt status registers [5211+]
365 */ 365 */
366 #define AR5K_RAC_PISR 0x00c0 /* Read and clear PISR */ 366 #define AR5K_RAC_PISR 0x00c0 /* Read and clear PISR */
367 #define AR5K_RAC_SISR0 0x00c4 /* Read and clear SISR0 */ 367 #define AR5K_RAC_SISR0 0x00c4 /* Read and clear SISR0 */
368 #define AR5K_RAC_SISR1 0x00c8 /* Read and clear SISR1 */ 368 #define AR5K_RAC_SISR1 0x00c8 /* Read and clear SISR1 */
369 #define AR5K_RAC_SISR2 0x00cc /* Read and clear SISR2 */ 369 #define AR5K_RAC_SISR2 0x00cc /* Read and clear SISR2 */
370 #define AR5K_RAC_SISR3 0x00d0 /* Read and clear SISR3 */ 370 #define AR5K_RAC_SISR3 0x00d0 /* Read and clear SISR3 */
371 #define AR5K_RAC_SISR4 0x00d4 /* Read and clear SISR4 */ 371 #define AR5K_RAC_SISR4 0x00d4 /* Read and clear SISR4 */
372 372
373 /* 373 /*
374 * Interrupt Mask Registers 374 * Interrupt Mask Registers
375 * 375 *
376 * As whith ISRs 5210 has one IMR (AR5K_IMR) and 5211/5212 has one primary 376 * As whith ISRs 5210 has one IMR (AR5K_IMR) and 5211/5212 has one primary
377 * (AR5K_PIMR) and 4 secondary IMRs (AR5K_SIMRx). Note that ISR/IMR flags match. 377 * (AR5K_PIMR) and 4 secondary IMRs (AR5K_SIMRx). Note that ISR/IMR flags match.
378 */ 378 */
379 #define AR5K_IMR 0x0020 /* Register Address [5210] */ 379 #define AR5K_IMR 0x0020 /* Register Address [5210] */
380 #define AR5K_PIMR 0x00a0 /* Register Address [5211+] */ 380 #define AR5K_PIMR 0x00a0 /* Register Address [5211+] */
381 #define AR5K_IMR_RXOK 0x00000001 /* Frame successfuly recieved*/ 381 #define AR5K_IMR_RXOK 0x00000001 /* Frame successfuly recieved*/
382 #define AR5K_IMR_RXDESC 0x00000002 /* RX descriptor request*/ 382 #define AR5K_IMR_RXDESC 0x00000002 /* RX descriptor request*/
383 #define AR5K_IMR_RXERR 0x00000004 /* Receive error*/ 383 #define AR5K_IMR_RXERR 0x00000004 /* Receive error*/
384 #define AR5K_IMR_RXNOFRM 0x00000008 /* No frame received (receive timeout)*/ 384 #define AR5K_IMR_RXNOFRM 0x00000008 /* No frame received (receive timeout)*/
385 #define AR5K_IMR_RXEOL 0x00000010 /* Empty RX descriptor*/ 385 #define AR5K_IMR_RXEOL 0x00000010 /* Empty RX descriptor*/
386 #define AR5K_IMR_RXORN 0x00000020 /* Receive FIFO overrun*/ 386 #define AR5K_IMR_RXORN 0x00000020 /* Receive FIFO overrun*/
387 #define AR5K_IMR_TXOK 0x00000040 /* Frame successfuly transmited*/ 387 #define AR5K_IMR_TXOK 0x00000040 /* Frame successfuly transmited*/
388 #define AR5K_IMR_TXDESC 0x00000080 /* TX descriptor request*/ 388 #define AR5K_IMR_TXDESC 0x00000080 /* TX descriptor request*/
389 #define AR5K_IMR_TXERR 0x00000100 /* Transmit error*/ 389 #define AR5K_IMR_TXERR 0x00000100 /* Transmit error*/
390 #define AR5K_IMR_TXNOFRM 0x00000200 /* No frame transmited (transmit timeout)*/ 390 #define AR5K_IMR_TXNOFRM 0x00000200 /* No frame transmited (transmit timeout)*/
391 #define AR5K_IMR_TXEOL 0x00000400 /* Empty TX descriptor*/ 391 #define AR5K_IMR_TXEOL 0x00000400 /* Empty TX descriptor*/
392 #define AR5K_IMR_TXURN 0x00000800 /* Transmit FIFO underrun*/ 392 #define AR5K_IMR_TXURN 0x00000800 /* Transmit FIFO underrun*/
393 #define AR5K_IMR_MIB 0x00001000 /* Update MIB counters*/ 393 #define AR5K_IMR_MIB 0x00001000 /* Update MIB counters*/
394 #define AR5K_IMR_SWI 0x00002000 /* Software interrupt */ 394 #define AR5K_IMR_SWI 0x00002000 /* Software interrupt */
395 #define AR5K_IMR_RXPHY 0x00004000 /* PHY error*/ 395 #define AR5K_IMR_RXPHY 0x00004000 /* PHY error*/
396 #define AR5K_IMR_RXKCM 0x00008000 /* RX Key cache miss */ 396 #define AR5K_IMR_RXKCM 0x00008000 /* RX Key cache miss */
397 #define AR5K_IMR_SWBA 0x00010000 /* Software beacon alert*/ 397 #define AR5K_IMR_SWBA 0x00010000 /* Software beacon alert*/
398 #define AR5K_IMR_BRSSI 0x00020000 /* Beacon rssi below threshold (?) */ 398 #define AR5K_IMR_BRSSI 0x00020000 /* Beacon rssi below threshold (?) */
399 #define AR5K_IMR_BMISS 0x00040000 /* Beacon missed*/ 399 #define AR5K_IMR_BMISS 0x00040000 /* Beacon missed*/
400 #define AR5K_IMR_HIUERR 0x00080000 /* Host Interface Unit error [5211+] */ 400 #define AR5K_IMR_HIUERR 0x00080000 /* Host Interface Unit error [5211+] */
401 #define AR5K_IMR_BNR 0x00100000 /* Beacon not ready [5211+] */ 401 #define AR5K_IMR_BNR 0x00100000 /* Beacon not ready [5211+] */
402 #define AR5K_IMR_MCABT 0x00100000 /* Master Cycle Abort [5210] */ 402 #define AR5K_IMR_MCABT 0x00100000 /* Master Cycle Abort [5210] */
403 #define AR5K_IMR_RXCHIRP 0x00200000 /* CHIRP Received [5212+]*/ 403 #define AR5K_IMR_RXCHIRP 0x00200000 /* CHIRP Received [5212+]*/
404 #define AR5K_IMR_SSERR 0x00200000 /* Signaled System Error [5210] */ 404 #define AR5K_IMR_SSERR 0x00200000 /* Signaled System Error [5210] */
405 #define AR5K_IMR_DPERR 0x00400000 /* Det par Error (?) [5210] */ 405 #define AR5K_IMR_DPERR 0x00400000 /* Det par Error (?) [5210] */
406 #define AR5K_IMR_RXDOPPLER 0x00400000 /* Doppler chirp received [5212+] */ 406 #define AR5K_IMR_RXDOPPLER 0x00400000 /* Doppler chirp received [5212+] */
407 #define AR5K_IMR_TIM 0x00800000 /* [5211+] */ 407 #define AR5K_IMR_TIM 0x00800000 /* [5211+] */
408 #define AR5K_IMR_BCNMISC 0x00800000 /* 'or' of TIM, CAB_END, DTIM_SYNC, BCN_TIMEOUT, 408 #define AR5K_IMR_BCNMISC 0x00800000 /* 'or' of TIM, CAB_END, DTIM_SYNC, BCN_TIMEOUT,
409 CAB_TIMEOUT and DTIM bits from SISR2 [5212+] */ 409 CAB_TIMEOUT and DTIM bits from SISR2 [5212+] */
410 #define AR5K_IMR_GPIO 0x01000000 /* GPIO (rf kill)*/ 410 #define AR5K_IMR_GPIO 0x01000000 /* GPIO (rf kill)*/
411 #define AR5K_IMR_QCBRORN 0x02000000 /* QCU CBR overrun (?) [5211+] */ 411 #define AR5K_IMR_QCBRORN 0x02000000 /* QCU CBR overrun (?) [5211+] */
412 #define AR5K_IMR_QCBRURN 0x04000000 /* QCU CBR underrun (?) [5211+] */ 412 #define AR5K_IMR_QCBRURN 0x04000000 /* QCU CBR underrun (?) [5211+] */
413 #define AR5K_IMR_QTRIG 0x08000000 /* QCU scheduling trigger [5211+] */ 413 #define AR5K_IMR_QTRIG 0x08000000 /* QCU scheduling trigger [5211+] */
414 414
415 /* 415 /*
416 * Secondary interrupt mask registers [5211+] (0 - 4) 416 * Secondary interrupt mask registers [5211+] (0 - 4)
417 */ 417 */
418 #define AR5K_SIMR0 0x00a4 /* Register Address [5211+] */ 418 #define AR5K_SIMR0 0x00a4 /* Register Address [5211+] */
419 #define AR5K_SIMR0_QCU_TXOK 0x000003ff /* Mask for QCU_TXOK */ 419 #define AR5K_SIMR0_QCU_TXOK 0x000003ff /* Mask for QCU_TXOK */
420 #define AR5K_SIMR0_QCU_TXOK_S 0 420 #define AR5K_SIMR0_QCU_TXOK_S 0
421 #define AR5K_SIMR0_QCU_TXDESC 0x03ff0000 /* Mask for QCU_TXDESC */ 421 #define AR5K_SIMR0_QCU_TXDESC 0x03ff0000 /* Mask for QCU_TXDESC */
422 #define AR5K_SIMR0_QCU_TXDESC_S 16 422 #define AR5K_SIMR0_QCU_TXDESC_S 16
423 423
424 #define AR5K_SIMR1 0x00a8 /* Register Address [5211+] */ 424 #define AR5K_SIMR1 0x00a8 /* Register Address [5211+] */
425 #define AR5K_SIMR1_QCU_TXERR 0x000003ff /* Mask for QCU_TXERR */ 425 #define AR5K_SIMR1_QCU_TXERR 0x000003ff /* Mask for QCU_TXERR */
426 #define AR5K_SIMR1_QCU_TXERR_S 0 426 #define AR5K_SIMR1_QCU_TXERR_S 0
427 #define AR5K_SIMR1_QCU_TXEOL 0x03ff0000 /* Mask for QCU_TXEOL */ 427 #define AR5K_SIMR1_QCU_TXEOL 0x03ff0000 /* Mask for QCU_TXEOL */
428 #define AR5K_SIMR1_QCU_TXEOL_S 16 428 #define AR5K_SIMR1_QCU_TXEOL_S 16
429 429
430 #define AR5K_SIMR2 0x00ac /* Register Address [5211+] */ 430 #define AR5K_SIMR2 0x00ac /* Register Address [5211+] */
431 #define AR5K_SIMR2_QCU_TXURN 0x000003ff /* Mask for QCU_TXURN */ 431 #define AR5K_SIMR2_QCU_TXURN 0x000003ff /* Mask for QCU_TXURN */
432 #define AR5K_SIMR2_QCU_TXURN_S 0 432 #define AR5K_SIMR2_QCU_TXURN_S 0
433 #define AR5K_SIMR2_MCABT 0x00010000 /* Master Cycle Abort */ 433 #define AR5K_SIMR2_MCABT 0x00010000 /* Master Cycle Abort */
434 #define AR5K_SIMR2_SSERR 0x00020000 /* Signaled System Error */ 434 #define AR5K_SIMR2_SSERR 0x00020000 /* Signaled System Error */
435 #define AR5K_SIMR2_DPERR 0x00040000 /* Bus parity error */ 435 #define AR5K_SIMR2_DPERR 0x00040000 /* Bus parity error */
436 #define AR5K_SIMR2_TIM 0x01000000 /* [5212+] */ 436 #define AR5K_SIMR2_TIM 0x01000000 /* [5212+] */
437 #define AR5K_SIMR2_CAB_END 0x02000000 /* [5212+] */ 437 #define AR5K_SIMR2_CAB_END 0x02000000 /* [5212+] */
438 #define AR5K_SIMR2_DTIM_SYNC 0x04000000 /* DTIM Sync lost [5212+] */ 438 #define AR5K_SIMR2_DTIM_SYNC 0x04000000 /* DTIM Sync lost [5212+] */
439 #define AR5K_SIMR2_BCN_TIMEOUT 0x08000000 /* Beacon Timeout [5212+] */ 439 #define AR5K_SIMR2_BCN_TIMEOUT 0x08000000 /* Beacon Timeout [5212+] */
440 #define AR5K_SIMR2_CAB_TIMEOUT 0x10000000 /* CAB Timeout [5212+] */ 440 #define AR5K_SIMR2_CAB_TIMEOUT 0x10000000 /* CAB Timeout [5212+] */
441 #define AR5K_SIMR2_DTIM 0x20000000 /* [5212+] */ 441 #define AR5K_SIMR2_DTIM 0x20000000 /* [5212+] */
442 #define AR5K_SIMR2_TSFOOR 0x80000000 /* TSF OOR (?) */ 442 #define AR5K_SIMR2_TSFOOR 0x80000000 /* TSF OOR (?) */
443 443
444 #define AR5K_SIMR3 0x00b0 /* Register Address [5211+] */ 444 #define AR5K_SIMR3 0x00b0 /* Register Address [5211+] */
445 #define AR5K_SIMR3_QCBRORN 0x000003ff /* Mask for QCBRORN */ 445 #define AR5K_SIMR3_QCBRORN 0x000003ff /* Mask for QCBRORN */
446 #define AR5K_SIMR3_QCBRORN_S 0 446 #define AR5K_SIMR3_QCBRORN_S 0
447 #define AR5K_SIMR3_QCBRURN 0x03ff0000 /* Mask for QCBRURN */ 447 #define AR5K_SIMR3_QCBRURN 0x03ff0000 /* Mask for QCBRURN */
448 #define AR5K_SIMR3_QCBRURN_S 16 448 #define AR5K_SIMR3_QCBRURN_S 16
449 449
450 #define AR5K_SIMR4 0x00b4 /* Register Address [5211+] */ 450 #define AR5K_SIMR4 0x00b4 /* Register Address [5211+] */
451 #define AR5K_SIMR4_QTRIG 0x000003ff /* Mask for QTRIG */ 451 #define AR5K_SIMR4_QTRIG 0x000003ff /* Mask for QTRIG */
452 #define AR5K_SIMR4_QTRIG_S 0 452 #define AR5K_SIMR4_QTRIG_S 0
453 453
454 /* 454 /*
455 * DMA Debug registers 0-7 455 * DMA Debug registers 0-7
456 * 0xe0 - 0xfc 456 * 0xe0 - 0xfc
457 */ 457 */
458 458
459 /* 459 /*
460 * Decompression mask registers [5212+] 460 * Decompression mask registers [5212+]
461 */ 461 */
462 #define AR5K_DCM_ADDR 0x0400 /*Decompression mask address (index) */ 462 #define AR5K_DCM_ADDR 0x0400 /*Decompression mask address (index) */
463 #define AR5K_DCM_DATA 0x0404 /*Decompression mask data */ 463 #define AR5K_DCM_DATA 0x0404 /*Decompression mask data */
464 464
465 /* 465 /*
466 * Wake On Wireless pattern control register [5212+] 466 * Wake On Wireless pattern control register [5212+]
467 */ 467 */
468 #define AR5K_WOW_PCFG 0x0410 /* Register Address */ 468 #define AR5K_WOW_PCFG 0x0410 /* Register Address */
469 #define AR5K_WOW_PCFG_PAT_MATCH_EN 0x00000001 /* Pattern match enable */ 469 #define AR5K_WOW_PCFG_PAT_MATCH_EN 0x00000001 /* Pattern match enable */
470 #define AR5K_WOW_PCFG_LONG_FRAME_POL 0x00000002 /* Long frame policy */ 470 #define AR5K_WOW_PCFG_LONG_FRAME_POL 0x00000002 /* Long frame policy */
471 #define AR5K_WOW_PCFG_WOBMISS 0x00000004 /* Wake on bea(con) miss (?) */ 471 #define AR5K_WOW_PCFG_WOBMISS 0x00000004 /* Wake on bea(con) miss (?) */
472 #define AR5K_WOW_PCFG_PAT_0_EN 0x00000100 /* Enable pattern 0 */ 472 #define AR5K_WOW_PCFG_PAT_0_EN 0x00000100 /* Enable pattern 0 */
473 #define AR5K_WOW_PCFG_PAT_1_EN 0x00000200 /* Enable pattern 1 */ 473 #define AR5K_WOW_PCFG_PAT_1_EN 0x00000200 /* Enable pattern 1 */
474 #define AR5K_WOW_PCFG_PAT_2_EN 0x00000400 /* Enable pattern 2 */ 474 #define AR5K_WOW_PCFG_PAT_2_EN 0x00000400 /* Enable pattern 2 */
475 #define AR5K_WOW_PCFG_PAT_3_EN 0x00000800 /* Enable pattern 3 */ 475 #define AR5K_WOW_PCFG_PAT_3_EN 0x00000800 /* Enable pattern 3 */
476 #define AR5K_WOW_PCFG_PAT_4_EN 0x00001000 /* Enable pattern 4 */ 476 #define AR5K_WOW_PCFG_PAT_4_EN 0x00001000 /* Enable pattern 4 */
477 #define AR5K_WOW_PCFG_PAT_5_EN 0x00002000 /* Enable pattern 5 */ 477 #define AR5K_WOW_PCFG_PAT_5_EN 0x00002000 /* Enable pattern 5 */
478 478
479 /* 479 /*
480 * Wake On Wireless pattern index register (?) [5212+] 480 * Wake On Wireless pattern index register (?) [5212+]
481 */ 481 */
482 #define AR5K_WOW_PAT_IDX 0x0414 482 #define AR5K_WOW_PAT_IDX 0x0414
483 483
484 /* 484 /*
485 * Wake On Wireless pattern data register [5212+] 485 * Wake On Wireless pattern data register [5212+]
486 */ 486 */
487 #define AR5K_WOW_PAT_DATA 0x0418 /* Register Address */ 487 #define AR5K_WOW_PAT_DATA 0x0418 /* Register Address */
488 #define AR5K_WOW_PAT_DATA_0_3_V 0x00000001 /* Pattern 0, 3 value */ 488 #define AR5K_WOW_PAT_DATA_0_3_V 0x00000001 /* Pattern 0, 3 value */
489 #define AR5K_WOW_PAT_DATA_1_4_V 0x00000100 /* Pattern 1, 4 value */ 489 #define AR5K_WOW_PAT_DATA_1_4_V 0x00000100 /* Pattern 1, 4 value */
490 #define AR5K_WOW_PAT_DATA_2_5_V 0x00010000 /* Pattern 2, 5 value */ 490 #define AR5K_WOW_PAT_DATA_2_5_V 0x00010000 /* Pattern 2, 5 value */
491 #define AR5K_WOW_PAT_DATA_0_3_M 0x01000000 /* Pattern 0, 3 mask */ 491 #define AR5K_WOW_PAT_DATA_0_3_M 0x01000000 /* Pattern 0, 3 mask */
492 #define AR5K_WOW_PAT_DATA_1_4_M 0x04000000 /* Pattern 1, 4 mask */ 492 #define AR5K_WOW_PAT_DATA_1_4_M 0x04000000 /* Pattern 1, 4 mask */
493 #define AR5K_WOW_PAT_DATA_2_5_M 0x10000000 /* Pattern 2, 5 mask */ 493 #define AR5K_WOW_PAT_DATA_2_5_M 0x10000000 /* Pattern 2, 5 mask */
494 494
495 /* 495 /*
496 * Decompression configuration registers [5212+] 496 * Decompression configuration registers [5212+]
497 */ 497 */
498 #define AR5K_DCCFG 0x0420 /* Register Address */ 498 #define AR5K_DCCFG 0x0420 /* Register Address */
499 #define AR5K_DCCFG_GLOBAL_EN 0x00000001 /* Enable decompression on all queues */ 499 #define AR5K_DCCFG_GLOBAL_EN 0x00000001 /* Enable decompression on all queues */
500 #define AR5K_DCCFG_BYPASS_EN 0x00000002 /* Bypass decompression */ 500 #define AR5K_DCCFG_BYPASS_EN 0x00000002 /* Bypass decompression */
501 #define AR5K_DCCFG_BCAST_EN 0x00000004 /* Enable decompression for bcast frames */ 501 #define AR5K_DCCFG_BCAST_EN 0x00000004 /* Enable decompression for bcast frames */
502 #define AR5K_DCCFG_MCAST_EN 0x00000008 /* Enable decompression for mcast frames */ 502 #define AR5K_DCCFG_MCAST_EN 0x00000008 /* Enable decompression for mcast frames */
503 503
504 /* 504 /*
505 * Compression configuration registers [5212+] 505 * Compression configuration registers [5212+]
506 */ 506 */
507 #define AR5K_CCFG 0x0600 /* Register Address */ 507 #define AR5K_CCFG 0x0600 /* Register Address */
508 #define AR5K_CCFG_WINDOW_SIZE 0x00000007 /* Compression window size */ 508 #define AR5K_CCFG_WINDOW_SIZE 0x00000007 /* Compression window size */
509 #define AR5K_CCFG_CPC_EN 0x00000008 /* Enable performance counters */ 509 #define AR5K_CCFG_CPC_EN 0x00000008 /* Enable performance counters */
510 510
511 #define AR5K_CCFG_CCU 0x0604 /* Register Address */ 511 #define AR5K_CCFG_CCU 0x0604 /* Register Address */
512 #define AR5K_CCFG_CCU_CUP_EN 0x00000001 /* CCU Catchup enable */ 512 #define AR5K_CCFG_CCU_CUP_EN 0x00000001 /* CCU Catchup enable */
513 #define AR5K_CCFG_CCU_CREDIT 0x00000002 /* CCU Credit (field) */ 513 #define AR5K_CCFG_CCU_CREDIT 0x00000002 /* CCU Credit (field) */
514 #define AR5K_CCFG_CCU_CD_THRES 0x00000080 /* CCU Cyc(lic?) debt threshold (field) */ 514 #define AR5K_CCFG_CCU_CD_THRES 0x00000080 /* CCU Cyc(lic?) debt threshold (field) */
515 #define AR5K_CCFG_CCU_CUP_LCNT 0x00010000 /* CCU Catchup lit(?) count */ 515 #define AR5K_CCFG_CCU_CUP_LCNT 0x00010000 /* CCU Catchup lit(?) count */
516 #define AR5K_CCFG_CCU_INIT 0x00100200 /* Initial value during reset */ 516 #define AR5K_CCFG_CCU_INIT 0x00100200 /* Initial value during reset */
517 517
518 /* 518 /*
519 * Compression performance counter registers [5212+] 519 * Compression performance counter registers [5212+]
520 */ 520 */
521 #define AR5K_CPC0 0x0610 /* Compression performance counter 0 */ 521 #define AR5K_CPC0 0x0610 /* Compression performance counter 0 */
522 #define AR5K_CPC1 0x0614 /* Compression performance counter 1*/ 522 #define AR5K_CPC1 0x0614 /* Compression performance counter 1*/
523 #define AR5K_CPC2 0x0618 /* Compression performance counter 2 */ 523 #define AR5K_CPC2 0x0618 /* Compression performance counter 2 */
524 #define AR5K_CPC3 0x061c /* Compression performance counter 3 */ 524 #define AR5K_CPC3 0x061c /* Compression performance counter 3 */
525 #define AR5K_CPCOVF 0x0620 /* Compression performance overflow */ 525 #define AR5K_CPCOVF 0x0620 /* Compression performance overflow */
526 526
527 527
528 /* 528 /*
529 * Queue control unit (QCU) registers [5211+] 529 * Queue control unit (QCU) registers [5211+]
530 * 530 *
531 * Card has 12 TX Queues but i see that only 0-9 are used (?) 531 * Card has 12 TX Queues but i see that only 0-9 are used (?)
532 * both in binary HAL (see ah.h) and ar5k. Each queue has it's own 532 * both in binary HAL (see ah.h) and ar5k. Each queue has it's own
533 * TXDP at addresses 0x0800 - 0x082c, a CBR (Constant Bit Rate) 533 * TXDP at addresses 0x0800 - 0x082c, a CBR (Constant Bit Rate)
534 * configuration register (0x08c0 - 0x08ec), a ready time configuration 534 * configuration register (0x08c0 - 0x08ec), a ready time configuration
535 * register (0x0900 - 0x092c), a misc configuration register (0x09c0 - 535 * register (0x0900 - 0x092c), a misc configuration register (0x09c0 -
536 * 0x09ec) and a status register (0x0a00 - 0x0a2c). We also have some 536 * 0x09ec) and a status register (0x0a00 - 0x0a2c). We also have some
537 * global registers, QCU transmit enable/disable and "one shot arm (?)" 537 * global registers, QCU transmit enable/disable and "one shot arm (?)"
538 * set/clear, which contain status for all queues (we shift by 1 for each 538 * set/clear, which contain status for all queues (we shift by 1 for each
539 * queue). To access these registers easily we define some macros here 539 * queue). To access these registers easily we define some macros here
540 * that are used inside HAL. For more infos check out *_tx_queue functs. 540 * that are used inside HAL. For more infos check out *_tx_queue functs.
541 */ 541 */
542 542
543 /* 543 /*
544 * Generic QCU Register access macros 544 * Generic QCU Register access macros
545 */ 545 */
546 #define AR5K_QUEUE_REG(_r, _q) (((_q) << 2) + _r) 546 #define AR5K_QUEUE_REG(_r, _q) (((_q) << 2) + _r)
547 #define AR5K_QCU_GLOBAL_READ(_r, _q) (AR5K_REG_READ(_r) & (1 << _q)) 547 #define AR5K_QCU_GLOBAL_READ(_r, _q) (AR5K_REG_READ(_r) & (1 << _q))
548 #define AR5K_QCU_GLOBAL_WRITE(_r, _q) AR5K_REG_WRITE(_r, (1 << _q)) 548 #define AR5K_QCU_GLOBAL_WRITE(_r, _q) AR5K_REG_WRITE(_r, (1 << _q))
549 549
550 /* 550 /*
551 * QCU Transmit descriptor pointer registers 551 * QCU Transmit descriptor pointer registers
552 */ 552 */
553 #define AR5K_QCU_TXDP_BASE 0x0800 /* Register Address - Queue0 TXDP */ 553 #define AR5K_QCU_TXDP_BASE 0x0800 /* Register Address - Queue0 TXDP */
554 #define AR5K_QUEUE_TXDP(_q) AR5K_QUEUE_REG(AR5K_QCU_TXDP_BASE, _q) 554 #define AR5K_QUEUE_TXDP(_q) AR5K_QUEUE_REG(AR5K_QCU_TXDP_BASE, _q)
555 555
556 /* 556 /*
557 * QCU Transmit enable register 557 * QCU Transmit enable register
558 */ 558 */
559 #define AR5K_QCU_TXE 0x0840 559 #define AR5K_QCU_TXE 0x0840
560 #define AR5K_ENABLE_QUEUE(_q) AR5K_QCU_GLOBAL_WRITE(AR5K_QCU_TXE, _q) 560 #define AR5K_ENABLE_QUEUE(_q) AR5K_QCU_GLOBAL_WRITE(AR5K_QCU_TXE, _q)
561 #define AR5K_QUEUE_ENABLED(_q) AR5K_QCU_GLOBAL_READ(AR5K_QCU_TXE, _q) 561 #define AR5K_QUEUE_ENABLED(_q) AR5K_QCU_GLOBAL_READ(AR5K_QCU_TXE, _q)
562 562
563 /* 563 /*
564 * QCU Transmit disable register 564 * QCU Transmit disable register
565 */ 565 */
566 #define AR5K_QCU_TXD 0x0880 566 #define AR5K_QCU_TXD 0x0880
567 #define AR5K_DISABLE_QUEUE(_q) AR5K_QCU_GLOBAL_WRITE(AR5K_QCU_TXD, _q) 567 #define AR5K_DISABLE_QUEUE(_q) AR5K_QCU_GLOBAL_WRITE(AR5K_QCU_TXD, _q)
568 #define AR5K_QUEUE_DISABLED(_q) AR5K_QCU_GLOBAL_READ(AR5K_QCU_TXD, _q) 568 #define AR5K_QUEUE_DISABLED(_q) AR5K_QCU_GLOBAL_READ(AR5K_QCU_TXD, _q)
569 569
570 /* 570 /*
571 * QCU Constant Bit Rate configuration registers 571 * QCU Constant Bit Rate configuration registers
572 */ 572 */
573 #define AR5K_QCU_CBRCFG_BASE 0x08c0 /* Register Address - Queue0 CBRCFG */ 573 #define AR5K_QCU_CBRCFG_BASE 0x08c0 /* Register Address - Queue0 CBRCFG */
574 #define AR5K_QCU_CBRCFG_INTVAL 0x00ffffff /* CBR Interval mask */ 574 #define AR5K_QCU_CBRCFG_INTVAL 0x00ffffff /* CBR Interval mask */
575 #define AR5K_QCU_CBRCFG_INTVAL_S 0 575 #define AR5K_QCU_CBRCFG_INTVAL_S 0
576 #define AR5K_QCU_CBRCFG_ORN_THRES 0xff000000 /* CBR overrun threshold mask */ 576 #define AR5K_QCU_CBRCFG_ORN_THRES 0xff000000 /* CBR overrun threshold mask */
577 #define AR5K_QCU_CBRCFG_ORN_THRES_S 24 577 #define AR5K_QCU_CBRCFG_ORN_THRES_S 24
578 #define AR5K_QUEUE_CBRCFG(_q) AR5K_QUEUE_REG(AR5K_QCU_CBRCFG_BASE, _q) 578 #define AR5K_QUEUE_CBRCFG(_q) AR5K_QUEUE_REG(AR5K_QCU_CBRCFG_BASE, _q)
579 579
580 /* 580 /*
581 * QCU Ready time configuration registers 581 * QCU Ready time configuration registers
582 */ 582 */
583 #define AR5K_QCU_RDYTIMECFG_BASE 0x0900 /* Register Address - Queue0 RDYTIMECFG */ 583 #define AR5K_QCU_RDYTIMECFG_BASE 0x0900 /* Register Address - Queue0 RDYTIMECFG */
584 #define AR5K_QCU_RDYTIMECFG_INTVAL 0x00ffffff /* Ready time interval mask */ 584 #define AR5K_QCU_RDYTIMECFG_INTVAL 0x00ffffff /* Ready time interval mask */
585 #define AR5K_QCU_RDYTIMECFG_INTVAL_S 0 585 #define AR5K_QCU_RDYTIMECFG_INTVAL_S 0
586 #define AR5K_QCU_RDYTIMECFG_ENABLE 0x01000000 /* Ready time enable mask */ 586 #define AR5K_QCU_RDYTIMECFG_ENABLE 0x01000000 /* Ready time enable mask */
587 #define AR5K_QUEUE_RDYTIMECFG(_q) AR5K_QUEUE_REG(AR5K_QCU_RDYTIMECFG_BASE, _q) 587 #define AR5K_QUEUE_RDYTIMECFG(_q) AR5K_QUEUE_REG(AR5K_QCU_RDYTIMECFG_BASE, _q)
588 588
589 /* 589 /*
590 * QCU one shot arm set registers 590 * QCU one shot arm set registers
591 */ 591 */
592 #define AR5K_QCU_ONESHOTARM_SET 0x0940 /* Register Address -QCU "one shot arm set (?)" */ 592 #define AR5K_QCU_ONESHOTARM_SET 0x0940 /* Register Address -QCU "one shot arm set (?)" */
593 #define AR5K_QCU_ONESHOTARM_SET_M 0x0000ffff 593 #define AR5K_QCU_ONESHOTARM_SET_M 0x0000ffff
594 594
595 /* 595 /*
596 * QCU one shot arm clear registers 596 * QCU one shot arm clear registers
597 */ 597 */
598 #define AR5K_QCU_ONESHOTARM_CLEAR 0x0980 /* Register Address -QCU "one shot arm clear (?)" */ 598 #define AR5K_QCU_ONESHOTARM_CLEAR 0x0980 /* Register Address -QCU "one shot arm clear (?)" */
599 #define AR5K_QCU_ONESHOTARM_CLEAR_M 0x0000ffff 599 #define AR5K_QCU_ONESHOTARM_CLEAR_M 0x0000ffff
600 600
601 /* 601 /*
602 * QCU misc registers 602 * QCU misc registers
603 */ 603 */
604 #define AR5K_QCU_MISC_BASE 0x09c0 /* Register Address -Queue0 MISC */ 604 #define AR5K_QCU_MISC_BASE 0x09c0 /* Register Address -Queue0 MISC */
605 #define AR5K_QCU_MISC_FRSHED_M 0x0000000f /* Frame sheduling mask */ 605 #define AR5K_QCU_MISC_FRSHED_M 0x0000000f /* Frame sheduling mask */
606 #define AR5K_QCU_MISC_FRSHED_ASAP 0 /* ASAP */ 606 #define AR5K_QCU_MISC_FRSHED_ASAP 0 /* ASAP */
607 #define AR5K_QCU_MISC_FRSHED_CBR 1 /* Constant Bit Rate */ 607 #define AR5K_QCU_MISC_FRSHED_CBR 1 /* Constant Bit Rate */
608 #define AR5K_QCU_MISC_FRSHED_DBA_GT 2 /* DMA Beacon alert gated */ 608 #define AR5K_QCU_MISC_FRSHED_DBA_GT 2 /* DMA Beacon alert gated */
609 #define AR5K_QCU_MISC_FRSHED_TIM_GT 3 /* TIMT gated */ 609 #define AR5K_QCU_MISC_FRSHED_TIM_GT 3 /* TIMT gated */
610 #define AR5K_QCU_MISC_FRSHED_BCN_SENT_GT 4 /* Beacon sent gated */ 610 #define AR5K_QCU_MISC_FRSHED_BCN_SENT_GT 4 /* Beacon sent gated */
611 #define AR5K_QCU_MISC_ONESHOT_ENABLE 0x00000010 /* Oneshot enable */ 611 #define AR5K_QCU_MISC_ONESHOT_ENABLE 0x00000010 /* Oneshot enable */
612 #define AR5K_QCU_MISC_CBREXP_DIS 0x00000020 /* Disable CBR expired counter (normal queue) */ 612 #define AR5K_QCU_MISC_CBREXP_DIS 0x00000020 /* Disable CBR expired counter (normal queue) */
613 #define AR5K_QCU_MISC_CBREXP_BCN_DIS 0x00000040 /* Disable CBR expired counter (beacon queue) */ 613 #define AR5K_QCU_MISC_CBREXP_BCN_DIS 0x00000040 /* Disable CBR expired counter (beacon queue) */
614 #define AR5K_QCU_MISC_BCN_ENABLE 0x00000080 /* Enable Beacon use */ 614 #define AR5K_QCU_MISC_BCN_ENABLE 0x00000080 /* Enable Beacon use */
615 #define AR5K_QCU_MISC_CBR_THRES_ENABLE 0x00000100 /* CBR expired threshold enabled */ 615 #define AR5K_QCU_MISC_CBR_THRES_ENABLE 0x00000100 /* CBR expired threshold enabled */
616 #define AR5K_QCU_MISC_RDY_VEOL_POLICY 0x00000200 /* TXE reset when RDYTIME expired or VEOL */ 616 #define AR5K_QCU_MISC_RDY_VEOL_POLICY 0x00000200 /* TXE reset when RDYTIME expired or VEOL */
617 #define AR5K_QCU_MISC_CBR_RESET_CNT 0x00000400 /* CBR threshold (counter) reset */ 617 #define AR5K_QCU_MISC_CBR_RESET_CNT 0x00000400 /* CBR threshold (counter) reset */
618 #define AR5K_QCU_MISC_DCU_EARLY 0x00000800 /* DCU early termination */ 618 #define AR5K_QCU_MISC_DCU_EARLY 0x00000800 /* DCU early termination */
619 #define AR5K_QCU_MISC_DCU_CMP_EN 0x00001000 /* Enable frame compression */ 619 #define AR5K_QCU_MISC_DCU_CMP_EN 0x00001000 /* Enable frame compression */
620 #define AR5K_QUEUE_MISC(_q) AR5K_QUEUE_REG(AR5K_QCU_MISC_BASE, _q) 620 #define AR5K_QUEUE_MISC(_q) AR5K_QUEUE_REG(AR5K_QCU_MISC_BASE, _q)
621 621
622 622
623 /* 623 /*
624 * QCU status registers 624 * QCU status registers
625 */ 625 */
626 #define AR5K_QCU_STS_BASE 0x0a00 /* Register Address - Queue0 STS */ 626 #define AR5K_QCU_STS_BASE 0x0a00 /* Register Address - Queue0 STS */
627 #define AR5K_QCU_STS_FRMPENDCNT 0x00000003 /* Frames pending counter */ 627 #define AR5K_QCU_STS_FRMPENDCNT 0x00000003 /* Frames pending counter */
628 #define AR5K_QCU_STS_CBREXPCNT 0x0000ff00 /* CBR expired counter */ 628 #define AR5K_QCU_STS_CBREXPCNT 0x0000ff00 /* CBR expired counter */
629 #define AR5K_QUEUE_STATUS(_q) AR5K_QUEUE_REG(AR5K_QCU_STS_BASE, _q) 629 #define AR5K_QUEUE_STATUS(_q) AR5K_QUEUE_REG(AR5K_QCU_STS_BASE, _q)
630 630
631 /* 631 /*
632 * QCU ready time shutdown register 632 * QCU ready time shutdown register
633 */ 633 */
634 #define AR5K_QCU_RDYTIMESHDN 0x0a40 634 #define AR5K_QCU_RDYTIMESHDN 0x0a40
635 #define AR5K_QCU_RDYTIMESHDN_M 0x000003ff 635 #define AR5K_QCU_RDYTIMESHDN_M 0x000003ff
636 636
637 /* 637 /*
638 * QCU compression buffer base registers [5212+] 638 * QCU compression buffer base registers [5212+]
639 */ 639 */
640 #define AR5K_QCU_CBB_SELECT 0x0b00 640 #define AR5K_QCU_CBB_SELECT 0x0b00
641 #define AR5K_QCU_CBB_ADDR 0x0b04 641 #define AR5K_QCU_CBB_ADDR 0x0b04
642 #define AR5K_QCU_CBB_ADDR_S 9 642 #define AR5K_QCU_CBB_ADDR_S 9
643 643
644 /* 644 /*
645 * QCU compression buffer configuration register [5212+] 645 * QCU compression buffer configuration register [5212+]
646 * (buffer size) 646 * (buffer size)
647 */ 647 */
648 #define AR5K_QCU_CBCFG 0x0b08 648 #define AR5K_QCU_CBCFG 0x0b08
649 649
650 650
651 651
652 /* 652 /*
653 * Distributed Coordination Function (DCF) control unit (DCU) 653 * Distributed Coordination Function (DCF) control unit (DCU)
654 * registers [5211+] 654 * registers [5211+]
655 * 655 *
656 * These registers control the various characteristics of each queue 656 * These registers control the various characteristics of each queue
657 * for 802.11e (WME) combatibility so they go together with 657 * for 802.11e (WME) combatibility so they go together with
658 * QCU registers in pairs. For each queue we have a QCU mask register, 658 * QCU registers in pairs. For each queue we have a QCU mask register,
659 * (0x1000 - 0x102c), a local-IFS settings register (0x1040 - 0x106c), 659 * (0x1000 - 0x102c), a local-IFS settings register (0x1040 - 0x106c),
660 * a retry limit register (0x1080 - 0x10ac), a channel time register 660 * a retry limit register (0x1080 - 0x10ac), a channel time register
661 * (0x10c0 - 0x10ec), a misc-settings register (0x1100 - 0x112c) and 661 * (0x10c0 - 0x10ec), a misc-settings register (0x1100 - 0x112c) and
662 * a sequence number register (0x1140 - 0x116c). It seems that "global" 662 * a sequence number register (0x1140 - 0x116c). It seems that "global"
663 * registers here afect all queues (see use of DCU_GBL_IFS_SLOT in ar5k). 663 * registers here afect all queues (see use of DCU_GBL_IFS_SLOT in ar5k).
664 * We use the same macros here for easier register access. 664 * We use the same macros here for easier register access.
665 * 665 *
666 */ 666 */
667 667
668 /* 668 /*
669 * DCU QCU mask registers 669 * DCU QCU mask registers
670 */ 670 */
671 #define AR5K_DCU_QCUMASK_BASE 0x1000 /* Register Address -Queue0 DCU_QCUMASK */ 671 #define AR5K_DCU_QCUMASK_BASE 0x1000 /* Register Address -Queue0 DCU_QCUMASK */
672 #define AR5K_DCU_QCUMASK_M 0x000003ff 672 #define AR5K_DCU_QCUMASK_M 0x000003ff
673 #define AR5K_QUEUE_QCUMASK(_q) AR5K_QUEUE_REG(AR5K_DCU_QCUMASK_BASE, _q) 673 #define AR5K_QUEUE_QCUMASK(_q) AR5K_QUEUE_REG(AR5K_DCU_QCUMASK_BASE, _q)
674 674
675 /* 675 /*
676 * DCU local Inter Frame Space settings register 676 * DCU local Inter Frame Space settings register
677 */ 677 */
678 #define AR5K_DCU_LCL_IFS_BASE 0x1040 /* Register Address -Queue0 DCU_LCL_IFS */ 678 #define AR5K_DCU_LCL_IFS_BASE 0x1040 /* Register Address -Queue0 DCU_LCL_IFS */
679 #define AR5K_DCU_LCL_IFS_CW_MIN 0x000003ff /* Minimum Contention Window */ 679 #define AR5K_DCU_LCL_IFS_CW_MIN 0x000003ff /* Minimum Contention Window */
680 #define AR5K_DCU_LCL_IFS_CW_MIN_S 0 680 #define AR5K_DCU_LCL_IFS_CW_MIN_S 0
681 #define AR5K_DCU_LCL_IFS_CW_MAX 0x000ffc00 /* Maximum Contention Window */ 681 #define AR5K_DCU_LCL_IFS_CW_MAX 0x000ffc00 /* Maximum Contention Window */
682 #define AR5K_DCU_LCL_IFS_CW_MAX_S 10 682 #define AR5K_DCU_LCL_IFS_CW_MAX_S 10
683 #define AR5K_DCU_LCL_IFS_AIFS 0x0ff00000 /* Arbitrated Interframe Space */ 683 #define AR5K_DCU_LCL_IFS_AIFS 0x0ff00000 /* Arbitrated Interframe Space */
684 #define AR5K_DCU_LCL_IFS_AIFS_S 20 684 #define AR5K_DCU_LCL_IFS_AIFS_S 20
685 #define AR5K_DCU_LCL_IFS_AIFS_MAX 0xfc /* Anything above that can cause DCU to hang */ 685 #define AR5K_DCU_LCL_IFS_AIFS_MAX 0xfc /* Anything above that can cause DCU to hang */
686 #define AR5K_QUEUE_DFS_LOCAL_IFS(_q) AR5K_QUEUE_REG(AR5K_DCU_LCL_IFS_BASE, _q) 686 #define AR5K_QUEUE_DFS_LOCAL_IFS(_q) AR5K_QUEUE_REG(AR5K_DCU_LCL_IFS_BASE, _q)
687 687
688 /* 688 /*
689 * DCU retry limit registers 689 * DCU retry limit registers
690 */ 690 */
691 #define AR5K_DCU_RETRY_LMT_BASE 0x1080 /* Register Address -Queue0 DCU_RETRY_LMT */ 691 #define AR5K_DCU_RETRY_LMT_BASE 0x1080 /* Register Address -Queue0 DCU_RETRY_LMT */
692 #define AR5K_DCU_RETRY_LMT_SH_RETRY 0x0000000f /* Short retry limit mask */ 692 #define AR5K_DCU_RETRY_LMT_SH_RETRY 0x0000000f /* Short retry limit mask */
693 #define AR5K_DCU_RETRY_LMT_SH_RETRY_S 0 693 #define AR5K_DCU_RETRY_LMT_SH_RETRY_S 0
694 #define AR5K_DCU_RETRY_LMT_LG_RETRY 0x000000f0 /* Long retry limit mask */ 694 #define AR5K_DCU_RETRY_LMT_LG_RETRY 0x000000f0 /* Long retry limit mask */
695 #define AR5K_DCU_RETRY_LMT_LG_RETRY_S 4 695 #define AR5K_DCU_RETRY_LMT_LG_RETRY_S 4
696 #define AR5K_DCU_RETRY_LMT_SSH_RETRY 0x00003f00 /* Station short retry limit mask (?) */ 696 #define AR5K_DCU_RETRY_LMT_SSH_RETRY 0x00003f00 /* Station short retry limit mask (?) */
697 #define AR5K_DCU_RETRY_LMT_SSH_RETRY_S 8 697 #define AR5K_DCU_RETRY_LMT_SSH_RETRY_S 8
698 #define AR5K_DCU_RETRY_LMT_SLG_RETRY 0x000fc000 /* Station long retry limit mask (?) */ 698 #define AR5K_DCU_RETRY_LMT_SLG_RETRY 0x000fc000 /* Station long retry limit mask (?) */
699 #define AR5K_DCU_RETRY_LMT_SLG_RETRY_S 14 699 #define AR5K_DCU_RETRY_LMT_SLG_RETRY_S 14
700 #define AR5K_QUEUE_DFS_RETRY_LIMIT(_q) AR5K_QUEUE_REG(AR5K_DCU_RETRY_LMT_BASE, _q) 700 #define AR5K_QUEUE_DFS_RETRY_LIMIT(_q) AR5K_QUEUE_REG(AR5K_DCU_RETRY_LMT_BASE, _q)
701 701
702 /* 702 /*
703 * DCU channel time registers 703 * DCU channel time registers
704 */ 704 */
705 #define AR5K_DCU_CHAN_TIME_BASE 0x10c0 /* Register Address -Queue0 DCU_CHAN_TIME */ 705 #define AR5K_DCU_CHAN_TIME_BASE 0x10c0 /* Register Address -Queue0 DCU_CHAN_TIME */
706 #define AR5K_DCU_CHAN_TIME_DUR 0x000fffff /* Channel time duration */ 706 #define AR5K_DCU_CHAN_TIME_DUR 0x000fffff /* Channel time duration */
707 #define AR5K_DCU_CHAN_TIME_DUR_S 0 707 #define AR5K_DCU_CHAN_TIME_DUR_S 0
708 #define AR5K_DCU_CHAN_TIME_ENABLE 0x00100000 /* Enable channel time */ 708 #define AR5K_DCU_CHAN_TIME_ENABLE 0x00100000 /* Enable channel time */
709 #define AR5K_QUEUE_DFS_CHANNEL_TIME(_q) AR5K_QUEUE_REG(AR5K_DCU_CHAN_TIME_BASE, _q) 709 #define AR5K_QUEUE_DFS_CHANNEL_TIME(_q) AR5K_QUEUE_REG(AR5K_DCU_CHAN_TIME_BASE, _q)
710 710
711 /* 711 /*
712 * DCU misc registers [5211+] 712 * DCU misc registers [5211+]
713 * 713 *
714 * Note: Arbiter lockout control controls the 714 * Note: Arbiter lockout control controls the
715 * behaviour on low priority queues when we have multiple queues 715 * behaviour on low priority queues when we have multiple queues
716 * with pending frames. Intra-frame lockout means we wait until 716 * with pending frames. Intra-frame lockout means we wait until
717 * the queue's current frame transmits (with post frame backoff and bursting) 717 * the queue's current frame transmits (with post frame backoff and bursting)
718 * before we transmit anything else and global lockout means we 718 * before we transmit anything else and global lockout means we
719 * wait for the whole queue to finish before higher priority queues 719 * wait for the whole queue to finish before higher priority queues
720 * can transmit (this is used on beacon and CAB queues). 720 * can transmit (this is used on beacon and CAB queues).
721 * No lockout means there is no special handling. 721 * No lockout means there is no special handling.
722 */ 722 */
723 #define AR5K_DCU_MISC_BASE 0x1100 /* Register Address -Queue0 DCU_MISC */ 723 #define AR5K_DCU_MISC_BASE 0x1100 /* Register Address -Queue0 DCU_MISC */
724 #define AR5K_DCU_MISC_BACKOFF 0x0000003f /* Mask for backoff threshold */ 724 #define AR5K_DCU_MISC_BACKOFF 0x0000003f /* Mask for backoff threshold */
725 #define AR5K_DCU_MISC_ETS_RTS_POL 0x00000040 /* End of transmission series 725 #define AR5K_DCU_MISC_ETS_RTS_POL 0x00000040 /* End of transmission series
726 station RTS/data failure count 726 station RTS/data failure count
727 reset policy (?) */ 727 reset policy (?) */
728 #define AR5K_DCU_MISC_ETS_CW_POL 0x00000080 /* End of transmission series 728 #define AR5K_DCU_MISC_ETS_CW_POL 0x00000080 /* End of transmission series
729 CW reset policy */ 729 CW reset policy */
730 #define AR5K_DCU_MISC_FRAG_WAIT 0x00000100 /* Wait for next fragment */ 730 #define AR5K_DCU_MISC_FRAG_WAIT 0x00000100 /* Wait for next fragment */
731 #define AR5K_DCU_MISC_BACKOFF_FRAG 0x00000200 /* Enable backoff while bursting */ 731 #define AR5K_DCU_MISC_BACKOFF_FRAG 0x00000200 /* Enable backoff while bursting */
732 #define AR5K_DCU_MISC_HCFPOLL_ENABLE 0x00000800 /* CF - Poll enable */ 732 #define AR5K_DCU_MISC_HCFPOLL_ENABLE 0x00000800 /* CF - Poll enable */
733 #define AR5K_DCU_MISC_BACKOFF_PERSIST 0x00001000 /* Persistent backoff */ 733 #define AR5K_DCU_MISC_BACKOFF_PERSIST 0x00001000 /* Persistent backoff */
734 #define AR5K_DCU_MISC_FRMPRFTCH_ENABLE 0x00002000 /* Enable frame pre-fetch */ 734 #define AR5K_DCU_MISC_FRMPRFTCH_ENABLE 0x00002000 /* Enable frame pre-fetch */
735 #define AR5K_DCU_MISC_VIRTCOL 0x0000c000 /* Mask for Virtual Collision (?) */ 735 #define AR5K_DCU_MISC_VIRTCOL 0x0000c000 /* Mask for Virtual Collision (?) */
736 #define AR5K_DCU_MISC_VIRTCOL_NORMAL 0 736 #define AR5K_DCU_MISC_VIRTCOL_NORMAL 0
737 #define AR5K_DCU_MISC_VIRTCOL_IGNORE 1 737 #define AR5K_DCU_MISC_VIRTCOL_IGNORE 1
738 #define AR5K_DCU_MISC_BCN_ENABLE 0x00010000 /* Enable Beacon use */ 738 #define AR5K_DCU_MISC_BCN_ENABLE 0x00010000 /* Enable Beacon use */
739 #define AR5K_DCU_MISC_ARBLOCK_CTL 0x00060000 /* Arbiter lockout control mask */ 739 #define AR5K_DCU_MISC_ARBLOCK_CTL 0x00060000 /* Arbiter lockout control mask */
740 #define AR5K_DCU_MISC_ARBLOCK_CTL_S 17 740 #define AR5K_DCU_MISC_ARBLOCK_CTL_S 17
741 #define AR5K_DCU_MISC_ARBLOCK_CTL_NONE 0 /* No arbiter lockout */ 741 #define AR5K_DCU_MISC_ARBLOCK_CTL_NONE 0 /* No arbiter lockout */
742 #define AR5K_DCU_MISC_ARBLOCK_CTL_INTFRM 1 /* Intra-frame lockout */ 742 #define AR5K_DCU_MISC_ARBLOCK_CTL_INTFRM 1 /* Intra-frame lockout */
743 #define AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL 2 /* Global lockout */ 743 #define AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL 2 /* Global lockout */
744 #define AR5K_DCU_MISC_ARBLOCK_IGNORE 0x00080000 /* Ignore Arbiter lockout */ 744 #define AR5K_DCU_MISC_ARBLOCK_IGNORE 0x00080000 /* Ignore Arbiter lockout */
745 #define AR5K_DCU_MISC_SEQ_NUM_INCR_DIS 0x00100000 /* Disable sequence number increment */ 745 #define AR5K_DCU_MISC_SEQ_NUM_INCR_DIS 0x00100000 /* Disable sequence number increment */
746 #define AR5K_DCU_MISC_POST_FR_BKOFF_DIS 0x00200000 /* Disable post-frame backoff */ 746 #define AR5K_DCU_MISC_POST_FR_BKOFF_DIS 0x00200000 /* Disable post-frame backoff */
747 #define AR5K_DCU_MISC_VIRT_COLL_POLICY 0x00400000 /* Virtual Collision cw policy */ 747 #define AR5K_DCU_MISC_VIRT_COLL_POLICY 0x00400000 /* Virtual Collision cw policy */
748 #define AR5K_DCU_MISC_BLOWN_IFS_POLICY 0x00800000 /* Blown IFS policy (?) */ 748 #define AR5K_DCU_MISC_BLOWN_IFS_POLICY 0x00800000 /* Blown IFS policy (?) */
749 #define AR5K_DCU_MISC_SEQNUM_CTL 0x01000000 /* Sequence number control (?) */ 749 #define AR5K_DCU_MISC_SEQNUM_CTL 0x01000000 /* Sequence number control (?) */
750 #define AR5K_QUEUE_DFS_MISC(_q) AR5K_QUEUE_REG(AR5K_DCU_MISC_BASE, _q) 750 #define AR5K_QUEUE_DFS_MISC(_q) AR5K_QUEUE_REG(AR5K_DCU_MISC_BASE, _q)
751 751
752 /* 752 /*
753 * DCU frame sequence number registers 753 * DCU frame sequence number registers
754 */ 754 */
755 #define AR5K_DCU_SEQNUM_BASE 0x1140 755 #define AR5K_DCU_SEQNUM_BASE 0x1140
756 #define AR5K_DCU_SEQNUM_M 0x00000fff 756 #define AR5K_DCU_SEQNUM_M 0x00000fff
757 #define AR5K_QUEUE_DCU_SEQNUM(_q) AR5K_QUEUE_REG(AR5K_DCU_SEQNUM_BASE, _q) 757 #define AR5K_QUEUE_DCU_SEQNUM(_q) AR5K_QUEUE_REG(AR5K_DCU_SEQNUM_BASE, _q)
758 758
759 /* 759 /*
760 * DCU global IFS SIFS register 760 * DCU global IFS SIFS register
761 */ 761 */
762 #define AR5K_DCU_GBL_IFS_SIFS 0x1030 762 #define AR5K_DCU_GBL_IFS_SIFS 0x1030
763 #define AR5K_DCU_GBL_IFS_SIFS_M 0x0000ffff 763 #define AR5K_DCU_GBL_IFS_SIFS_M 0x0000ffff
764 764
765 /* 765 /*
766 * DCU global IFS slot interval register 766 * DCU global IFS slot interval register
767 */ 767 */
768 #define AR5K_DCU_GBL_IFS_SLOT 0x1070 768 #define AR5K_DCU_GBL_IFS_SLOT 0x1070
769 #define AR5K_DCU_GBL_IFS_SLOT_M 0x0000ffff 769 #define AR5K_DCU_GBL_IFS_SLOT_M 0x0000ffff
770 770
771 /* 771 /*
772 * DCU global IFS EIFS register 772 * DCU global IFS EIFS register
773 */ 773 */
774 #define AR5K_DCU_GBL_IFS_EIFS 0x10b0 774 #define AR5K_DCU_GBL_IFS_EIFS 0x10b0
775 #define AR5K_DCU_GBL_IFS_EIFS_M 0x0000ffff 775 #define AR5K_DCU_GBL_IFS_EIFS_M 0x0000ffff
776 776
777 /* 777 /*
778 * DCU global IFS misc register 778 * DCU global IFS misc register
779 * 779 *
780 * LFSR stands for Linear Feedback Shift Register 780 * LFSR stands for Linear Feedback Shift Register
781 * and it's used for generating pseudo-random 781 * and it's used for generating pseudo-random
782 * number sequences. 782 * number sequences.
783 * 783 *
784 * (If i understand corectly, random numbers are 784 * (If i understand corectly, random numbers are
785 * used for idle sensing -multiplied with cwmin/max etc-) 785 * used for idle sensing -multiplied with cwmin/max etc-)
786 */ 786 */
787 #define AR5K_DCU_GBL_IFS_MISC 0x10f0 /* Register Address */ 787 #define AR5K_DCU_GBL_IFS_MISC 0x10f0 /* Register Address */
788 #define AR5K_DCU_GBL_IFS_MISC_LFSR_SLICE 0x00000007 /* LFSR Slice Select */ 788 #define AR5K_DCU_GBL_IFS_MISC_LFSR_SLICE 0x00000007 /* LFSR Slice Select */
789 #define AR5K_DCU_GBL_IFS_MISC_TURBO_MODE 0x00000008 /* Turbo mode */ 789 #define AR5K_DCU_GBL_IFS_MISC_TURBO_MODE 0x00000008 /* Turbo mode */
790 #define AR5K_DCU_GBL_IFS_MISC_SIFS_DUR_USEC 0x000003f0 /* SIFS Duration mask */ 790 #define AR5K_DCU_GBL_IFS_MISC_SIFS_DUR_USEC 0x000003f0 /* SIFS Duration mask */
791 #define AR5K_DCU_GBL_IFS_MISC_USEC_DUR 0x000ffc00 /* USEC Duration mask */ 791 #define AR5K_DCU_GBL_IFS_MISC_USEC_DUR 0x000ffc00 /* USEC Duration mask */
792 #define AR5K_DCU_GBL_IFS_MISC_USEC_DUR_S 10 792 #define AR5K_DCU_GBL_IFS_MISC_USEC_DUR_S 10
793 #define AR5K_DCU_GBL_IFS_MISC_DCU_ARB_DELAY 0x00300000 /* DCU Arbiter delay mask */ 793 #define AR5K_DCU_GBL_IFS_MISC_DCU_ARB_DELAY 0x00300000 /* DCU Arbiter delay mask */
794 #define AR5K_DCU_GBL_IFS_MISC_SIFS_CNT_RST 0x00400000 /* SIFS cnt reset policy (?) */ 794 #define AR5K_DCU_GBL_IFS_MISC_SIFS_CNT_RST 0x00400000 /* SIFS cnt reset policy (?) */
795 #define AR5K_DCU_GBL_IFS_MISC_AIFS_CNT_RST 0x00800000 /* AIFS cnt reset policy (?) */ 795 #define AR5K_DCU_GBL_IFS_MISC_AIFS_CNT_RST 0x00800000 /* AIFS cnt reset policy (?) */
796 #define AR5K_DCU_GBL_IFS_MISC_RND_LFSR_SL_DIS 0x01000000 /* Disable random LFSR slice */ 796 #define AR5K_DCU_GBL_IFS_MISC_RND_LFSR_SL_DIS 0x01000000 /* Disable random LFSR slice */
797 797
798 /* 798 /*
799 * DCU frame prefetch control register 799 * DCU frame prefetch control register
800 */ 800 */
801 #define AR5K_DCU_FP 0x1230 /* Register Address */ 801 #define AR5K_DCU_FP 0x1230 /* Register Address */
802 #define AR5K_DCU_FP_NOBURST_DCU_EN 0x00000001 /* Enable non-burst prefetch on DCU (?) */ 802 #define AR5K_DCU_FP_NOBURST_DCU_EN 0x00000001 /* Enable non-burst prefetch on DCU (?) */
803 #define AR5K_DCU_FP_NOBURST_EN 0x00000010 /* Enable non-burst prefetch (?) */ 803 #define AR5K_DCU_FP_NOBURST_EN 0x00000010 /* Enable non-burst prefetch (?) */
804 #define AR5K_DCU_FP_BURST_DCU_EN 0x00000020 /* Enable burst prefetch on DCU (?) */ 804 #define AR5K_DCU_FP_BURST_DCU_EN 0x00000020 /* Enable burst prefetch on DCU (?) */
805 805
806 /* 806 /*
807 * DCU transmit pause control/status register 807 * DCU transmit pause control/status register
808 */ 808 */
809 #define AR5K_DCU_TXP 0x1270 /* Register Address */ 809 #define AR5K_DCU_TXP 0x1270 /* Register Address */
810 #define AR5K_DCU_TXP_M 0x000003ff /* Tx pause mask */ 810 #define AR5K_DCU_TXP_M 0x000003ff /* Tx pause mask */
811 #define AR5K_DCU_TXP_STATUS 0x00010000 /* Tx pause status */ 811 #define AR5K_DCU_TXP_STATUS 0x00010000 /* Tx pause status */
812 812
813 /* 813 /*
814 * DCU transmit filter table 0 (32 entries) 814 * DCU transmit filter table 0 (32 entries)
815 * each entry contains a 32bit slice of the 815 * each entry contains a 32bit slice of the
816 * 128bit tx filter for each DCU (4 slices per DCU) 816 * 128bit tx filter for each DCU (4 slices per DCU)
817 */ 817 */
818 #define AR5K_DCU_TX_FILTER_0_BASE 0x1038 818 #define AR5K_DCU_TX_FILTER_0_BASE 0x1038
819 #define AR5K_DCU_TX_FILTER_0(_n) (AR5K_DCU_TX_FILTER_0_BASE + (_n * 64)) 819 #define AR5K_DCU_TX_FILTER_0(_n) (AR5K_DCU_TX_FILTER_0_BASE + (_n * 64))
820 820
821 /* 821 /*
822 * DCU transmit filter table 1 (16 entries) 822 * DCU transmit filter table 1 (16 entries)
823 */ 823 */
824 #define AR5K_DCU_TX_FILTER_1_BASE 0x103c 824 #define AR5K_DCU_TX_FILTER_1_BASE 0x103c
825 #define AR5K_DCU_TX_FILTER_1(_n) (AR5K_DCU_TX_FILTER_1_BASE + (_n * 64)) 825 #define AR5K_DCU_TX_FILTER_1(_n) (AR5K_DCU_TX_FILTER_1_BASE + (_n * 64))
826 826
827 /* 827 /*
828 * DCU clear transmit filter register 828 * DCU clear transmit filter register
829 */ 829 */
830 #define AR5K_DCU_TX_FILTER_CLR 0x143c 830 #define AR5K_DCU_TX_FILTER_CLR 0x143c
831 831
832 /* 832 /*
833 * DCU set transmit filter register 833 * DCU set transmit filter register
834 */ 834 */
835 #define AR5K_DCU_TX_FILTER_SET 0x147c 835 #define AR5K_DCU_TX_FILTER_SET 0x147c
836 836
837 /* 837 /*
838 * Reset control register 838 * Reset control register
839 */ 839 */
840 #define AR5K_RESET_CTL 0x4000 /* Register Address */ 840 #define AR5K_RESET_CTL 0x4000 /* Register Address */
841 #define AR5K_RESET_CTL_PCU 0x00000001 /* Protocol Control Unit reset */ 841 #define AR5K_RESET_CTL_PCU 0x00000001 /* Protocol Control Unit reset */
842 #define AR5K_RESET_CTL_DMA 0x00000002 /* DMA (Rx/Tx) reset [5210] */ 842 #define AR5K_RESET_CTL_DMA 0x00000002 /* DMA (Rx/Tx) reset [5210] */
843 #define AR5K_RESET_CTL_BASEBAND 0x00000002 /* Baseband reset [5211+] */ 843 #define AR5K_RESET_CTL_BASEBAND 0x00000002 /* Baseband reset [5211+] */
844 #define AR5K_RESET_CTL_MAC 0x00000004 /* MAC reset (PCU+Baseband ?) [5210] */ 844 #define AR5K_RESET_CTL_MAC 0x00000004 /* MAC reset (PCU+Baseband ?) [5210] */
845 #define AR5K_RESET_CTL_PHY 0x00000008 /* PHY reset [5210] */ 845 #define AR5K_RESET_CTL_PHY 0x00000008 /* PHY reset [5210] */
846 #define AR5K_RESET_CTL_PCI 0x00000010 /* PCI Core reset (interrupts etc) */ 846 #define AR5K_RESET_CTL_PCI 0x00000010 /* PCI Core reset (interrupts etc) */
847 847
848 /* 848 /*
849 * Sleep control register 849 * Sleep control register
850 */ 850 */
851 #define AR5K_SLEEP_CTL 0x4004 /* Register Address */ 851 #define AR5K_SLEEP_CTL 0x4004 /* Register Address */
852 #define AR5K_SLEEP_CTL_SLDUR 0x0000ffff /* Sleep duration mask */ 852 #define AR5K_SLEEP_CTL_SLDUR 0x0000ffff /* Sleep duration mask */
853 #define AR5K_SLEEP_CTL_SLDUR_S 0 853 #define AR5K_SLEEP_CTL_SLDUR_S 0
854 #define AR5K_SLEEP_CTL_SLE 0x00030000 /* Sleep enable mask */ 854 #define AR5K_SLEEP_CTL_SLE 0x00030000 /* Sleep enable mask */
855 #define AR5K_SLEEP_CTL_SLE_S 16 855 #define AR5K_SLEEP_CTL_SLE_S 16
856 #define AR5K_SLEEP_CTL_SLE_WAKE 0x00000000 /* Force chip awake */ 856 #define AR5K_SLEEP_CTL_SLE_WAKE 0x00000000 /* Force chip awake */
857 #define AR5K_SLEEP_CTL_SLE_SLP 0x00010000 /* Force chip sleep */ 857 #define AR5K_SLEEP_CTL_SLE_SLP 0x00010000 /* Force chip sleep */
858 #define AR5K_SLEEP_CTL_SLE_ALLOW 0x00020000 /* Normal sleep policy */ 858 #define AR5K_SLEEP_CTL_SLE_ALLOW 0x00020000 /* Normal sleep policy */
859 #define AR5K_SLEEP_CTL_SLE_UNITS 0x00000008 /* [5211+] */ 859 #define AR5K_SLEEP_CTL_SLE_UNITS 0x00000008 /* [5211+] */
860 #define AR5K_SLEEP_CTL_DUR_TIM_POL 0x00040000 /* Sleep duration timing policy */ 860 #define AR5K_SLEEP_CTL_DUR_TIM_POL 0x00040000 /* Sleep duration timing policy */
861 #define AR5K_SLEEP_CTL_DUR_WRITE_POL 0x00080000 /* Sleep duration write policy */ 861 #define AR5K_SLEEP_CTL_DUR_WRITE_POL 0x00080000 /* Sleep duration write policy */
862 #define AR5K_SLEEP_CTL_SLE_POL 0x00100000 /* Sleep policy mode */ 862 #define AR5K_SLEEP_CTL_SLE_POL 0x00100000 /* Sleep policy mode */
863 863
864 /* 864 /*
865 * Interrupt pending register 865 * Interrupt pending register
866 */ 866 */
867 #define AR5K_INTPEND 0x4008 867 #define AR5K_INTPEND 0x4008
868 #define AR5K_INTPEND_M 0x00000001 868 #define AR5K_INTPEND_M 0x00000001
869 869
870 /* 870 /*
871 * Sleep force register 871 * Sleep force register
872 */ 872 */
873 #define AR5K_SFR 0x400c 873 #define AR5K_SFR 0x400c
874 #define AR5K_SFR_EN 0x00000001 874 #define AR5K_SFR_EN 0x00000001
875 875
876 /* 876 /*
877 * PCI configuration register 877 * PCI configuration register
878 * TODO: Fix LED stuff 878 * TODO: Fix LED stuff
879 */ 879 */
880 #define AR5K_PCICFG 0x4010 /* Register Address */ 880 #define AR5K_PCICFG 0x4010 /* Register Address */
881 #define AR5K_PCICFG_EEAE 0x00000001 /* Eeprom access enable [5210] */ 881 #define AR5K_PCICFG_EEAE 0x00000001 /* Eeprom access enable [5210] */
882 #define AR5K_PCICFG_SLEEP_CLOCK_EN 0x00000002 /* Enable sleep clock */ 882 #define AR5K_PCICFG_SLEEP_CLOCK_EN 0x00000002 /* Enable sleep clock */
883 #define AR5K_PCICFG_CLKRUNEN 0x00000004 /* CLKRUN enable [5211+] */ 883 #define AR5K_PCICFG_CLKRUNEN 0x00000004 /* CLKRUN enable [5211+] */
884 #define AR5K_PCICFG_EESIZE 0x00000018 /* Mask for EEPROM size [5211+] */ 884 #define AR5K_PCICFG_EESIZE 0x00000018 /* Mask for EEPROM size [5211+] */
885 #define AR5K_PCICFG_EESIZE_S 3 885 #define AR5K_PCICFG_EESIZE_S 3
886 #define AR5K_PCICFG_EESIZE_4K 0 /* 4K */ 886 #define AR5K_PCICFG_EESIZE_4K 0 /* 4K */
887 #define AR5K_PCICFG_EESIZE_8K 1 /* 8K */ 887 #define AR5K_PCICFG_EESIZE_8K 1 /* 8K */
888 #define AR5K_PCICFG_EESIZE_16K 2 /* 16K */ 888 #define AR5K_PCICFG_EESIZE_16K 2 /* 16K */
889 #define AR5K_PCICFG_EESIZE_FAIL 3 /* Failed to get size [5211+] */ 889 #define AR5K_PCICFG_EESIZE_FAIL 3 /* Failed to get size [5211+] */
890 #define AR5K_PCICFG_LED 0x00000060 /* Led status [5211+] */ 890 #define AR5K_PCICFG_LED 0x00000060 /* Led status [5211+] */
891 #define AR5K_PCICFG_LED_NONE 0x00000000 /* Default [5211+] */ 891 #define AR5K_PCICFG_LED_NONE 0x00000000 /* Default [5211+] */
892 #define AR5K_PCICFG_LED_PEND 0x00000020 /* Scan / Auth pending */ 892 #define AR5K_PCICFG_LED_PEND 0x00000020 /* Scan / Auth pending */
893 #define AR5K_PCICFG_LED_ASSOC 0x00000040 /* Associated */ 893 #define AR5K_PCICFG_LED_ASSOC 0x00000040 /* Associated */
894 #define AR5K_PCICFG_BUS_SEL 0x00000380 /* Mask for "bus select" [5211+] (?) */ 894 #define AR5K_PCICFG_BUS_SEL 0x00000380 /* Mask for "bus select" [5211+] (?) */
895 #define AR5K_PCICFG_CBEFIX_DIS 0x00000400 /* Disable CBE fix */ 895 #define AR5K_PCICFG_CBEFIX_DIS 0x00000400 /* Disable CBE fix */
896 #define AR5K_PCICFG_SL_INTEN 0x00000800 /* Enable interrupts when asleep */ 896 #define AR5K_PCICFG_SL_INTEN 0x00000800 /* Enable interrupts when asleep */
897 #define AR5K_PCICFG_LED_BCTL 0x00001000 /* Led blink (?) [5210] */ 897 #define AR5K_PCICFG_LED_BCTL 0x00001000 /* Led blink (?) [5210] */
898 #define AR5K_PCICFG_RETRY_FIX 0x00001000 /* Enable pci core retry fix */ 898 #define AR5K_PCICFG_RETRY_FIX 0x00001000 /* Enable pci core retry fix */
899 #define AR5K_PCICFG_SL_INPEN 0x00002000 /* Sleep even whith pending interrupts*/ 899 #define AR5K_PCICFG_SL_INPEN 0x00002000 /* Sleep even whith pending interrupts*/
900 #define AR5K_PCICFG_SPWR_DN 0x00010000 /* Mask for power status */ 900 #define AR5K_PCICFG_SPWR_DN 0x00010000 /* Mask for power status */
901 #define AR5K_PCICFG_LEDMODE 0x000e0000 /* Ledmode [5211+] */ 901 #define AR5K_PCICFG_LEDMODE 0x000e0000 /* Ledmode [5211+] */
902 #define AR5K_PCICFG_LEDMODE_PROP 0x00000000 /* Blink on standard traffic [5211+] */ 902 #define AR5K_PCICFG_LEDMODE_PROP 0x00000000 /* Blink on standard traffic [5211+] */
903 #define AR5K_PCICFG_LEDMODE_PROM 0x00020000 /* Default mode (blink on any traffic) [5211+] */ 903 #define AR5K_PCICFG_LEDMODE_PROM 0x00020000 /* Default mode (blink on any traffic) [5211+] */
904 #define AR5K_PCICFG_LEDMODE_PWR 0x00040000 /* Some other blinking mode (?) [5211+] */ 904 #define AR5K_PCICFG_LEDMODE_PWR 0x00040000 /* Some other blinking mode (?) [5211+] */
905 #define AR5K_PCICFG_LEDMODE_RAND 0x00060000 /* Random blinking (?) [5211+] */ 905 #define AR5K_PCICFG_LEDMODE_RAND 0x00060000 /* Random blinking (?) [5211+] */
906 #define AR5K_PCICFG_LEDBLINK 0x00700000 /* Led blink rate */ 906 #define AR5K_PCICFG_LEDBLINK 0x00700000 /* Led blink rate */
907 #define AR5K_PCICFG_LEDBLINK_S 20 907 #define AR5K_PCICFG_LEDBLINK_S 20
908 #define AR5K_PCICFG_LEDSLOW 0x00800000 /* Slowest led blink rate [5211+] */ 908 #define AR5K_PCICFG_LEDSLOW 0x00800000 /* Slowest led blink rate [5211+] */
909 #define AR5K_PCICFG_LEDSTATE \ 909 #define AR5K_PCICFG_LEDSTATE \
910 (AR5K_PCICFG_LED | AR5K_PCICFG_LEDMODE | \ 910 (AR5K_PCICFG_LED | AR5K_PCICFG_LEDMODE | \
911 AR5K_PCICFG_LEDBLINK | AR5K_PCICFG_LEDSLOW) 911 AR5K_PCICFG_LEDBLINK | AR5K_PCICFG_LEDSLOW)
912 #define AR5K_PCICFG_SLEEP_CLOCK_RATE 0x03000000 /* Sleep clock rate */ 912 #define AR5K_PCICFG_SLEEP_CLOCK_RATE 0x03000000 /* Sleep clock rate */
913 #define AR5K_PCICFG_SLEEP_CLOCK_RATE_S 24 913 #define AR5K_PCICFG_SLEEP_CLOCK_RATE_S 24
914 914
915 /* 915 /*
916 * "General Purpose Input/Output" (GPIO) control register 916 * "General Purpose Input/Output" (GPIO) control register
917 * 917 *
918 * I'm not sure about this but after looking at the code 918 * I'm not sure about this but after looking at the code
919 * for all chipsets here is what i got. 919 * for all chipsets here is what i got.
920 * 920 *
921 * We have 6 GPIOs (pins), each GPIO has 4 modes (2 bits) 921 * We have 6 GPIOs (pins), each GPIO has 4 modes (2 bits)
922 * Mode 0 -> always input 922 * Mode 0 -> always input
923 * Mode 1 -> output when GPIODO for this GPIO is set to 0 923 * Mode 1 -> output when GPIODO for this GPIO is set to 0
924 * Mode 2 -> output when GPIODO for this GPIO is set to 1 924 * Mode 2 -> output when GPIODO for this GPIO is set to 1
925 * Mode 3 -> always output 925 * Mode 3 -> always output
926 * 926 *
927 * For more infos check out get_gpio/set_gpio and 927 * For more infos check out get_gpio/set_gpio and
928 * set_gpio_input/set_gpio_output functs. 928 * set_gpio_input/set_gpio_output functs.
929 * For more infos on gpio interrupt check out set_gpio_intr. 929 * For more infos on gpio interrupt check out set_gpio_intr.
930 */ 930 */
931 #define AR5K_NUM_GPIO 6 931 #define AR5K_NUM_GPIO 6
932 932
933 #define AR5K_GPIOCR 0x4014 /* Register Address */ 933 #define AR5K_GPIOCR 0x4014 /* Register Address */
934 #define AR5K_GPIOCR_INT_ENA 0x00008000 /* Enable GPIO interrupt */ 934 #define AR5K_GPIOCR_INT_ENA 0x00008000 /* Enable GPIO interrupt */
935 #define AR5K_GPIOCR_INT_SELL 0x00000000 /* Generate interrupt when pin is low */ 935 #define AR5K_GPIOCR_INT_SELL 0x00000000 /* Generate interrupt when pin is low */
936 #define AR5K_GPIOCR_INT_SELH 0x00010000 /* Generate interrupt when pin is high */ 936 #define AR5K_GPIOCR_INT_SELH 0x00010000 /* Generate interrupt when pin is high */
937 #define AR5K_GPIOCR_IN(n) (0 << ((n) * 2)) /* Mode 0 for pin n */ 937 #define AR5K_GPIOCR_IN(n) (0 << ((n) * 2)) /* Mode 0 for pin n */
938 #define AR5K_GPIOCR_OUT0(n) (1 << ((n) * 2)) /* Mode 1 for pin n */ 938 #define AR5K_GPIOCR_OUT0(n) (1 << ((n) * 2)) /* Mode 1 for pin n */
939 #define AR5K_GPIOCR_OUT1(n) (2 << ((n) * 2)) /* Mode 2 for pin n */ 939 #define AR5K_GPIOCR_OUT1(n) (2 << ((n) * 2)) /* Mode 2 for pin n */
940 #define AR5K_GPIOCR_OUT(n) (3 << ((n) * 2)) /* Mode 3 for pin n */ 940 #define AR5K_GPIOCR_OUT(n) (3 << ((n) * 2)) /* Mode 3 for pin n */
941 #define AR5K_GPIOCR_INT_SEL(n) ((n) << 12) /* Interrupt for GPIO pin n */ 941 #define AR5K_GPIOCR_INT_SEL(n) ((n) << 12) /* Interrupt for GPIO pin n */
942 942
943 /* 943 /*
944 * "General Purpose Input/Output" (GPIO) data output register 944 * "General Purpose Input/Output" (GPIO) data output register
945 */ 945 */
946 #define AR5K_GPIODO 0x4018 946 #define AR5K_GPIODO 0x4018
947 947
948 /* 948 /*
949 * "General Purpose Input/Output" (GPIO) data input register 949 * "General Purpose Input/Output" (GPIO) data input register
950 */ 950 */
951 #define AR5K_GPIODI 0x401c 951 #define AR5K_GPIODI 0x401c
952 #define AR5K_GPIODI_M 0x0000002f 952 #define AR5K_GPIODI_M 0x0000002f
953 953
954 /* 954 /*
955 * Silicon revision register 955 * Silicon revision register
956 */ 956 */
957 #define AR5K_SREV 0x4020 /* Register Address */ 957 #define AR5K_SREV 0x4020 /* Register Address */
958 #define AR5K_SREV_REV 0x0000000f /* Mask for revision */ 958 #define AR5K_SREV_REV 0x0000000f /* Mask for revision */
959 #define AR5K_SREV_REV_S 0 959 #define AR5K_SREV_REV_S 0
960 #define AR5K_SREV_VER 0x000000ff /* Mask for version */ 960 #define AR5K_SREV_VER 0x000000ff /* Mask for version */
961 #define AR5K_SREV_VER_S 4 961 #define AR5K_SREV_VER_S 4
962 962
963 /* 963 /*
964 * TXE write posting register 964 * TXE write posting register
965 */ 965 */
966 #define AR5K_TXEPOST 0x4028 966 #define AR5K_TXEPOST 0x4028
967 967
968 /* 968 /*
969 * QCU sleep mask 969 * QCU sleep mask
970 */ 970 */
971 #define AR5K_QCU_SLEEP_MASK 0x402c 971 #define AR5K_QCU_SLEEP_MASK 0x402c
972 972
973 /* 0x4068 is compression buffer configuration 973 /* 0x4068 is compression buffer configuration
974 * register on 5414 and pm configuration register 974 * register on 5414 and pm configuration register
975 * on 5424 and newer pci-e chips. */ 975 * on 5424 and newer pci-e chips. */
976 976
977 /* 977 /*
978 * Compression buffer configuration 978 * Compression buffer configuration
979 * register (enable/disable) [5414] 979 * register (enable/disable) [5414]
980 */ 980 */
981 #define AR5K_5414_CBCFG 0x4068 981 #define AR5K_5414_CBCFG 0x4068
982 #define AR5K_5414_CBCFG_BUF_DIS 0x10 /* Disable buffer */ 982 #define AR5K_5414_CBCFG_BUF_DIS 0x10 /* Disable buffer */
983 983
984 /* 984 /*
985 * PCI-E Power managment configuration 985 * PCI-E Power management configuration
986 * and status register [5424+] 986 * and status register [5424+]
987 */ 987 */
988 #define AR5K_PCIE_PM_CTL 0x4068 /* Register address */ 988 #define AR5K_PCIE_PM_CTL 0x4068 /* Register address */
989 /* Only 5424 */ 989 /* Only 5424 */
990 #define AR5K_PCIE_PM_CTL_L1_WHEN_D2 0x00000001 /* enable PCIe core enter L1 990 #define AR5K_PCIE_PM_CTL_L1_WHEN_D2 0x00000001 /* enable PCIe core enter L1
991 when d2_sleep_en is asserted */ 991 when d2_sleep_en is asserted */
992 #define AR5K_PCIE_PM_CTL_L0_L0S_CLEAR 0x00000002 /* Clear L0 and L0S counters */ 992 #define AR5K_PCIE_PM_CTL_L0_L0S_CLEAR 0x00000002 /* Clear L0 and L0S counters */
993 #define AR5K_PCIE_PM_CTL_L0_L0S_EN 0x00000004 /* Start L0 nd L0S counters */ 993 #define AR5K_PCIE_PM_CTL_L0_L0S_EN 0x00000004 /* Start L0 nd L0S counters */
994 #define AR5K_PCIE_PM_CTL_LDRESET_EN 0x00000008 /* Enable reset when link goes 994 #define AR5K_PCIE_PM_CTL_LDRESET_EN 0x00000008 /* Enable reset when link goes
995 down */ 995 down */
996 /* Wake On Wireless */ 996 /* Wake On Wireless */
997 #define AR5K_PCIE_PM_CTL_PME_EN 0x00000010 /* PME Enable */ 997 #define AR5K_PCIE_PM_CTL_PME_EN 0x00000010 /* PME Enable */
998 #define AR5K_PCIE_PM_CTL_AUX_PWR_DET 0x00000020 /* Aux power detect */ 998 #define AR5K_PCIE_PM_CTL_AUX_PWR_DET 0x00000020 /* Aux power detect */
999 #define AR5K_PCIE_PM_CTL_PME_CLEAR 0x00000040 /* Clear PME */ 999 #define AR5K_PCIE_PM_CTL_PME_CLEAR 0x00000040 /* Clear PME */
1000 #define AR5K_PCIE_PM_CTL_PSM_D0 0x00000080 1000 #define AR5K_PCIE_PM_CTL_PSM_D0 0x00000080
1001 #define AR5K_PCIE_PM_CTL_PSM_D1 0x00000100 1001 #define AR5K_PCIE_PM_CTL_PSM_D1 0x00000100
1002 #define AR5K_PCIE_PM_CTL_PSM_D2 0x00000200 1002 #define AR5K_PCIE_PM_CTL_PSM_D2 0x00000200
1003 #define AR5K_PCIE_PM_CTL_PSM_D3 0x00000400 1003 #define AR5K_PCIE_PM_CTL_PSM_D3 0x00000400
1004 1004
1005 /* 1005 /*
1006 * PCI-E Workaround enable register 1006 * PCI-E Workaround enable register
1007 */ 1007 */
1008 #define AR5K_PCIE_WAEN 0x407c 1008 #define AR5K_PCIE_WAEN 0x407c
1009 1009
1010 /* 1010 /*
1011 * PCI-E Serializer/Desirializer 1011 * PCI-E Serializer/Desirializer
1012 * registers 1012 * registers
1013 */ 1013 */
1014 #define AR5K_PCIE_SERDES 0x4080 1014 #define AR5K_PCIE_SERDES 0x4080
1015 #define AR5K_PCIE_SERDES_RESET 0x4084 1015 #define AR5K_PCIE_SERDES_RESET 0x4084
1016 1016
1017 /*====EEPROM REGISTERS====*/ 1017 /*====EEPROM REGISTERS====*/
1018 1018
1019 /* 1019 /*
1020 * EEPROM access registers 1020 * EEPROM access registers
1021 * 1021 *
1022 * Here we got a difference between 5210/5211-12 1022 * Here we got a difference between 5210/5211-12
1023 * read data register for 5210 is at 0x6800 and 1023 * read data register for 5210 is at 0x6800 and
1024 * status register is at 0x6c00. There is also 1024 * status register is at 0x6c00. There is also
1025 * no eeprom command register on 5210 and the 1025 * no eeprom command register on 5210 and the
1026 * offsets are different. 1026 * offsets are different.
1027 * 1027 *
1028 * To read eeprom data for a specific offset: 1028 * To read eeprom data for a specific offset:
1029 * 5210 - enable eeprom access (AR5K_PCICFG_EEAE) 1029 * 5210 - enable eeprom access (AR5K_PCICFG_EEAE)
1030 * read AR5K_EEPROM_BASE +(4 * offset) 1030 * read AR5K_EEPROM_BASE +(4 * offset)
1031 * check the eeprom status register 1031 * check the eeprom status register
1032 * and read eeprom data register. 1032 * and read eeprom data register.
1033 * 1033 *
1034 * 5211 - write offset to AR5K_EEPROM_BASE 1034 * 5211 - write offset to AR5K_EEPROM_BASE
1035 * 5212 write AR5K_EEPROM_CMD_READ on AR5K_EEPROM_CMD 1035 * 5212 write AR5K_EEPROM_CMD_READ on AR5K_EEPROM_CMD
1036 * check the eeprom status register 1036 * check the eeprom status register
1037 * and read eeprom data register. 1037 * and read eeprom data register.
1038 * 1038 *
1039 * To write eeprom data for a specific offset: 1039 * To write eeprom data for a specific offset:
1040 * 5210 - enable eeprom access (AR5K_PCICFG_EEAE) 1040 * 5210 - enable eeprom access (AR5K_PCICFG_EEAE)
1041 * write data to AR5K_EEPROM_BASE +(4 * offset) 1041 * write data to AR5K_EEPROM_BASE +(4 * offset)
1042 * check the eeprom status register 1042 * check the eeprom status register
1043 * 5211 - write AR5K_EEPROM_CMD_RESET on AR5K_EEPROM_CMD 1043 * 5211 - write AR5K_EEPROM_CMD_RESET on AR5K_EEPROM_CMD
1044 * 5212 write offset to AR5K_EEPROM_BASE 1044 * 5212 write offset to AR5K_EEPROM_BASE
1045 * write data to data register 1045 * write data to data register
1046 * write AR5K_EEPROM_CMD_WRITE on AR5K_EEPROM_CMD 1046 * write AR5K_EEPROM_CMD_WRITE on AR5K_EEPROM_CMD
1047 * check the eeprom status register 1047 * check the eeprom status register
1048 * 1048 *
1049 * For more infos check eeprom_* functs and the ar5k.c 1049 * For more infos check eeprom_* functs and the ar5k.c
1050 * file posted in madwifi-devel mailing list. 1050 * file posted in madwifi-devel mailing list.
1051 * http://sourceforge.net/mailarchive/message.php?msg_id=8966525 1051 * http://sourceforge.net/mailarchive/message.php?msg_id=8966525
1052 * 1052 *
1053 */ 1053 */
1054 #define AR5K_EEPROM_BASE 0x6000 1054 #define AR5K_EEPROM_BASE 0x6000
1055 1055
1056 /* 1056 /*
1057 * EEPROM data register 1057 * EEPROM data register
1058 */ 1058 */
1059 #define AR5K_EEPROM_DATA_5211 0x6004 1059 #define AR5K_EEPROM_DATA_5211 0x6004
1060 #define AR5K_EEPROM_DATA_5210 0x6800 1060 #define AR5K_EEPROM_DATA_5210 0x6800
1061 #define AR5K_EEPROM_DATA (ah->ah_version == AR5K_AR5210 ? \ 1061 #define AR5K_EEPROM_DATA (ah->ah_version == AR5K_AR5210 ? \
1062 AR5K_EEPROM_DATA_5210 : AR5K_EEPROM_DATA_5211) 1062 AR5K_EEPROM_DATA_5210 : AR5K_EEPROM_DATA_5211)
1063 1063
1064 /* 1064 /*
1065 * EEPROM command register 1065 * EEPROM command register
1066 */ 1066 */
1067 #define AR5K_EEPROM_CMD 0x6008 /* Register Addres */ 1067 #define AR5K_EEPROM_CMD 0x6008 /* Register Addres */
1068 #define AR5K_EEPROM_CMD_READ 0x00000001 /* EEPROM read */ 1068 #define AR5K_EEPROM_CMD_READ 0x00000001 /* EEPROM read */
1069 #define AR5K_EEPROM_CMD_WRITE 0x00000002 /* EEPROM write */ 1069 #define AR5K_EEPROM_CMD_WRITE 0x00000002 /* EEPROM write */
1070 #define AR5K_EEPROM_CMD_RESET 0x00000004 /* EEPROM reset */ 1070 #define AR5K_EEPROM_CMD_RESET 0x00000004 /* EEPROM reset */
1071 1071
1072 /* 1072 /*
1073 * EEPROM status register 1073 * EEPROM status register
1074 */ 1074 */
1075 #define AR5K_EEPROM_STAT_5210 0x6c00 /* Register Address [5210] */ 1075 #define AR5K_EEPROM_STAT_5210 0x6c00 /* Register Address [5210] */
1076 #define AR5K_EEPROM_STAT_5211 0x600c /* Register Address [5211+] */ 1076 #define AR5K_EEPROM_STAT_5211 0x600c /* Register Address [5211+] */
1077 #define AR5K_EEPROM_STATUS (ah->ah_version == AR5K_AR5210 ? \ 1077 #define AR5K_EEPROM_STATUS (ah->ah_version == AR5K_AR5210 ? \
1078 AR5K_EEPROM_STAT_5210 : AR5K_EEPROM_STAT_5211) 1078 AR5K_EEPROM_STAT_5210 : AR5K_EEPROM_STAT_5211)
1079 #define AR5K_EEPROM_STAT_RDERR 0x00000001 /* EEPROM read failed */ 1079 #define AR5K_EEPROM_STAT_RDERR 0x00000001 /* EEPROM read failed */
1080 #define AR5K_EEPROM_STAT_RDDONE 0x00000002 /* EEPROM read successful */ 1080 #define AR5K_EEPROM_STAT_RDDONE 0x00000002 /* EEPROM read successful */
1081 #define AR5K_EEPROM_STAT_WRERR 0x00000004 /* EEPROM write failed */ 1081 #define AR5K_EEPROM_STAT_WRERR 0x00000004 /* EEPROM write failed */
1082 #define AR5K_EEPROM_STAT_WRDONE 0x00000008 /* EEPROM write successful */ 1082 #define AR5K_EEPROM_STAT_WRDONE 0x00000008 /* EEPROM write successful */
1083 1083
1084 /* 1084 /*
1085 * EEPROM config register 1085 * EEPROM config register
1086 */ 1086 */
1087 #define AR5K_EEPROM_CFG 0x6010 /* Register Addres */ 1087 #define AR5K_EEPROM_CFG 0x6010 /* Register Addres */
1088 #define AR5K_EEPROM_CFG_SIZE 0x00000003 /* Size determination override */ 1088 #define AR5K_EEPROM_CFG_SIZE 0x00000003 /* Size determination override */
1089 #define AR5K_EEPROM_CFG_SIZE_AUTO 0 1089 #define AR5K_EEPROM_CFG_SIZE_AUTO 0
1090 #define AR5K_EEPROM_CFG_SIZE_4KBIT 1 1090 #define AR5K_EEPROM_CFG_SIZE_4KBIT 1
1091 #define AR5K_EEPROM_CFG_SIZE_8KBIT 2 1091 #define AR5K_EEPROM_CFG_SIZE_8KBIT 2
1092 #define AR5K_EEPROM_CFG_SIZE_16KBIT 3 1092 #define AR5K_EEPROM_CFG_SIZE_16KBIT 3
1093 #define AR5K_EEPROM_CFG_WR_WAIT_DIS 0x00000004 /* Disable write wait */ 1093 #define AR5K_EEPROM_CFG_WR_WAIT_DIS 0x00000004 /* Disable write wait */
1094 #define AR5K_EEPROM_CFG_CLK_RATE 0x00000018 /* Clock rate */ 1094 #define AR5K_EEPROM_CFG_CLK_RATE 0x00000018 /* Clock rate */
1095 #define AR5K_EEPROM_CFG_CLK_RATE_S 3 1095 #define AR5K_EEPROM_CFG_CLK_RATE_S 3
1096 #define AR5K_EEPROM_CFG_CLK_RATE_156KHZ 0 1096 #define AR5K_EEPROM_CFG_CLK_RATE_156KHZ 0
1097 #define AR5K_EEPROM_CFG_CLK_RATE_312KHZ 1 1097 #define AR5K_EEPROM_CFG_CLK_RATE_312KHZ 1
1098 #define AR5K_EEPROM_CFG_CLK_RATE_625KHZ 2 1098 #define AR5K_EEPROM_CFG_CLK_RATE_625KHZ 2
1099 #define AR5K_EEPROM_CFG_PROT_KEY 0x00ffff00 /* Protection key */ 1099 #define AR5K_EEPROM_CFG_PROT_KEY 0x00ffff00 /* Protection key */
1100 #define AR5K_EEPROM_CFG_PROT_KEY_S 8 1100 #define AR5K_EEPROM_CFG_PROT_KEY_S 8
1101 #define AR5K_EEPROM_CFG_LIND_EN 0x01000000 /* Enable length indicator (?) */ 1101 #define AR5K_EEPROM_CFG_LIND_EN 0x01000000 /* Enable length indicator (?) */
1102 1102
1103 1103
1104 /* 1104 /*
1105 * TODO: Wake On Wireless registers 1105 * TODO: Wake On Wireless registers
1106 * Range 0x7000 - 0x7ce0 1106 * Range 0x7000 - 0x7ce0
1107 */ 1107 */
1108 1108
1109 /* 1109 /*
1110 * Protocol Control Unit (PCU) registers 1110 * Protocol Control Unit (PCU) registers
1111 */ 1111 */
1112 /* 1112 /*
1113 * Used for checking initial register writes 1113 * Used for checking initial register writes
1114 * during channel reset (see reset func) 1114 * during channel reset (see reset func)
1115 */ 1115 */
1116 #define AR5K_PCU_MIN 0x8000 1116 #define AR5K_PCU_MIN 0x8000
1117 #define AR5K_PCU_MAX 0x8fff 1117 #define AR5K_PCU_MAX 0x8fff
1118 1118
1119 /* 1119 /*
1120 * First station id register (Lower 32 bits of MAC address) 1120 * First station id register (Lower 32 bits of MAC address)
1121 */ 1121 */
1122 #define AR5K_STA_ID0 0x8000 1122 #define AR5K_STA_ID0 0x8000
1123 #define AR5K_STA_ID0_ARRD_L32 0xffffffff 1123 #define AR5K_STA_ID0_ARRD_L32 0xffffffff
1124 1124
1125 /* 1125 /*
1126 * Second station id register (Upper 16 bits of MAC address + PCU settings) 1126 * Second station id register (Upper 16 bits of MAC address + PCU settings)
1127 */ 1127 */
1128 #define AR5K_STA_ID1 0x8004 /* Register Address */ 1128 #define AR5K_STA_ID1 0x8004 /* Register Address */
1129 #define AR5K_STA_ID1_ADDR_U16 0x0000ffff /* Upper 16 bits of MAC addres */ 1129 #define AR5K_STA_ID1_ADDR_U16 0x0000ffff /* Upper 16 bits of MAC addres */
1130 #define AR5K_STA_ID1_AP 0x00010000 /* Set AP mode */ 1130 #define AR5K_STA_ID1_AP 0x00010000 /* Set AP mode */
1131 #define AR5K_STA_ID1_ADHOC 0x00020000 /* Set Ad-Hoc mode */ 1131 #define AR5K_STA_ID1_ADHOC 0x00020000 /* Set Ad-Hoc mode */
1132 #define AR5K_STA_ID1_PWR_SV 0x00040000 /* Power save reporting */ 1132 #define AR5K_STA_ID1_PWR_SV 0x00040000 /* Power save reporting */
1133 #define AR5K_STA_ID1_NO_KEYSRCH 0x00080000 /* No key search */ 1133 #define AR5K_STA_ID1_NO_KEYSRCH 0x00080000 /* No key search */
1134 #define AR5K_STA_ID1_NO_PSPOLL 0x00100000 /* No power save polling [5210] */ 1134 #define AR5K_STA_ID1_NO_PSPOLL 0x00100000 /* No power save polling [5210] */
1135 #define AR5K_STA_ID1_PCF_5211 0x00100000 /* Enable PCF on [5211+] */ 1135 #define AR5K_STA_ID1_PCF_5211 0x00100000 /* Enable PCF on [5211+] */
1136 #define AR5K_STA_ID1_PCF_5210 0x00200000 /* Enable PCF on [5210]*/ 1136 #define AR5K_STA_ID1_PCF_5210 0x00200000 /* Enable PCF on [5210]*/
1137 #define AR5K_STA_ID1_PCF (ah->ah_version == AR5K_AR5210 ? \ 1137 #define AR5K_STA_ID1_PCF (ah->ah_version == AR5K_AR5210 ? \
1138 AR5K_STA_ID1_PCF_5210 : AR5K_STA_ID1_PCF_5211) 1138 AR5K_STA_ID1_PCF_5210 : AR5K_STA_ID1_PCF_5211)
1139 #define AR5K_STA_ID1_DEFAULT_ANTENNA 0x00200000 /* Use default antenna */ 1139 #define AR5K_STA_ID1_DEFAULT_ANTENNA 0x00200000 /* Use default antenna */
1140 #define AR5K_STA_ID1_DESC_ANTENNA 0x00400000 /* Update antenna from descriptor */ 1140 #define AR5K_STA_ID1_DESC_ANTENNA 0x00400000 /* Update antenna from descriptor */
1141 #define AR5K_STA_ID1_RTS_DEF_ANTENNA 0x00800000 /* Use default antenna for RTS */ 1141 #define AR5K_STA_ID1_RTS_DEF_ANTENNA 0x00800000 /* Use default antenna for RTS */
1142 #define AR5K_STA_ID1_ACKCTS_6MB 0x01000000 /* Use 6Mbit/s for ACK/CTS */ 1142 #define AR5K_STA_ID1_ACKCTS_6MB 0x01000000 /* Use 6Mbit/s for ACK/CTS */
1143 #define AR5K_STA_ID1_BASE_RATE_11B 0x02000000 /* Use 11b base rate for ACK/CTS [5211+] */ 1143 #define AR5K_STA_ID1_BASE_RATE_11B 0x02000000 /* Use 11b base rate for ACK/CTS [5211+] */
1144 #define AR5K_STA_ID1_SELFGEN_DEF_ANT 0x04000000 /* Use def. antenna for self generated frames */ 1144 #define AR5K_STA_ID1_SELFGEN_DEF_ANT 0x04000000 /* Use def. antenna for self generated frames */
1145 #define AR5K_STA_ID1_CRYPT_MIC_EN 0x08000000 /* Enable MIC */ 1145 #define AR5K_STA_ID1_CRYPT_MIC_EN 0x08000000 /* Enable MIC */
1146 #define AR5K_STA_ID1_KEYSRCH_MODE 0x10000000 /* Look up key when key id != 0 */ 1146 #define AR5K_STA_ID1_KEYSRCH_MODE 0x10000000 /* Look up key when key id != 0 */
1147 #define AR5K_STA_ID1_PRESERVE_SEQ_NUM 0x20000000 /* Preserve sequence number */ 1147 #define AR5K_STA_ID1_PRESERVE_SEQ_NUM 0x20000000 /* Preserve sequence number */
1148 #define AR5K_STA_ID1_CBCIV_ENDIAN 0x40000000 /* ??? */ 1148 #define AR5K_STA_ID1_CBCIV_ENDIAN 0x40000000 /* ??? */
1149 #define AR5K_STA_ID1_KEYSRCH_MCAST 0x80000000 /* Do key cache search for mcast frames */ 1149 #define AR5K_STA_ID1_KEYSRCH_MCAST 0x80000000 /* Do key cache search for mcast frames */
1150 1150
1151 #define AR5K_STA_ID1_ANTENNA_SETTINGS (AR5K_STA_ID1_DEFAULT_ANTENNA | \ 1151 #define AR5K_STA_ID1_ANTENNA_SETTINGS (AR5K_STA_ID1_DEFAULT_ANTENNA | \
1152 AR5K_STA_ID1_DESC_ANTENNA | \ 1152 AR5K_STA_ID1_DESC_ANTENNA | \
1153 AR5K_STA_ID1_RTS_DEF_ANTENNA | \ 1153 AR5K_STA_ID1_RTS_DEF_ANTENNA | \
1154 AR5K_STA_ID1_SELFGEN_DEF_ANT) 1154 AR5K_STA_ID1_SELFGEN_DEF_ANT)
1155 1155
1156 /* 1156 /*
1157 * First BSSID register (MAC address, lower 32bits) 1157 * First BSSID register (MAC address, lower 32bits)
1158 */ 1158 */
1159 #define AR5K_BSS_ID0 0x8008 1159 #define AR5K_BSS_ID0 0x8008
1160 1160
1161 /* 1161 /*
1162 * Second BSSID register (MAC address in upper 16 bits) 1162 * Second BSSID register (MAC address in upper 16 bits)
1163 * 1163 *
1164 * AID: Association ID 1164 * AID: Association ID
1165 */ 1165 */
1166 #define AR5K_BSS_ID1 0x800c 1166 #define AR5K_BSS_ID1 0x800c
1167 #define AR5K_BSS_ID1_AID 0xffff0000 1167 #define AR5K_BSS_ID1_AID 0xffff0000
1168 #define AR5K_BSS_ID1_AID_S 16 1168 #define AR5K_BSS_ID1_AID_S 16
1169 1169
1170 /* 1170 /*
1171 * Backoff slot time register 1171 * Backoff slot time register
1172 */ 1172 */
1173 #define AR5K_SLOT_TIME 0x8010 1173 #define AR5K_SLOT_TIME 0x8010
1174 1174
1175 /* 1175 /*
1176 * ACK/CTS timeout register 1176 * ACK/CTS timeout register
1177 */ 1177 */
1178 #define AR5K_TIME_OUT 0x8014 /* Register Address */ 1178 #define AR5K_TIME_OUT 0x8014 /* Register Address */
1179 #define AR5K_TIME_OUT_ACK 0x00001fff /* ACK timeout mask */ 1179 #define AR5K_TIME_OUT_ACK 0x00001fff /* ACK timeout mask */
1180 #define AR5K_TIME_OUT_ACK_S 0 1180 #define AR5K_TIME_OUT_ACK_S 0
1181 #define AR5K_TIME_OUT_CTS 0x1fff0000 /* CTS timeout mask */ 1181 #define AR5K_TIME_OUT_CTS 0x1fff0000 /* CTS timeout mask */
1182 #define AR5K_TIME_OUT_CTS_S 16 1182 #define AR5K_TIME_OUT_CTS_S 16
1183 1183
1184 /* 1184 /*
1185 * RSSI threshold register 1185 * RSSI threshold register
1186 */ 1186 */
1187 #define AR5K_RSSI_THR 0x8018 /* Register Address */ 1187 #define AR5K_RSSI_THR 0x8018 /* Register Address */
1188 #define AR5K_RSSI_THR_M 0x000000ff /* Mask for RSSI threshold [5211+] */ 1188 #define AR5K_RSSI_THR_M 0x000000ff /* Mask for RSSI threshold [5211+] */
1189 #define AR5K_RSSI_THR_BMISS_5210 0x00000700 /* Mask for Beacon Missed threshold [5210] */ 1189 #define AR5K_RSSI_THR_BMISS_5210 0x00000700 /* Mask for Beacon Missed threshold [5210] */
1190 #define AR5K_RSSI_THR_BMISS_5210_S 8 1190 #define AR5K_RSSI_THR_BMISS_5210_S 8
1191 #define AR5K_RSSI_THR_BMISS_5211 0x0000ff00 /* Mask for Beacon Missed threshold [5211+] */ 1191 #define AR5K_RSSI_THR_BMISS_5211 0x0000ff00 /* Mask for Beacon Missed threshold [5211+] */
1192 #define AR5K_RSSI_THR_BMISS_5211_S 8 1192 #define AR5K_RSSI_THR_BMISS_5211_S 8
1193 #define AR5K_RSSI_THR_BMISS (ah->ah_version == AR5K_AR5210 ? \ 1193 #define AR5K_RSSI_THR_BMISS (ah->ah_version == AR5K_AR5210 ? \
1194 AR5K_RSSI_THR_BMISS_5210 : AR5K_RSSI_THR_BMISS_5211) 1194 AR5K_RSSI_THR_BMISS_5210 : AR5K_RSSI_THR_BMISS_5211)
1195 #define AR5K_RSSI_THR_BMISS_S 8 1195 #define AR5K_RSSI_THR_BMISS_S 8
1196 1196
1197 /* 1197 /*
1198 * 5210 has more PCU registers because there is no QCU/DCU 1198 * 5210 has more PCU registers because there is no QCU/DCU
1199 * so queue parameters are set here, this way a lot common 1199 * so queue parameters are set here, this way a lot common
1200 * registers have different address for 5210. To make things 1200 * registers have different address for 5210. To make things
1201 * easier we define a macro based on ah->ah_version for common 1201 * easier we define a macro based on ah->ah_version for common
1202 * registers with different addresses and common flags. 1202 * registers with different addresses and common flags.
1203 */ 1203 */
1204 1204
1205 /* 1205 /*
1206 * Retry limit register 1206 * Retry limit register
1207 * 1207 *
1208 * Retry limit register for 5210 (no QCU/DCU so it's done in PCU) 1208 * Retry limit register for 5210 (no QCU/DCU so it's done in PCU)
1209 */ 1209 */
1210 #define AR5K_NODCU_RETRY_LMT 0x801c /* Register Address */ 1210 #define AR5K_NODCU_RETRY_LMT 0x801c /* Register Address */
1211 #define AR5K_NODCU_RETRY_LMT_SH_RETRY 0x0000000f /* Short retry limit mask */ 1211 #define AR5K_NODCU_RETRY_LMT_SH_RETRY 0x0000000f /* Short retry limit mask */
1212 #define AR5K_NODCU_RETRY_LMT_SH_RETRY_S 0 1212 #define AR5K_NODCU_RETRY_LMT_SH_RETRY_S 0
1213 #define AR5K_NODCU_RETRY_LMT_LG_RETRY 0x000000f0 /* Long retry mask */ 1213 #define AR5K_NODCU_RETRY_LMT_LG_RETRY 0x000000f0 /* Long retry mask */
1214 #define AR5K_NODCU_RETRY_LMT_LG_RETRY_S 4 1214 #define AR5K_NODCU_RETRY_LMT_LG_RETRY_S 4
1215 #define AR5K_NODCU_RETRY_LMT_SSH_RETRY 0x00003f00 /* Station short retry limit mask */ 1215 #define AR5K_NODCU_RETRY_LMT_SSH_RETRY 0x00003f00 /* Station short retry limit mask */
1216 #define AR5K_NODCU_RETRY_LMT_SSH_RETRY_S 8 1216 #define AR5K_NODCU_RETRY_LMT_SSH_RETRY_S 8
1217 #define AR5K_NODCU_RETRY_LMT_SLG_RETRY 0x000fc000 /* Station long retry limit mask */ 1217 #define AR5K_NODCU_RETRY_LMT_SLG_RETRY 0x000fc000 /* Station long retry limit mask */
1218 #define AR5K_NODCU_RETRY_LMT_SLG_RETRY_S 14 1218 #define AR5K_NODCU_RETRY_LMT_SLG_RETRY_S 14
1219 #define AR5K_NODCU_RETRY_LMT_CW_MIN 0x3ff00000 /* Minimum contention window mask */ 1219 #define AR5K_NODCU_RETRY_LMT_CW_MIN 0x3ff00000 /* Minimum contention window mask */
1220 #define AR5K_NODCU_RETRY_LMT_CW_MIN_S 20 1220 #define AR5K_NODCU_RETRY_LMT_CW_MIN_S 20
1221 1221
1222 /* 1222 /*
1223 * Transmit latency register 1223 * Transmit latency register
1224 */ 1224 */
1225 #define AR5K_USEC_5210 0x8020 /* Register Address [5210] */ 1225 #define AR5K_USEC_5210 0x8020 /* Register Address [5210] */
1226 #define AR5K_USEC_5211 0x801c /* Register Address [5211+] */ 1226 #define AR5K_USEC_5211 0x801c /* Register Address [5211+] */
1227 #define AR5K_USEC (ah->ah_version == AR5K_AR5210 ? \ 1227 #define AR5K_USEC (ah->ah_version == AR5K_AR5210 ? \
1228 AR5K_USEC_5210 : AR5K_USEC_5211) 1228 AR5K_USEC_5210 : AR5K_USEC_5211)
1229 #define AR5K_USEC_1 0x0000007f /* clock cycles for 1us */ 1229 #define AR5K_USEC_1 0x0000007f /* clock cycles for 1us */
1230 #define AR5K_USEC_1_S 0 1230 #define AR5K_USEC_1_S 0
1231 #define AR5K_USEC_32 0x00003f80 /* clock cycles for 1us while on 32Mhz clock */ 1231 #define AR5K_USEC_32 0x00003f80 /* clock cycles for 1us while on 32Mhz clock */
1232 #define AR5K_USEC_32_S 7 1232 #define AR5K_USEC_32_S 7
1233 #define AR5K_USEC_TX_LATENCY_5211 0x007fc000 1233 #define AR5K_USEC_TX_LATENCY_5211 0x007fc000
1234 #define AR5K_USEC_TX_LATENCY_5211_S 14 1234 #define AR5K_USEC_TX_LATENCY_5211_S 14
1235 #define AR5K_USEC_RX_LATENCY_5211 0x1f800000 1235 #define AR5K_USEC_RX_LATENCY_5211 0x1f800000
1236 #define AR5K_USEC_RX_LATENCY_5211_S 23 1236 #define AR5K_USEC_RX_LATENCY_5211_S 23
1237 #define AR5K_USEC_TX_LATENCY_5210 0x000fc000 /* also for 5311 */ 1237 #define AR5K_USEC_TX_LATENCY_5210 0x000fc000 /* also for 5311 */
1238 #define AR5K_USEC_TX_LATENCY_5210_S 14 1238 #define AR5K_USEC_TX_LATENCY_5210_S 14
1239 #define AR5K_USEC_RX_LATENCY_5210 0x03f00000 /* also for 5311 */ 1239 #define AR5K_USEC_RX_LATENCY_5210 0x03f00000 /* also for 5311 */
1240 #define AR5K_USEC_RX_LATENCY_5210_S 20 1240 #define AR5K_USEC_RX_LATENCY_5210_S 20
1241 1241
1242 /* 1242 /*
1243 * PCU beacon control register 1243 * PCU beacon control register
1244 */ 1244 */
1245 #define AR5K_BEACON_5210 0x8024 /*Register Address [5210] */ 1245 #define AR5K_BEACON_5210 0x8024 /*Register Address [5210] */
1246 #define AR5K_BEACON_5211 0x8020 /*Register Address [5211+] */ 1246 #define AR5K_BEACON_5211 0x8020 /*Register Address [5211+] */
1247 #define AR5K_BEACON (ah->ah_version == AR5K_AR5210 ? \ 1247 #define AR5K_BEACON (ah->ah_version == AR5K_AR5210 ? \
1248 AR5K_BEACON_5210 : AR5K_BEACON_5211) 1248 AR5K_BEACON_5210 : AR5K_BEACON_5211)
1249 #define AR5K_BEACON_PERIOD 0x0000ffff /* Mask for beacon period */ 1249 #define AR5K_BEACON_PERIOD 0x0000ffff /* Mask for beacon period */
1250 #define AR5K_BEACON_PERIOD_S 0 1250 #define AR5K_BEACON_PERIOD_S 0
1251 #define AR5K_BEACON_TIM 0x007f0000 /* Mask for TIM offset */ 1251 #define AR5K_BEACON_TIM 0x007f0000 /* Mask for TIM offset */
1252 #define AR5K_BEACON_TIM_S 16 1252 #define AR5K_BEACON_TIM_S 16
1253 #define AR5K_BEACON_ENABLE 0x00800000 /* Enable beacons */ 1253 #define AR5K_BEACON_ENABLE 0x00800000 /* Enable beacons */
1254 #define AR5K_BEACON_RESET_TSF 0x01000000 /* Force TSF reset */ 1254 #define AR5K_BEACON_RESET_TSF 0x01000000 /* Force TSF reset */
1255 1255
1256 /* 1256 /*
1257 * CFP period register 1257 * CFP period register
1258 */ 1258 */
1259 #define AR5K_CFP_PERIOD_5210 0x8028 1259 #define AR5K_CFP_PERIOD_5210 0x8028
1260 #define AR5K_CFP_PERIOD_5211 0x8024 1260 #define AR5K_CFP_PERIOD_5211 0x8024
1261 #define AR5K_CFP_PERIOD (ah->ah_version == AR5K_AR5210 ? \ 1261 #define AR5K_CFP_PERIOD (ah->ah_version == AR5K_AR5210 ? \
1262 AR5K_CFP_PERIOD_5210 : AR5K_CFP_PERIOD_5211) 1262 AR5K_CFP_PERIOD_5210 : AR5K_CFP_PERIOD_5211)
1263 1263
1264 /* 1264 /*
1265 * Next beacon time register 1265 * Next beacon time register
1266 */ 1266 */
1267 #define AR5K_TIMER0_5210 0x802c 1267 #define AR5K_TIMER0_5210 0x802c
1268 #define AR5K_TIMER0_5211 0x8028 1268 #define AR5K_TIMER0_5211 0x8028
1269 #define AR5K_TIMER0 (ah->ah_version == AR5K_AR5210 ? \ 1269 #define AR5K_TIMER0 (ah->ah_version == AR5K_AR5210 ? \
1270 AR5K_TIMER0_5210 : AR5K_TIMER0_5211) 1270 AR5K_TIMER0_5210 : AR5K_TIMER0_5211)
1271 1271
1272 /* 1272 /*
1273 * Next DMA beacon alert register 1273 * Next DMA beacon alert register
1274 */ 1274 */
1275 #define AR5K_TIMER1_5210 0x8030 1275 #define AR5K_TIMER1_5210 0x8030
1276 #define AR5K_TIMER1_5211 0x802c 1276 #define AR5K_TIMER1_5211 0x802c
1277 #define AR5K_TIMER1 (ah->ah_version == AR5K_AR5210 ? \ 1277 #define AR5K_TIMER1 (ah->ah_version == AR5K_AR5210 ? \
1278 AR5K_TIMER1_5210 : AR5K_TIMER1_5211) 1278 AR5K_TIMER1_5210 : AR5K_TIMER1_5211)
1279 1279
1280 /* 1280 /*
1281 * Next software beacon alert register 1281 * Next software beacon alert register
1282 */ 1282 */
1283 #define AR5K_TIMER2_5210 0x8034 1283 #define AR5K_TIMER2_5210 0x8034
1284 #define AR5K_TIMER2_5211 0x8030 1284 #define AR5K_TIMER2_5211 0x8030
1285 #define AR5K_TIMER2 (ah->ah_version == AR5K_AR5210 ? \ 1285 #define AR5K_TIMER2 (ah->ah_version == AR5K_AR5210 ? \
1286 AR5K_TIMER2_5210 : AR5K_TIMER2_5211) 1286 AR5K_TIMER2_5210 : AR5K_TIMER2_5211)
1287 1287
1288 /* 1288 /*
1289 * Next ATIM window time register 1289 * Next ATIM window time register
1290 */ 1290 */
1291 #define AR5K_TIMER3_5210 0x8038 1291 #define AR5K_TIMER3_5210 0x8038
1292 #define AR5K_TIMER3_5211 0x8034 1292 #define AR5K_TIMER3_5211 0x8034
1293 #define AR5K_TIMER3 (ah->ah_version == AR5K_AR5210 ? \ 1293 #define AR5K_TIMER3 (ah->ah_version == AR5K_AR5210 ? \
1294 AR5K_TIMER3_5210 : AR5K_TIMER3_5211) 1294 AR5K_TIMER3_5210 : AR5K_TIMER3_5211)
1295 1295
1296 1296
1297 /* 1297 /*
1298 * 5210 First inter frame spacing register (IFS) 1298 * 5210 First inter frame spacing register (IFS)
1299 */ 1299 */
1300 #define AR5K_IFS0 0x8040 1300 #define AR5K_IFS0 0x8040
1301 #define AR5K_IFS0_SIFS 0x000007ff 1301 #define AR5K_IFS0_SIFS 0x000007ff
1302 #define AR5K_IFS0_SIFS_S 0 1302 #define AR5K_IFS0_SIFS_S 0
1303 #define AR5K_IFS0_DIFS 0x007ff800 1303 #define AR5K_IFS0_DIFS 0x007ff800
1304 #define AR5K_IFS0_DIFS_S 11 1304 #define AR5K_IFS0_DIFS_S 11
1305 1305
1306 /* 1306 /*
1307 * 5210 Second inter frame spacing register (IFS) 1307 * 5210 Second inter frame spacing register (IFS)
1308 */ 1308 */
1309 #define AR5K_IFS1 0x8044 1309 #define AR5K_IFS1 0x8044
1310 #define AR5K_IFS1_PIFS 0x00000fff 1310 #define AR5K_IFS1_PIFS 0x00000fff
1311 #define AR5K_IFS1_PIFS_S 0 1311 #define AR5K_IFS1_PIFS_S 0
1312 #define AR5K_IFS1_EIFS 0x03fff000 1312 #define AR5K_IFS1_EIFS 0x03fff000
1313 #define AR5K_IFS1_EIFS_S 12 1313 #define AR5K_IFS1_EIFS_S 12
1314 #define AR5K_IFS1_CS_EN 0x04000000 1314 #define AR5K_IFS1_CS_EN 0x04000000
1315 1315
1316 1316
1317 /* 1317 /*
1318 * CFP duration register 1318 * CFP duration register
1319 */ 1319 */
1320 #define AR5K_CFP_DUR_5210 0x8048 1320 #define AR5K_CFP_DUR_5210 0x8048
1321 #define AR5K_CFP_DUR_5211 0x8038 1321 #define AR5K_CFP_DUR_5211 0x8038
1322 #define AR5K_CFP_DUR (ah->ah_version == AR5K_AR5210 ? \ 1322 #define AR5K_CFP_DUR (ah->ah_version == AR5K_AR5210 ? \
1323 AR5K_CFP_DUR_5210 : AR5K_CFP_DUR_5211) 1323 AR5K_CFP_DUR_5210 : AR5K_CFP_DUR_5211)
1324 1324
1325 /* 1325 /*
1326 * Receive filter register 1326 * Receive filter register
1327 */ 1327 */
1328 #define AR5K_RX_FILTER_5210 0x804c /* Register Address [5210] */ 1328 #define AR5K_RX_FILTER_5210 0x804c /* Register Address [5210] */
1329 #define AR5K_RX_FILTER_5211 0x803c /* Register Address [5211+] */ 1329 #define AR5K_RX_FILTER_5211 0x803c /* Register Address [5211+] */
1330 #define AR5K_RX_FILTER (ah->ah_version == AR5K_AR5210 ? \ 1330 #define AR5K_RX_FILTER (ah->ah_version == AR5K_AR5210 ? \
1331 AR5K_RX_FILTER_5210 : AR5K_RX_FILTER_5211) 1331 AR5K_RX_FILTER_5210 : AR5K_RX_FILTER_5211)
1332 #define AR5K_RX_FILTER_UCAST 0x00000001 /* Don't filter unicast frames */ 1332 #define AR5K_RX_FILTER_UCAST 0x00000001 /* Don't filter unicast frames */
1333 #define AR5K_RX_FILTER_MCAST 0x00000002 /* Don't filter multicast frames */ 1333 #define AR5K_RX_FILTER_MCAST 0x00000002 /* Don't filter multicast frames */
1334 #define AR5K_RX_FILTER_BCAST 0x00000004 /* Don't filter broadcast frames */ 1334 #define AR5K_RX_FILTER_BCAST 0x00000004 /* Don't filter broadcast frames */
1335 #define AR5K_RX_FILTER_CONTROL 0x00000008 /* Don't filter control frames */ 1335 #define AR5K_RX_FILTER_CONTROL 0x00000008 /* Don't filter control frames */
1336 #define AR5K_RX_FILTER_BEACON 0x00000010 /* Don't filter beacon frames */ 1336 #define AR5K_RX_FILTER_BEACON 0x00000010 /* Don't filter beacon frames */
1337 #define AR5K_RX_FILTER_PROM 0x00000020 /* Set promiscuous mode */ 1337 #define AR5K_RX_FILTER_PROM 0x00000020 /* Set promiscuous mode */
1338 #define AR5K_RX_FILTER_XRPOLL 0x00000040 /* Don't filter XR poll frame [5212+] */ 1338 #define AR5K_RX_FILTER_XRPOLL 0x00000040 /* Don't filter XR poll frame [5212+] */
1339 #define AR5K_RX_FILTER_PROBEREQ 0x00000080 /* Don't filter probe requests [5212+] */ 1339 #define AR5K_RX_FILTER_PROBEREQ 0x00000080 /* Don't filter probe requests [5212+] */
1340 #define AR5K_RX_FILTER_PHYERR_5212 0x00000100 /* Don't filter phy errors [5212+] */ 1340 #define AR5K_RX_FILTER_PHYERR_5212 0x00000100 /* Don't filter phy errors [5212+] */
1341 #define AR5K_RX_FILTER_RADARERR_5212 0x00000200 /* Don't filter phy radar errors [5212+] */ 1341 #define AR5K_RX_FILTER_RADARERR_5212 0x00000200 /* Don't filter phy radar errors [5212+] */
1342 #define AR5K_RX_FILTER_PHYERR_5211 0x00000040 /* [5211] */ 1342 #define AR5K_RX_FILTER_PHYERR_5211 0x00000040 /* [5211] */
1343 #define AR5K_RX_FILTER_RADARERR_5211 0x00000080 /* [5211] */ 1343 #define AR5K_RX_FILTER_RADARERR_5211 0x00000080 /* [5211] */
1344 #define AR5K_RX_FILTER_PHYERR \ 1344 #define AR5K_RX_FILTER_PHYERR \
1345 ((ah->ah_version == AR5K_AR5211 ? \ 1345 ((ah->ah_version == AR5K_AR5211 ? \
1346 AR5K_RX_FILTER_PHYERR_5211 : AR5K_RX_FILTER_PHYERR_5212)) 1346 AR5K_RX_FILTER_PHYERR_5211 : AR5K_RX_FILTER_PHYERR_5212))
1347 #define AR5K_RX_FILTER_RADARERR \ 1347 #define AR5K_RX_FILTER_RADARERR \
1348 ((ah->ah_version == AR5K_AR5211 ? \ 1348 ((ah->ah_version == AR5K_AR5211 ? \
1349 AR5K_RX_FILTER_RADARERR_5211 : AR5K_RX_FILTER_RADARERR_5212)) 1349 AR5K_RX_FILTER_RADARERR_5211 : AR5K_RX_FILTER_RADARERR_5212))
1350 1350
1351 /* 1351 /*
1352 * Multicast filter register (lower 32 bits) 1352 * Multicast filter register (lower 32 bits)
1353 */ 1353 */
1354 #define AR5K_MCAST_FILTER0_5210 0x8050 1354 #define AR5K_MCAST_FILTER0_5210 0x8050
1355 #define AR5K_MCAST_FILTER0_5211 0x8040 1355 #define AR5K_MCAST_FILTER0_5211 0x8040
1356 #define AR5K_MCAST_FILTER0 (ah->ah_version == AR5K_AR5210 ? \ 1356 #define AR5K_MCAST_FILTER0 (ah->ah_version == AR5K_AR5210 ? \
1357 AR5K_MCAST_FILTER0_5210 : AR5K_MCAST_FILTER0_5211) 1357 AR5K_MCAST_FILTER0_5210 : AR5K_MCAST_FILTER0_5211)
1358 1358
1359 /* 1359 /*
1360 * Multicast filter register (higher 16 bits) 1360 * Multicast filter register (higher 16 bits)
1361 */ 1361 */
1362 #define AR5K_MCAST_FILTER1_5210 0x8054 1362 #define AR5K_MCAST_FILTER1_5210 0x8054
1363 #define AR5K_MCAST_FILTER1_5211 0x8044 1363 #define AR5K_MCAST_FILTER1_5211 0x8044
1364 #define AR5K_MCAST_FILTER1 (ah->ah_version == AR5K_AR5210 ? \ 1364 #define AR5K_MCAST_FILTER1 (ah->ah_version == AR5K_AR5210 ? \
1365 AR5K_MCAST_FILTER1_5210 : AR5K_MCAST_FILTER1_5211) 1365 AR5K_MCAST_FILTER1_5210 : AR5K_MCAST_FILTER1_5211)
1366 1366
1367 1367
1368 /* 1368 /*
1369 * Transmit mask register (lower 32 bits) [5210] 1369 * Transmit mask register (lower 32 bits) [5210]
1370 */ 1370 */
1371 #define AR5K_TX_MASK0 0x8058 1371 #define AR5K_TX_MASK0 0x8058
1372 1372
1373 /* 1373 /*
1374 * Transmit mask register (higher 16 bits) [5210] 1374 * Transmit mask register (higher 16 bits) [5210]
1375 */ 1375 */
1376 #define AR5K_TX_MASK1 0x805c 1376 #define AR5K_TX_MASK1 0x805c
1377 1377
1378 /* 1378 /*
1379 * Clear transmit mask [5210] 1379 * Clear transmit mask [5210]
1380 */ 1380 */
1381 #define AR5K_CLR_TMASK 0x8060 1381 #define AR5K_CLR_TMASK 0x8060
1382 1382
1383 /* 1383 /*
1384 * Trigger level register (before transmission) [5210] 1384 * Trigger level register (before transmission) [5210]
1385 */ 1385 */
1386 #define AR5K_TRIG_LVL 0x8064 1386 #define AR5K_TRIG_LVL 0x8064
1387 1387
1388 1388
1389 /* 1389 /*
1390 * PCU control register 1390 * PCU control register
1391 * 1391 *
1392 * Only DIS_RX is used in the code, the rest i guess are 1392 * Only DIS_RX is used in the code, the rest i guess are
1393 * for tweaking/diagnostics. 1393 * for tweaking/diagnostics.
1394 */ 1394 */
1395 #define AR5K_DIAG_SW_5210 0x8068 /* Register Address [5210] */ 1395 #define AR5K_DIAG_SW_5210 0x8068 /* Register Address [5210] */
1396 #define AR5K_DIAG_SW_5211 0x8048 /* Register Address [5211+] */ 1396 #define AR5K_DIAG_SW_5211 0x8048 /* Register Address [5211+] */
1397 #define AR5K_DIAG_SW (ah->ah_version == AR5K_AR5210 ? \ 1397 #define AR5K_DIAG_SW (ah->ah_version == AR5K_AR5210 ? \
1398 AR5K_DIAG_SW_5210 : AR5K_DIAG_SW_5211) 1398 AR5K_DIAG_SW_5210 : AR5K_DIAG_SW_5211)
1399 #define AR5K_DIAG_SW_DIS_WEP_ACK 0x00000001 /* Disable ACKs if WEP key is invalid */ 1399 #define AR5K_DIAG_SW_DIS_WEP_ACK 0x00000001 /* Disable ACKs if WEP key is invalid */
1400 #define AR5K_DIAG_SW_DIS_ACK 0x00000002 /* Disable ACKs */ 1400 #define AR5K_DIAG_SW_DIS_ACK 0x00000002 /* Disable ACKs */
1401 #define AR5K_DIAG_SW_DIS_CTS 0x00000004 /* Disable CTSs */ 1401 #define AR5K_DIAG_SW_DIS_CTS 0x00000004 /* Disable CTSs */
1402 #define AR5K_DIAG_SW_DIS_ENC 0x00000008 /* Disable encryption */ 1402 #define AR5K_DIAG_SW_DIS_ENC 0x00000008 /* Disable encryption */
1403 #define AR5K_DIAG_SW_DIS_DEC 0x00000010 /* Disable decryption */ 1403 #define AR5K_DIAG_SW_DIS_DEC 0x00000010 /* Disable decryption */
1404 #define AR5K_DIAG_SW_DIS_TX 0x00000020 /* Disable transmit [5210] */ 1404 #define AR5K_DIAG_SW_DIS_TX 0x00000020 /* Disable transmit [5210] */
1405 #define AR5K_DIAG_SW_DIS_RX_5210 0x00000040 /* Disable recieve */ 1405 #define AR5K_DIAG_SW_DIS_RX_5210 0x00000040 /* Disable recieve */
1406 #define AR5K_DIAG_SW_DIS_RX_5211 0x00000020 1406 #define AR5K_DIAG_SW_DIS_RX_5211 0x00000020
1407 #define AR5K_DIAG_SW_DIS_RX (ah->ah_version == AR5K_AR5210 ? \ 1407 #define AR5K_DIAG_SW_DIS_RX (ah->ah_version == AR5K_AR5210 ? \
1408 AR5K_DIAG_SW_DIS_RX_5210 : AR5K_DIAG_SW_DIS_RX_5211) 1408 AR5K_DIAG_SW_DIS_RX_5210 : AR5K_DIAG_SW_DIS_RX_5211)
1409 #define AR5K_DIAG_SW_LOOP_BACK_5210 0x00000080 /* Loopback (i guess it goes with DIS_TX) [5210] */ 1409 #define AR5K_DIAG_SW_LOOP_BACK_5210 0x00000080 /* Loopback (i guess it goes with DIS_TX) [5210] */
1410 #define AR5K_DIAG_SW_LOOP_BACK_5211 0x00000040 1410 #define AR5K_DIAG_SW_LOOP_BACK_5211 0x00000040
1411 #define AR5K_DIAG_SW_LOOP_BACK (ah->ah_version == AR5K_AR5210 ? \ 1411 #define AR5K_DIAG_SW_LOOP_BACK (ah->ah_version == AR5K_AR5210 ? \
1412 AR5K_DIAG_SW_LOOP_BACK_5210 : AR5K_DIAG_SW_LOOP_BACK_5211) 1412 AR5K_DIAG_SW_LOOP_BACK_5210 : AR5K_DIAG_SW_LOOP_BACK_5211)
1413 #define AR5K_DIAG_SW_CORR_FCS_5210 0x00000100 /* Corrupted FCS */ 1413 #define AR5K_DIAG_SW_CORR_FCS_5210 0x00000100 /* Corrupted FCS */
1414 #define AR5K_DIAG_SW_CORR_FCS_5211 0x00000080 1414 #define AR5K_DIAG_SW_CORR_FCS_5211 0x00000080
1415 #define AR5K_DIAG_SW_CORR_FCS (ah->ah_version == AR5K_AR5210 ? \ 1415 #define AR5K_DIAG_SW_CORR_FCS (ah->ah_version == AR5K_AR5210 ? \
1416 AR5K_DIAG_SW_CORR_FCS_5210 : AR5K_DIAG_SW_CORR_FCS_5211) 1416 AR5K_DIAG_SW_CORR_FCS_5210 : AR5K_DIAG_SW_CORR_FCS_5211)
1417 #define AR5K_DIAG_SW_CHAN_INFO_5210 0x00000200 /* Dump channel info */ 1417 #define AR5K_DIAG_SW_CHAN_INFO_5210 0x00000200 /* Dump channel info */
1418 #define AR5K_DIAG_SW_CHAN_INFO_5211 0x00000100 1418 #define AR5K_DIAG_SW_CHAN_INFO_5211 0x00000100
1419 #define AR5K_DIAG_SW_CHAN_INFO (ah->ah_version == AR5K_AR5210 ? \ 1419 #define AR5K_DIAG_SW_CHAN_INFO (ah->ah_version == AR5K_AR5210 ? \
1420 AR5K_DIAG_SW_CHAN_INFO_5210 : AR5K_DIAG_SW_CHAN_INFO_5211) 1420 AR5K_DIAG_SW_CHAN_INFO_5210 : AR5K_DIAG_SW_CHAN_INFO_5211)
1421 #define AR5K_DIAG_SW_EN_SCRAM_SEED_5210 0x00000400 /* Enable fixed scrambler seed */ 1421 #define AR5K_DIAG_SW_EN_SCRAM_SEED_5210 0x00000400 /* Enable fixed scrambler seed */
1422 #define AR5K_DIAG_SW_EN_SCRAM_SEED_5211 0x00000200 1422 #define AR5K_DIAG_SW_EN_SCRAM_SEED_5211 0x00000200
1423 #define AR5K_DIAG_SW_EN_SCRAM_SEED (ah->ah_version == AR5K_AR5210 ? \ 1423 #define AR5K_DIAG_SW_EN_SCRAM_SEED (ah->ah_version == AR5K_AR5210 ? \
1424 AR5K_DIAG_SW_EN_SCRAM_SEED_5210 : AR5K_DIAG_SW_EN_SCRAM_SEED_5211) 1424 AR5K_DIAG_SW_EN_SCRAM_SEED_5210 : AR5K_DIAG_SW_EN_SCRAM_SEED_5211)
1425 #define AR5K_DIAG_SW_ECO_ENABLE 0x00000400 /* [5211+] */ 1425 #define AR5K_DIAG_SW_ECO_ENABLE 0x00000400 /* [5211+] */
1426 #define AR5K_DIAG_SW_SCVRAM_SEED 0x0003f800 /* [5210] */ 1426 #define AR5K_DIAG_SW_SCVRAM_SEED 0x0003f800 /* [5210] */
1427 #define AR5K_DIAG_SW_SCRAM_SEED_M 0x0001fc00 /* Scrambler seed mask */ 1427 #define AR5K_DIAG_SW_SCRAM_SEED_M 0x0001fc00 /* Scrambler seed mask */
1428 #define AR5K_DIAG_SW_SCRAM_SEED_S 10 1428 #define AR5K_DIAG_SW_SCRAM_SEED_S 10
1429 #define AR5K_DIAG_SW_DIS_SEQ_INC 0x00040000 /* Disable seqnum increment (?)[5210] */ 1429 #define AR5K_DIAG_SW_DIS_SEQ_INC 0x00040000 /* Disable seqnum increment (?)[5210] */
1430 #define AR5K_DIAG_SW_FRAME_NV0_5210 0x00080000 1430 #define AR5K_DIAG_SW_FRAME_NV0_5210 0x00080000
1431 #define AR5K_DIAG_SW_FRAME_NV0_5211 0x00020000 /* Accept frames of non-zero protocol number */ 1431 #define AR5K_DIAG_SW_FRAME_NV0_5211 0x00020000 /* Accept frames of non-zero protocol number */
1432 #define AR5K_DIAG_SW_FRAME_NV0 (ah->ah_version == AR5K_AR5210 ? \ 1432 #define AR5K_DIAG_SW_FRAME_NV0 (ah->ah_version == AR5K_AR5210 ? \
1433 AR5K_DIAG_SW_FRAME_NV0_5210 : AR5K_DIAG_SW_FRAME_NV0_5211) 1433 AR5K_DIAG_SW_FRAME_NV0_5210 : AR5K_DIAG_SW_FRAME_NV0_5211)
1434 #define AR5K_DIAG_SW_OBSPT_M 0x000c0000 /* Observation point select (?) */ 1434 #define AR5K_DIAG_SW_OBSPT_M 0x000c0000 /* Observation point select (?) */
1435 #define AR5K_DIAG_SW_OBSPT_S 18 1435 #define AR5K_DIAG_SW_OBSPT_S 18
1436 #define AR5K_DIAG_SW_RX_CLEAR_HIGH 0x0010000 /* Force RX Clear high */ 1436 #define AR5K_DIAG_SW_RX_CLEAR_HIGH 0x0010000 /* Force RX Clear high */
1437 #define AR5K_DIAG_SW_IGNORE_CARR_SENSE 0x0020000 /* Ignore virtual carrier sense */ 1437 #define AR5K_DIAG_SW_IGNORE_CARR_SENSE 0x0020000 /* Ignore virtual carrier sense */
1438 #define AR5K_DIAG_SW_CHANEL_IDLE_HIGH 0x0040000 /* Force channel idle high */ 1438 #define AR5K_DIAG_SW_CHANEL_IDLE_HIGH 0x0040000 /* Force channel idle high */
1439 #define AR5K_DIAG_SW_PHEAR_ME 0x0080000 /* ??? */ 1439 #define AR5K_DIAG_SW_PHEAR_ME 0x0080000 /* ??? */
1440 1440
1441 /* 1441 /*
1442 * TSF (clock) register (lower 32 bits) 1442 * TSF (clock) register (lower 32 bits)
1443 */ 1443 */
1444 #define AR5K_TSF_L32_5210 0x806c 1444 #define AR5K_TSF_L32_5210 0x806c
1445 #define AR5K_TSF_L32_5211 0x804c 1445 #define AR5K_TSF_L32_5211 0x804c
1446 #define AR5K_TSF_L32 (ah->ah_version == AR5K_AR5210 ? \ 1446 #define AR5K_TSF_L32 (ah->ah_version == AR5K_AR5210 ? \
1447 AR5K_TSF_L32_5210 : AR5K_TSF_L32_5211) 1447 AR5K_TSF_L32_5210 : AR5K_TSF_L32_5211)
1448 1448
1449 /* 1449 /*
1450 * TSF (clock) register (higher 32 bits) 1450 * TSF (clock) register (higher 32 bits)
1451 */ 1451 */
1452 #define AR5K_TSF_U32_5210 0x8070 1452 #define AR5K_TSF_U32_5210 0x8070
1453 #define AR5K_TSF_U32_5211 0x8050 1453 #define AR5K_TSF_U32_5211 0x8050
1454 #define AR5K_TSF_U32 (ah->ah_version == AR5K_AR5210 ? \ 1454 #define AR5K_TSF_U32 (ah->ah_version == AR5K_AR5210 ? \
1455 AR5K_TSF_U32_5210 : AR5K_TSF_U32_5211) 1455 AR5K_TSF_U32_5210 : AR5K_TSF_U32_5211)
1456 1456
1457 /* 1457 /*
1458 * Last beacon timestamp register (Read Only) 1458 * Last beacon timestamp register (Read Only)
1459 */ 1459 */
1460 #define AR5K_LAST_TSTP 0x8080 1460 #define AR5K_LAST_TSTP 0x8080
1461 1461
1462 /* 1462 /*
1463 * ADDAC test register [5211+] 1463 * ADDAC test register [5211+]
1464 */ 1464 */
1465 #define AR5K_ADDAC_TEST 0x8054 /* Register Address */ 1465 #define AR5K_ADDAC_TEST 0x8054 /* Register Address */
1466 #define AR5K_ADDAC_TEST_TXCONT 0x00000001 /* Test continuous tx */ 1466 #define AR5K_ADDAC_TEST_TXCONT 0x00000001 /* Test continuous tx */
1467 #define AR5K_ADDAC_TEST_TST_MODE 0x00000002 /* Test mode */ 1467 #define AR5K_ADDAC_TEST_TST_MODE 0x00000002 /* Test mode */
1468 #define AR5K_ADDAC_TEST_LOOP_EN 0x00000004 /* Enable loop */ 1468 #define AR5K_ADDAC_TEST_LOOP_EN 0x00000004 /* Enable loop */
1469 #define AR5K_ADDAC_TEST_LOOP_LEN 0x00000008 /* Loop length (field) */ 1469 #define AR5K_ADDAC_TEST_LOOP_LEN 0x00000008 /* Loop length (field) */
1470 #define AR5K_ADDAC_TEST_USE_U8 0x00004000 /* Use upper 8 bits */ 1470 #define AR5K_ADDAC_TEST_USE_U8 0x00004000 /* Use upper 8 bits */
1471 #define AR5K_ADDAC_TEST_MSB 0x00008000 /* State of MSB */ 1471 #define AR5K_ADDAC_TEST_MSB 0x00008000 /* State of MSB */
1472 #define AR5K_ADDAC_TEST_TRIG_SEL 0x00010000 /* Trigger select */ 1472 #define AR5K_ADDAC_TEST_TRIG_SEL 0x00010000 /* Trigger select */
1473 #define AR5K_ADDAC_TEST_TRIG_PTY 0x00020000 /* Trigger polarity */ 1473 #define AR5K_ADDAC_TEST_TRIG_PTY 0x00020000 /* Trigger polarity */
1474 #define AR5K_ADDAC_TEST_RXCONT 0x00040000 /* Continuous capture */ 1474 #define AR5K_ADDAC_TEST_RXCONT 0x00040000 /* Continuous capture */
1475 #define AR5K_ADDAC_TEST_CAPTURE 0x00080000 /* Begin capture */ 1475 #define AR5K_ADDAC_TEST_CAPTURE 0x00080000 /* Begin capture */
1476 #define AR5K_ADDAC_TEST_TST_ARM 0x00100000 /* ARM rx buffer for capture */ 1476 #define AR5K_ADDAC_TEST_TST_ARM 0x00100000 /* ARM rx buffer for capture */
1477 1477
1478 /* 1478 /*
1479 * Default antenna register [5211+] 1479 * Default antenna register [5211+]
1480 */ 1480 */
1481 #define AR5K_DEFAULT_ANTENNA 0x8058 1481 #define AR5K_DEFAULT_ANTENNA 0x8058
1482 1482
1483 /* 1483 /*
1484 * Frame control QoS mask register (?) [5211+] 1484 * Frame control QoS mask register (?) [5211+]
1485 * (FC_QOS_MASK) 1485 * (FC_QOS_MASK)
1486 */ 1486 */
1487 #define AR5K_FRAME_CTL_QOSM 0x805c 1487 #define AR5K_FRAME_CTL_QOSM 0x805c
1488 1488
1489 /* 1489 /*
1490 * Seq mask register (?) [5211+] 1490 * Seq mask register (?) [5211+]
1491 */ 1491 */
1492 #define AR5K_SEQ_MASK 0x8060 1492 #define AR5K_SEQ_MASK 0x8060
1493 1493
1494 /* 1494 /*
1495 * Retry count register [5210] 1495 * Retry count register [5210]
1496 */ 1496 */
1497 #define AR5K_RETRY_CNT 0x8084 /* Register Address [5210] */ 1497 #define AR5K_RETRY_CNT 0x8084 /* Register Address [5210] */
1498 #define AR5K_RETRY_CNT_SSH 0x0000003f /* Station short retry count (?) */ 1498 #define AR5K_RETRY_CNT_SSH 0x0000003f /* Station short retry count (?) */
1499 #define AR5K_RETRY_CNT_SLG 0x00000fc0 /* Station long retry count (?) */ 1499 #define AR5K_RETRY_CNT_SLG 0x00000fc0 /* Station long retry count (?) */
1500 1500
1501 /* 1501 /*
1502 * Back-off status register [5210] 1502 * Back-off status register [5210]
1503 */ 1503 */
1504 #define AR5K_BACKOFF 0x8088 /* Register Address [5210] */ 1504 #define AR5K_BACKOFF 0x8088 /* Register Address [5210] */
1505 #define AR5K_BACKOFF_CW 0x000003ff /* Backoff Contention Window (?) */ 1505 #define AR5K_BACKOFF_CW 0x000003ff /* Backoff Contention Window (?) */
1506 #define AR5K_BACKOFF_CNT 0x03ff0000 /* Backoff count (?) */ 1506 #define AR5K_BACKOFF_CNT 0x03ff0000 /* Backoff count (?) */
1507 1507
1508 1508
1509 1509
1510 /* 1510 /*
1511 * NAV register (current) 1511 * NAV register (current)
1512 */ 1512 */
1513 #define AR5K_NAV_5210 0x808c 1513 #define AR5K_NAV_5210 0x808c
1514 #define AR5K_NAV_5211 0x8084 1514 #define AR5K_NAV_5211 0x8084
1515 #define AR5K_NAV (ah->ah_version == AR5K_AR5210 ? \ 1515 #define AR5K_NAV (ah->ah_version == AR5K_AR5210 ? \
1516 AR5K_NAV_5210 : AR5K_NAV_5211) 1516 AR5K_NAV_5210 : AR5K_NAV_5211)
1517 1517
1518 /* 1518 /*
1519 * RTS success register 1519 * RTS success register
1520 */ 1520 */
1521 #define AR5K_RTS_OK_5210 0x8090 1521 #define AR5K_RTS_OK_5210 0x8090
1522 #define AR5K_RTS_OK_5211 0x8088 1522 #define AR5K_RTS_OK_5211 0x8088
1523 #define AR5K_RTS_OK (ah->ah_version == AR5K_AR5210 ? \ 1523 #define AR5K_RTS_OK (ah->ah_version == AR5K_AR5210 ? \
1524 AR5K_RTS_OK_5210 : AR5K_RTS_OK_5211) 1524 AR5K_RTS_OK_5210 : AR5K_RTS_OK_5211)
1525 1525
1526 /* 1526 /*
1527 * RTS failure register 1527 * RTS failure register
1528 */ 1528 */
1529 #define AR5K_RTS_FAIL_5210 0x8094 1529 #define AR5K_RTS_FAIL_5210 0x8094
1530 #define AR5K_RTS_FAIL_5211 0x808c 1530 #define AR5K_RTS_FAIL_5211 0x808c
1531 #define AR5K_RTS_FAIL (ah->ah_version == AR5K_AR5210 ? \ 1531 #define AR5K_RTS_FAIL (ah->ah_version == AR5K_AR5210 ? \
1532 AR5K_RTS_FAIL_5210 : AR5K_RTS_FAIL_5211) 1532 AR5K_RTS_FAIL_5210 : AR5K_RTS_FAIL_5211)
1533 1533
1534 /* 1534 /*
1535 * ACK failure register 1535 * ACK failure register
1536 */ 1536 */
1537 #define AR5K_ACK_FAIL_5210 0x8098 1537 #define AR5K_ACK_FAIL_5210 0x8098
1538 #define AR5K_ACK_FAIL_5211 0x8090 1538 #define AR5K_ACK_FAIL_5211 0x8090
1539 #define AR5K_ACK_FAIL (ah->ah_version == AR5K_AR5210 ? \ 1539 #define AR5K_ACK_FAIL (ah->ah_version == AR5K_AR5210 ? \
1540 AR5K_ACK_FAIL_5210 : AR5K_ACK_FAIL_5211) 1540 AR5K_ACK_FAIL_5210 : AR5K_ACK_FAIL_5211)
1541 1541
1542 /* 1542 /*
1543 * FCS failure register 1543 * FCS failure register
1544 */ 1544 */
1545 #define AR5K_FCS_FAIL_5210 0x809c 1545 #define AR5K_FCS_FAIL_5210 0x809c
1546 #define AR5K_FCS_FAIL_5211 0x8094 1546 #define AR5K_FCS_FAIL_5211 0x8094
1547 #define AR5K_FCS_FAIL (ah->ah_version == AR5K_AR5210 ? \ 1547 #define AR5K_FCS_FAIL (ah->ah_version == AR5K_AR5210 ? \
1548 AR5K_FCS_FAIL_5210 : AR5K_FCS_FAIL_5211) 1548 AR5K_FCS_FAIL_5210 : AR5K_FCS_FAIL_5211)
1549 1549
1550 /* 1550 /*
1551 * Beacon count register 1551 * Beacon count register
1552 */ 1552 */
1553 #define AR5K_BEACON_CNT_5210 0x80a0 1553 #define AR5K_BEACON_CNT_5210 0x80a0
1554 #define AR5K_BEACON_CNT_5211 0x8098 1554 #define AR5K_BEACON_CNT_5211 0x8098
1555 #define AR5K_BEACON_CNT (ah->ah_version == AR5K_AR5210 ? \ 1555 #define AR5K_BEACON_CNT (ah->ah_version == AR5K_AR5210 ? \
1556 AR5K_BEACON_CNT_5210 : AR5K_BEACON_CNT_5211) 1556 AR5K_BEACON_CNT_5210 : AR5K_BEACON_CNT_5211)
1557 1557
1558 1558
1559 /*===5212 Specific PCU registers===*/ 1559 /*===5212 Specific PCU registers===*/
1560 1560
1561 /* 1561 /*
1562 * Transmit power control register 1562 * Transmit power control register
1563 */ 1563 */
1564 #define AR5K_TPC 0x80e8 1564 #define AR5K_TPC 0x80e8
1565 #define AR5K_TPC_ACK 0x0000003f /* ack frames */ 1565 #define AR5K_TPC_ACK 0x0000003f /* ack frames */
1566 #define AR5K_TPC_ACK_S 0 1566 #define AR5K_TPC_ACK_S 0
1567 #define AR5K_TPC_CTS 0x00003f00 /* cts frames */ 1567 #define AR5K_TPC_CTS 0x00003f00 /* cts frames */
1568 #define AR5K_TPC_CTS_S 8 1568 #define AR5K_TPC_CTS_S 8
1569 #define AR5K_TPC_CHIRP 0x003f0000 /* chirp frames */ 1569 #define AR5K_TPC_CHIRP 0x003f0000 /* chirp frames */
1570 #define AR5K_TPC_CHIRP_S 16 1570 #define AR5K_TPC_CHIRP_S 16
1571 #define AR5K_TPC_DOPPLER 0x0f000000 /* doppler chirp span */ 1571 #define AR5K_TPC_DOPPLER 0x0f000000 /* doppler chirp span */
1572 #define AR5K_TPC_DOPPLER_S 24 1572 #define AR5K_TPC_DOPPLER_S 24
1573 1573
1574 /* 1574 /*
1575 * XR (eXtended Range) mode register 1575 * XR (eXtended Range) mode register
1576 */ 1576 */
1577 #define AR5K_XRMODE 0x80c0 /* Register Address */ 1577 #define AR5K_XRMODE 0x80c0 /* Register Address */
1578 #define AR5K_XRMODE_POLL_TYPE_M 0x0000003f /* Mask for Poll type (?) */ 1578 #define AR5K_XRMODE_POLL_TYPE_M 0x0000003f /* Mask for Poll type (?) */
1579 #define AR5K_XRMODE_POLL_TYPE_S 0 1579 #define AR5K_XRMODE_POLL_TYPE_S 0
1580 #define AR5K_XRMODE_POLL_SUBTYPE_M 0x0000003c /* Mask for Poll subtype (?) */ 1580 #define AR5K_XRMODE_POLL_SUBTYPE_M 0x0000003c /* Mask for Poll subtype (?) */
1581 #define AR5K_XRMODE_POLL_SUBTYPE_S 2 1581 #define AR5K_XRMODE_POLL_SUBTYPE_S 2
1582 #define AR5K_XRMODE_POLL_WAIT_ALL 0x00000080 /* Wait for poll */ 1582 #define AR5K_XRMODE_POLL_WAIT_ALL 0x00000080 /* Wait for poll */
1583 #define AR5K_XRMODE_SIFS_DELAY 0x000fff00 /* Mask for SIFS delay */ 1583 #define AR5K_XRMODE_SIFS_DELAY 0x000fff00 /* Mask for SIFS delay */
1584 #define AR5K_XRMODE_FRAME_HOLD_M 0xfff00000 /* Mask for frame hold (?) */ 1584 #define AR5K_XRMODE_FRAME_HOLD_M 0xfff00000 /* Mask for frame hold (?) */
1585 #define AR5K_XRMODE_FRAME_HOLD_S 20 1585 #define AR5K_XRMODE_FRAME_HOLD_S 20
1586 1586
1587 /* 1587 /*
1588 * XR delay register 1588 * XR delay register
1589 */ 1589 */
1590 #define AR5K_XRDELAY 0x80c4 /* Register Address */ 1590 #define AR5K_XRDELAY 0x80c4 /* Register Address */
1591 #define AR5K_XRDELAY_SLOT_DELAY_M 0x0000ffff /* Mask for slot delay */ 1591 #define AR5K_XRDELAY_SLOT_DELAY_M 0x0000ffff /* Mask for slot delay */
1592 #define AR5K_XRDELAY_SLOT_DELAY_S 0 1592 #define AR5K_XRDELAY_SLOT_DELAY_S 0
1593 #define AR5K_XRDELAY_CHIRP_DELAY_M 0xffff0000 /* Mask for CHIRP data delay */ 1593 #define AR5K_XRDELAY_CHIRP_DELAY_M 0xffff0000 /* Mask for CHIRP data delay */
1594 #define AR5K_XRDELAY_CHIRP_DELAY_S 16 1594 #define AR5K_XRDELAY_CHIRP_DELAY_S 16
1595 1595
1596 /* 1596 /*
1597 * XR timeout register 1597 * XR timeout register
1598 */ 1598 */
1599 #define AR5K_XRTIMEOUT 0x80c8 /* Register Address */ 1599 #define AR5K_XRTIMEOUT 0x80c8 /* Register Address */
1600 #define AR5K_XRTIMEOUT_CHIRP_M 0x0000ffff /* Mask for CHIRP timeout */ 1600 #define AR5K_XRTIMEOUT_CHIRP_M 0x0000ffff /* Mask for CHIRP timeout */
1601 #define AR5K_XRTIMEOUT_CHIRP_S 0 1601 #define AR5K_XRTIMEOUT_CHIRP_S 0
1602 #define AR5K_XRTIMEOUT_POLL_M 0xffff0000 /* Mask for Poll timeout */ 1602 #define AR5K_XRTIMEOUT_POLL_M 0xffff0000 /* Mask for Poll timeout */
1603 #define AR5K_XRTIMEOUT_POLL_S 16 1603 #define AR5K_XRTIMEOUT_POLL_S 16
1604 1604
1605 /* 1605 /*
1606 * XR chirp register 1606 * XR chirp register
1607 */ 1607 */
1608 #define AR5K_XRCHIRP 0x80cc /* Register Address */ 1608 #define AR5K_XRCHIRP 0x80cc /* Register Address */
1609 #define AR5K_XRCHIRP_SEND 0x00000001 /* Send CHIRP */ 1609 #define AR5K_XRCHIRP_SEND 0x00000001 /* Send CHIRP */
1610 #define AR5K_XRCHIRP_GAP 0xffff0000 /* Mask for CHIRP gap (?) */ 1610 #define AR5K_XRCHIRP_GAP 0xffff0000 /* Mask for CHIRP gap (?) */
1611 1611
1612 /* 1612 /*
1613 * XR stomp register 1613 * XR stomp register
1614 */ 1614 */
1615 #define AR5K_XRSTOMP 0x80d0 /* Register Address */ 1615 #define AR5K_XRSTOMP 0x80d0 /* Register Address */
1616 #define AR5K_XRSTOMP_TX 0x00000001 /* Stomp Tx (?) */ 1616 #define AR5K_XRSTOMP_TX 0x00000001 /* Stomp Tx (?) */
1617 #define AR5K_XRSTOMP_RX 0x00000002 /* Stomp Rx (?) */ 1617 #define AR5K_XRSTOMP_RX 0x00000002 /* Stomp Rx (?) */
1618 #define AR5K_XRSTOMP_TX_RSSI 0x00000004 /* Stomp Tx RSSI (?) */ 1618 #define AR5K_XRSTOMP_TX_RSSI 0x00000004 /* Stomp Tx RSSI (?) */
1619 #define AR5K_XRSTOMP_TX_BSSID 0x00000008 /* Stomp Tx BSSID (?) */ 1619 #define AR5K_XRSTOMP_TX_BSSID 0x00000008 /* Stomp Tx BSSID (?) */
1620 #define AR5K_XRSTOMP_DATA 0x00000010 /* Stomp data (?)*/ 1620 #define AR5K_XRSTOMP_DATA 0x00000010 /* Stomp data (?)*/
1621 #define AR5K_XRSTOMP_RSSI_THRES 0x0000ff00 /* Mask for XR RSSI threshold */ 1621 #define AR5K_XRSTOMP_RSSI_THRES 0x0000ff00 /* Mask for XR RSSI threshold */
1622 1622
1623 /* 1623 /*
1624 * First enhanced sleep register 1624 * First enhanced sleep register
1625 */ 1625 */
1626 #define AR5K_SLEEP0 0x80d4 /* Register Address */ 1626 #define AR5K_SLEEP0 0x80d4 /* Register Address */
1627 #define AR5K_SLEEP0_NEXT_DTIM 0x0007ffff /* Mask for next DTIM (?) */ 1627 #define AR5K_SLEEP0_NEXT_DTIM 0x0007ffff /* Mask for next DTIM (?) */
1628 #define AR5K_SLEEP0_NEXT_DTIM_S 0 1628 #define AR5K_SLEEP0_NEXT_DTIM_S 0
1629 #define AR5K_SLEEP0_ASSUME_DTIM 0x00080000 /* Assume DTIM */ 1629 #define AR5K_SLEEP0_ASSUME_DTIM 0x00080000 /* Assume DTIM */
1630 #define AR5K_SLEEP0_ENH_SLEEP_EN 0x00100000 /* Enable enchanced sleep control */ 1630 #define AR5K_SLEEP0_ENH_SLEEP_EN 0x00100000 /* Enable enchanced sleep control */
1631 #define AR5K_SLEEP0_CABTO 0xff000000 /* Mask for CAB Time Out */ 1631 #define AR5K_SLEEP0_CABTO 0xff000000 /* Mask for CAB Time Out */
1632 #define AR5K_SLEEP0_CABTO_S 24 1632 #define AR5K_SLEEP0_CABTO_S 24
1633 1633
1634 /* 1634 /*
1635 * Second enhanced sleep register 1635 * Second enhanced sleep register
1636 */ 1636 */
1637 #define AR5K_SLEEP1 0x80d8 /* Register Address */ 1637 #define AR5K_SLEEP1 0x80d8 /* Register Address */
1638 #define AR5K_SLEEP1_NEXT_TIM 0x0007ffff /* Mask for next TIM (?) */ 1638 #define AR5K_SLEEP1_NEXT_TIM 0x0007ffff /* Mask for next TIM (?) */
1639 #define AR5K_SLEEP1_NEXT_TIM_S 0 1639 #define AR5K_SLEEP1_NEXT_TIM_S 0
1640 #define AR5K_SLEEP1_BEACON_TO 0xff000000 /* Mask for Beacon Time Out */ 1640 #define AR5K_SLEEP1_BEACON_TO 0xff000000 /* Mask for Beacon Time Out */
1641 #define AR5K_SLEEP1_BEACON_TO_S 24 1641 #define AR5K_SLEEP1_BEACON_TO_S 24
1642 1642
1643 /* 1643 /*
1644 * Third enhanced sleep register 1644 * Third enhanced sleep register
1645 */ 1645 */
1646 #define AR5K_SLEEP2 0x80dc /* Register Address */ 1646 #define AR5K_SLEEP2 0x80dc /* Register Address */
1647 #define AR5K_SLEEP2_TIM_PER 0x0000ffff /* Mask for TIM period (?) */ 1647 #define AR5K_SLEEP2_TIM_PER 0x0000ffff /* Mask for TIM period (?) */
1648 #define AR5K_SLEEP2_TIM_PER_S 0 1648 #define AR5K_SLEEP2_TIM_PER_S 0
1649 #define AR5K_SLEEP2_DTIM_PER 0xffff0000 /* Mask for DTIM period (?) */ 1649 #define AR5K_SLEEP2_DTIM_PER 0xffff0000 /* Mask for DTIM period (?) */
1650 #define AR5K_SLEEP2_DTIM_PER_S 16 1650 #define AR5K_SLEEP2_DTIM_PER_S 16
1651 1651
1652 /* 1652 /*
1653 * BSSID mask registers 1653 * BSSID mask registers
1654 */ 1654 */
1655 #define AR5K_BSS_IDM0 0x80e0 /* Upper bits */ 1655 #define AR5K_BSS_IDM0 0x80e0 /* Upper bits */
1656 #define AR5K_BSS_IDM1 0x80e4 /* Lower bits */ 1656 #define AR5K_BSS_IDM1 0x80e4 /* Lower bits */
1657 1657
1658 /* 1658 /*
1659 * TX power control (TPC) register 1659 * TX power control (TPC) register
1660 * 1660 *
1661 * XXX: PCDAC steps (0.5dbm) or DBM ? 1661 * XXX: PCDAC steps (0.5dbm) or DBM ?
1662 * 1662 *
1663 */ 1663 */
1664 #define AR5K_TXPC 0x80e8 /* Register Address */ 1664 #define AR5K_TXPC 0x80e8 /* Register Address */
1665 #define AR5K_TXPC_ACK_M 0x0000003f /* ACK tx power */ 1665 #define AR5K_TXPC_ACK_M 0x0000003f /* ACK tx power */
1666 #define AR5K_TXPC_ACK_S 0 1666 #define AR5K_TXPC_ACK_S 0
1667 #define AR5K_TXPC_CTS_M 0x00003f00 /* CTS tx power */ 1667 #define AR5K_TXPC_CTS_M 0x00003f00 /* CTS tx power */
1668 #define AR5K_TXPC_CTS_S 8 1668 #define AR5K_TXPC_CTS_S 8
1669 #define AR5K_TXPC_CHIRP_M 0x003f0000 /* CHIRP tx power */ 1669 #define AR5K_TXPC_CHIRP_M 0x003f0000 /* CHIRP tx power */
1670 #define AR5K_TXPC_CHIRP_S 16 1670 #define AR5K_TXPC_CHIRP_S 16
1671 #define AR5K_TXPC_DOPPLER 0x0f000000 /* Doppler chirp span (?) */ 1671 #define AR5K_TXPC_DOPPLER 0x0f000000 /* Doppler chirp span (?) */
1672 #define AR5K_TXPC_DOPPLER_S 24 1672 #define AR5K_TXPC_DOPPLER_S 24
1673 1673
1674 /* 1674 /*
1675 * Profile count registers 1675 * Profile count registers
1676 */ 1676 */
1677 #define AR5K_PROFCNT_TX 0x80ec /* Tx count */ 1677 #define AR5K_PROFCNT_TX 0x80ec /* Tx count */
1678 #define AR5K_PROFCNT_RX 0x80f0 /* Rx count */ 1678 #define AR5K_PROFCNT_RX 0x80f0 /* Rx count */
1679 #define AR5K_PROFCNT_RXCLR 0x80f4 /* Clear Rx count */ 1679 #define AR5K_PROFCNT_RXCLR 0x80f4 /* Clear Rx count */
1680 #define AR5K_PROFCNT_CYCLE 0x80f8 /* Cycle count (?) */ 1680 #define AR5K_PROFCNT_CYCLE 0x80f8 /* Cycle count (?) */
1681 1681
1682 /* 1682 /*
1683 * Quiet period control registers 1683 * Quiet period control registers
1684 */ 1684 */
1685 #define AR5K_QUIET_CTL1 0x80fc /* Register Address */ 1685 #define AR5K_QUIET_CTL1 0x80fc /* Register Address */
1686 #define AR5K_QUIET_CTL1_NEXT_QT_TSF 0x0000ffff /* Next quiet period TSF (TU) */ 1686 #define AR5K_QUIET_CTL1_NEXT_QT_TSF 0x0000ffff /* Next quiet period TSF (TU) */
1687 #define AR5K_QUIET_CTL1_NEXT_QT_TSF_S 0 1687 #define AR5K_QUIET_CTL1_NEXT_QT_TSF_S 0
1688 #define AR5K_QUIET_CTL1_QT_EN 0x00010000 /* Enable quiet period */ 1688 #define AR5K_QUIET_CTL1_QT_EN 0x00010000 /* Enable quiet period */
1689 #define AR5K_QUIET_CTL1_ACK_CTS_EN 0x00020000 /* Send ACK/CTS during quiet period */ 1689 #define AR5K_QUIET_CTL1_ACK_CTS_EN 0x00020000 /* Send ACK/CTS during quiet period */
1690 1690
1691 #define AR5K_QUIET_CTL2 0x8100 /* Register Address */ 1691 #define AR5K_QUIET_CTL2 0x8100 /* Register Address */
1692 #define AR5K_QUIET_CTL2_QT_PER 0x0000ffff /* Mask for quiet period periodicity */ 1692 #define AR5K_QUIET_CTL2_QT_PER 0x0000ffff /* Mask for quiet period periodicity */
1693 #define AR5K_QUIET_CTL2_QT_PER_S 0 1693 #define AR5K_QUIET_CTL2_QT_PER_S 0
1694 #define AR5K_QUIET_CTL2_QT_DUR 0xffff0000 /* Mask for quiet period duration */ 1694 #define AR5K_QUIET_CTL2_QT_DUR 0xffff0000 /* Mask for quiet period duration */
1695 #define AR5K_QUIET_CTL2_QT_DUR_S 16 1695 #define AR5K_QUIET_CTL2_QT_DUR_S 16
1696 1696
1697 /* 1697 /*
1698 * TSF parameter register 1698 * TSF parameter register
1699 */ 1699 */
1700 #define AR5K_TSF_PARM 0x8104 /* Register Address */ 1700 #define AR5K_TSF_PARM 0x8104 /* Register Address */
1701 #define AR5K_TSF_PARM_INC 0x000000ff /* Mask for TSF increment */ 1701 #define AR5K_TSF_PARM_INC 0x000000ff /* Mask for TSF increment */
1702 #define AR5K_TSF_PARM_INC_S 0 1702 #define AR5K_TSF_PARM_INC_S 0
1703 1703
1704 /* 1704 /*
1705 * QoS NOACK policy 1705 * QoS NOACK policy
1706 */ 1706 */
1707 #define AR5K_QOS_NOACK 0x8108 /* Register Address */ 1707 #define AR5K_QOS_NOACK 0x8108 /* Register Address */
1708 #define AR5K_QOS_NOACK_2BIT_VALUES 0x0000000f /* ??? */ 1708 #define AR5K_QOS_NOACK_2BIT_VALUES 0x0000000f /* ??? */
1709 #define AR5K_QOS_NOACK_2BIT_VALUES_S 0 1709 #define AR5K_QOS_NOACK_2BIT_VALUES_S 0
1710 #define AR5K_QOS_NOACK_BIT_OFFSET 0x00000070 /* ??? */ 1710 #define AR5K_QOS_NOACK_BIT_OFFSET 0x00000070 /* ??? */
1711 #define AR5K_QOS_NOACK_BIT_OFFSET_S 4 1711 #define AR5K_QOS_NOACK_BIT_OFFSET_S 4
1712 #define AR5K_QOS_NOACK_BYTE_OFFSET 0x00000180 /* ??? */ 1712 #define AR5K_QOS_NOACK_BYTE_OFFSET 0x00000180 /* ??? */
1713 #define AR5K_QOS_NOACK_BYTE_OFFSET_S 7 1713 #define AR5K_QOS_NOACK_BYTE_OFFSET_S 7
1714 1714
1715 /* 1715 /*
1716 * PHY error filter register 1716 * PHY error filter register
1717 */ 1717 */
1718 #define AR5K_PHY_ERR_FIL 0x810c 1718 #define AR5K_PHY_ERR_FIL 0x810c
1719 #define AR5K_PHY_ERR_FIL_RADAR 0x00000020 /* Radar signal */ 1719 #define AR5K_PHY_ERR_FIL_RADAR 0x00000020 /* Radar signal */
1720 #define AR5K_PHY_ERR_FIL_OFDM 0x00020000 /* OFDM false detect (ANI) */ 1720 #define AR5K_PHY_ERR_FIL_OFDM 0x00020000 /* OFDM false detect (ANI) */
1721 #define AR5K_PHY_ERR_FIL_CCK 0x02000000 /* CCK false detect (ANI) */ 1721 #define AR5K_PHY_ERR_FIL_CCK 0x02000000 /* CCK false detect (ANI) */
1722 1722
1723 /* 1723 /*
1724 * XR latency register 1724 * XR latency register
1725 */ 1725 */
1726 #define AR5K_XRLAT_TX 0x8110 1726 #define AR5K_XRLAT_TX 0x8110
1727 1727
1728 /* 1728 /*
1729 * ACK SIFS register 1729 * ACK SIFS register
1730 */ 1730 */
1731 #define AR5K_ACKSIFS 0x8114 /* Register Address */ 1731 #define AR5K_ACKSIFS 0x8114 /* Register Address */
1732 #define AR5K_ACKSIFS_INC 0x00000000 /* ACK SIFS Increment (field) */ 1732 #define AR5K_ACKSIFS_INC 0x00000000 /* ACK SIFS Increment (field) */
1733 1733
1734 /* 1734 /*
1735 * MIC QoS control register (?) 1735 * MIC QoS control register (?)
1736 */ 1736 */
1737 #define AR5K_MIC_QOS_CTL 0x8118 /* Register Address */ 1737 #define AR5K_MIC_QOS_CTL 0x8118 /* Register Address */
1738 #define AR5K_MIC_QOS_CTL_OFF(_n) (1 << (_n * 2)) 1738 #define AR5K_MIC_QOS_CTL_OFF(_n) (1 << (_n * 2))
1739 #define AR5K_MIC_QOS_CTL_MQ_EN 0x00010000 /* Enable MIC QoS */ 1739 #define AR5K_MIC_QOS_CTL_MQ_EN 0x00010000 /* Enable MIC QoS */
1740 1740
1741 /* 1741 /*
1742 * MIC QoS select register (?) 1742 * MIC QoS select register (?)
1743 */ 1743 */
1744 #define AR5K_MIC_QOS_SEL 0x811c 1744 #define AR5K_MIC_QOS_SEL 0x811c
1745 #define AR5K_MIC_QOS_SEL_OFF(_n) (1 << (_n * 4)) 1745 #define AR5K_MIC_QOS_SEL_OFF(_n) (1 << (_n * 4))
1746 1746
1747 /* 1747 /*
1748 * Misc mode control register (?) 1748 * Misc mode control register (?)
1749 */ 1749 */
1750 #define AR5K_MISC_MODE 0x8120 /* Register Address */ 1750 #define AR5K_MISC_MODE 0x8120 /* Register Address */
1751 #define AR5K_MISC_MODE_FBSSID_MATCH 0x00000001 /* Force BSSID match */ 1751 #define AR5K_MISC_MODE_FBSSID_MATCH 0x00000001 /* Force BSSID match */
1752 #define AR5K_MISC_MODE_ACKSIFS_MEM 0x00000002 /* ACK SIFS memory (?) */ 1752 #define AR5K_MISC_MODE_ACKSIFS_MEM 0x00000002 /* ACK SIFS memory (?) */
1753 #define AR5K_MISC_MODE_COMBINED_MIC 0x00000004 /* use rx/tx MIC key */ 1753 #define AR5K_MISC_MODE_COMBINED_MIC 0x00000004 /* use rx/tx MIC key */
1754 /* more bits */ 1754 /* more bits */
1755 1755
1756 /* 1756 /*
1757 * OFDM Filter counter 1757 * OFDM Filter counter
1758 */ 1758 */
1759 #define AR5K_OFDM_FIL_CNT 0x8124 1759 #define AR5K_OFDM_FIL_CNT 0x8124
1760 1760
1761 /* 1761 /*
1762 * CCK Filter counter 1762 * CCK Filter counter
1763 */ 1763 */
1764 #define AR5K_CCK_FIL_CNT 0x8128 1764 #define AR5K_CCK_FIL_CNT 0x8128
1765 1765
1766 /* 1766 /*
1767 * PHY Error Counters (?) 1767 * PHY Error Counters (?)
1768 */ 1768 */
1769 #define AR5K_PHYERR_CNT1 0x812c 1769 #define AR5K_PHYERR_CNT1 0x812c
1770 #define AR5K_PHYERR_CNT1_MASK 0x8130 1770 #define AR5K_PHYERR_CNT1_MASK 0x8130
1771 1771
1772 #define AR5K_PHYERR_CNT2 0x8134 1772 #define AR5K_PHYERR_CNT2 0x8134
1773 #define AR5K_PHYERR_CNT2_MASK 0x8138 1773 #define AR5K_PHYERR_CNT2_MASK 0x8138
1774 1774
1775 /* 1775 /*
1776 * TSF Threshold register (?) 1776 * TSF Threshold register (?)
1777 */ 1777 */
1778 #define AR5K_TSF_THRES 0x813c 1778 #define AR5K_TSF_THRES 0x813c
1779 1779
1780 /* 1780 /*
1781 * TODO: Wake On Wireless registers 1781 * TODO: Wake On Wireless registers
1782 * Range: 0x8147 - 0x818c 1782 * Range: 0x8147 - 0x818c
1783 */ 1783 */
1784 1784
1785 /* 1785 /*
1786 * Rate -> ACK SIFS mapping table (32 entries) 1786 * Rate -> ACK SIFS mapping table (32 entries)
1787 */ 1787 */
1788 #define AR5K_RATE_ACKSIFS_BASE 0x8680 /* Register Address */ 1788 #define AR5K_RATE_ACKSIFS_BASE 0x8680 /* Register Address */
1789 #define AR5K_RATE_ACKSIFS(_n) (AR5K_RATE_ACKSIFS_BSE + ((_n) << 2)) 1789 #define AR5K_RATE_ACKSIFS(_n) (AR5K_RATE_ACKSIFS_BSE + ((_n) << 2))
1790 #define AR5K_RATE_ACKSIFS_NORMAL 0x00000001 /* Normal SIFS (field) */ 1790 #define AR5K_RATE_ACKSIFS_NORMAL 0x00000001 /* Normal SIFS (field) */
1791 #define AR5K_RATE_ACKSIFS_TURBO 0x00000400 /* Turbo SIFS (field) */ 1791 #define AR5K_RATE_ACKSIFS_TURBO 0x00000400 /* Turbo SIFS (field) */
1792 1792
1793 /* 1793 /*
1794 * Rate -> duration mapping table (32 entries) 1794 * Rate -> duration mapping table (32 entries)
1795 */ 1795 */
1796 #define AR5K_RATE_DUR_BASE 0x8700 1796 #define AR5K_RATE_DUR_BASE 0x8700
1797 #define AR5K_RATE_DUR(_n) (AR5K_RATE_DUR_BASE + ((_n) << 2)) 1797 #define AR5K_RATE_DUR(_n) (AR5K_RATE_DUR_BASE + ((_n) << 2))
1798 1798
1799 /* 1799 /*
1800 * Rate -> db mapping table 1800 * Rate -> db mapping table
1801 * (8 entries, each one has 4 8bit fields) 1801 * (8 entries, each one has 4 8bit fields)
1802 */ 1802 */
1803 #define AR5K_RATE2DB_BASE 0x87c0 1803 #define AR5K_RATE2DB_BASE 0x87c0
1804 #define AR5K_RATE2DB(_n) (AR5K_RATE2DB_BASE + ((_n) << 2)) 1804 #define AR5K_RATE2DB(_n) (AR5K_RATE2DB_BASE + ((_n) << 2))
1805 1805
1806 /* 1806 /*
1807 * db -> Rate mapping table 1807 * db -> Rate mapping table
1808 * (8 entries, each one has 4 8bit fields) 1808 * (8 entries, each one has 4 8bit fields)
1809 */ 1809 */
1810 #define AR5K_DB2RATE_BASE 0x87e0 1810 #define AR5K_DB2RATE_BASE 0x87e0
1811 #define AR5K_DB2RATE(_n) (AR5K_DB2RATE_BASE + ((_n) << 2)) 1811 #define AR5K_DB2RATE(_n) (AR5K_DB2RATE_BASE + ((_n) << 2))
1812 1812
1813 /*===5212 end===*/ 1813 /*===5212 end===*/
1814 1814
1815 /* 1815 /*
1816 * Key table (WEP) register 1816 * Key table (WEP) register
1817 */ 1817 */
1818 #define AR5K_KEYTABLE_0_5210 0x9000 1818 #define AR5K_KEYTABLE_0_5210 0x9000
1819 #define AR5K_KEYTABLE_0_5211 0x8800 1819 #define AR5K_KEYTABLE_0_5211 0x8800
1820 #define AR5K_KEYTABLE_5210(_n) (AR5K_KEYTABLE_0_5210 + ((_n) << 5)) 1820 #define AR5K_KEYTABLE_5210(_n) (AR5K_KEYTABLE_0_5210 + ((_n) << 5))
1821 #define AR5K_KEYTABLE_5211(_n) (AR5K_KEYTABLE_0_5211 + ((_n) << 5)) 1821 #define AR5K_KEYTABLE_5211(_n) (AR5K_KEYTABLE_0_5211 + ((_n) << 5))
1822 #define AR5K_KEYTABLE(_n) (ah->ah_version == AR5K_AR5210 ? \ 1822 #define AR5K_KEYTABLE(_n) (ah->ah_version == AR5K_AR5210 ? \
1823 AR5K_KEYTABLE_5210(_n) : AR5K_KEYTABLE_5211(_n)) 1823 AR5K_KEYTABLE_5210(_n) : AR5K_KEYTABLE_5211(_n))
1824 #define AR5K_KEYTABLE_OFF(_n, x) (AR5K_KEYTABLE(_n) + (x << 2)) 1824 #define AR5K_KEYTABLE_OFF(_n, x) (AR5K_KEYTABLE(_n) + (x << 2))
1825 #define AR5K_KEYTABLE_TYPE(_n) AR5K_KEYTABLE_OFF(_n, 5) 1825 #define AR5K_KEYTABLE_TYPE(_n) AR5K_KEYTABLE_OFF(_n, 5)
1826 #define AR5K_KEYTABLE_TYPE_40 0x00000000 1826 #define AR5K_KEYTABLE_TYPE_40 0x00000000
1827 #define AR5K_KEYTABLE_TYPE_104 0x00000001 1827 #define AR5K_KEYTABLE_TYPE_104 0x00000001
1828 #define AR5K_KEYTABLE_TYPE_128 0x00000003 1828 #define AR5K_KEYTABLE_TYPE_128 0x00000003
1829 #define AR5K_KEYTABLE_TYPE_TKIP 0x00000004 /* [5212+] */ 1829 #define AR5K_KEYTABLE_TYPE_TKIP 0x00000004 /* [5212+] */
1830 #define AR5K_KEYTABLE_TYPE_AES 0x00000005 /* [5211+] */ 1830 #define AR5K_KEYTABLE_TYPE_AES 0x00000005 /* [5211+] */
1831 #define AR5K_KEYTABLE_TYPE_CCM 0x00000006 /* [5212+] */ 1831 #define AR5K_KEYTABLE_TYPE_CCM 0x00000006 /* [5212+] */
1832 #define AR5K_KEYTABLE_TYPE_NULL 0x00000007 /* [5211+] */ 1832 #define AR5K_KEYTABLE_TYPE_NULL 0x00000007 /* [5211+] */
1833 #define AR5K_KEYTABLE_ANTENNA 0x00000008 /* [5212+] */ 1833 #define AR5K_KEYTABLE_ANTENNA 0x00000008 /* [5212+] */
1834 #define AR5K_KEYTABLE_MAC0(_n) AR5K_KEYTABLE_OFF(_n, 6) 1834 #define AR5K_KEYTABLE_MAC0(_n) AR5K_KEYTABLE_OFF(_n, 6)
1835 #define AR5K_KEYTABLE_MAC1(_n) AR5K_KEYTABLE_OFF(_n, 7) 1835 #define AR5K_KEYTABLE_MAC1(_n) AR5K_KEYTABLE_OFF(_n, 7)
1836 #define AR5K_KEYTABLE_VALID 0x00008000 1836 #define AR5K_KEYTABLE_VALID 0x00008000
1837 1837
1838 /* If key type is TKIP and MIC is enabled 1838 /* If key type is TKIP and MIC is enabled
1839 * MIC key goes in offset entry + 64 */ 1839 * MIC key goes in offset entry + 64 */
1840 #define AR5K_KEYTABLE_MIC_OFFSET 64 1840 #define AR5K_KEYTABLE_MIC_OFFSET 64
1841 1841
1842 /* WEP 40-bit = 40-bit entered key + 24 bit IV = 64-bit 1842 /* WEP 40-bit = 40-bit entered key + 24 bit IV = 64-bit
1843 * WEP 104-bit = 104-bit entered key + 24-bit IV = 128-bit 1843 * WEP 104-bit = 104-bit entered key + 24-bit IV = 128-bit
1844 * WEP 128-bit = 128-bit entered key + 24 bit IV = 152-bit 1844 * WEP 128-bit = 128-bit entered key + 24 bit IV = 152-bit
1845 * 1845 *
1846 * Some vendors have introduced bigger WEP keys to address 1846 * Some vendors have introduced bigger WEP keys to address
1847 * security vulnerabilities in WEP. This includes: 1847 * security vulnerabilities in WEP. This includes:
1848 * 1848 *
1849 * WEP 232-bit = 232-bit entered key + 24 bit IV = 256-bit 1849 * WEP 232-bit = 232-bit entered key + 24 bit IV = 256-bit
1850 * 1850 *
1851 * We can expand this if we find ar5k Atheros cards with a larger 1851 * We can expand this if we find ar5k Atheros cards with a larger
1852 * key table size. 1852 * key table size.
1853 */ 1853 */
1854 #define AR5K_KEYTABLE_SIZE_5210 64 1854 #define AR5K_KEYTABLE_SIZE_5210 64
1855 #define AR5K_KEYTABLE_SIZE_5211 128 1855 #define AR5K_KEYTABLE_SIZE_5211 128
1856 #define AR5K_KEYTABLE_SIZE (ah->ah_version == AR5K_AR5210 ? \ 1856 #define AR5K_KEYTABLE_SIZE (ah->ah_version == AR5K_AR5210 ? \
1857 AR5K_KEYTABLE_SIZE_5210 : AR5K_KEYTABLE_SIZE_5211) 1857 AR5K_KEYTABLE_SIZE_5210 : AR5K_KEYTABLE_SIZE_5211)
1858 1858
1859 1859
1860 /*===PHY REGISTERS===*/ 1860 /*===PHY REGISTERS===*/
1861 1861
1862 /* 1862 /*
1863 * PHY registers start 1863 * PHY registers start
1864 */ 1864 */
1865 #define AR5K_PHY_BASE 0x9800 1865 #define AR5K_PHY_BASE 0x9800
1866 #define AR5K_PHY(_n) (AR5K_PHY_BASE + ((_n) << 2)) 1866 #define AR5K_PHY(_n) (AR5K_PHY_BASE + ((_n) << 2))
1867 1867
1868 /* 1868 /*
1869 * TST_2 (Misc config parameters) 1869 * TST_2 (Misc config parameters)
1870 */ 1870 */
1871 #define AR5K_PHY_TST2 0x9800 /* Register Address */ 1871 #define AR5K_PHY_TST2 0x9800 /* Register Address */
1872 #define AR5K_PHY_TST2_TRIG_SEL 0x00000007 /* Trigger select (?)*/ 1872 #define AR5K_PHY_TST2_TRIG_SEL 0x00000007 /* Trigger select (?)*/
1873 #define AR5K_PHY_TST2_TRIG 0x00000010 /* Trigger (?) */ 1873 #define AR5K_PHY_TST2_TRIG 0x00000010 /* Trigger (?) */
1874 #define AR5K_PHY_TST2_CBUS_MODE 0x00000060 /* Cardbus mode (?) */ 1874 #define AR5K_PHY_TST2_CBUS_MODE 0x00000060 /* Cardbus mode (?) */
1875 #define AR5K_PHY_TST2_CLK32 0x00000400 /* CLK_OUT is CLK32 (32Khz external) */ 1875 #define AR5K_PHY_TST2_CLK32 0x00000400 /* CLK_OUT is CLK32 (32Khz external) */
1876 #define AR5K_PHY_TST2_CHANCOR_DUMP_EN 0x00000800 /* Enable Chancor dump (?) */ 1876 #define AR5K_PHY_TST2_CHANCOR_DUMP_EN 0x00000800 /* Enable Chancor dump (?) */
1877 #define AR5K_PHY_TST2_EVEN_CHANCOR_DUMP 0x00001000 /* Even Chancor dump (?) */ 1877 #define AR5K_PHY_TST2_EVEN_CHANCOR_DUMP 0x00001000 /* Even Chancor dump (?) */
1878 #define AR5K_PHY_TST2_RFSILENT_EN 0x00002000 /* Enable RFSILENT */ 1878 #define AR5K_PHY_TST2_RFSILENT_EN 0x00002000 /* Enable RFSILENT */
1879 #define AR5K_PHY_TST2_ALT_RFDATA 0x00004000 /* Alternate RFDATA (5-2GHz switch ?) */ 1879 #define AR5K_PHY_TST2_ALT_RFDATA 0x00004000 /* Alternate RFDATA (5-2GHz switch ?) */
1880 #define AR5K_PHY_TST2_MINI_OBS_EN 0x00008000 /* Enable mini OBS (?) */ 1880 #define AR5K_PHY_TST2_MINI_OBS_EN 0x00008000 /* Enable mini OBS (?) */
1881 #define AR5K_PHY_TST2_RX2_IS_RX5_INV 0x00010000 /* 2GHz rx path is the 5GHz path inverted (?) */ 1881 #define AR5K_PHY_TST2_RX2_IS_RX5_INV 0x00010000 /* 2GHz rx path is the 5GHz path inverted (?) */
1882 #define AR5K_PHY_TST2_SLOW_CLK160 0x00020000 /* Slow CLK160 (?) */ 1882 #define AR5K_PHY_TST2_SLOW_CLK160 0x00020000 /* Slow CLK160 (?) */
1883 #define AR5K_PHY_TST2_AGC_OBS_SEL_3 0x00040000 /* AGC OBS Select 3 (?) */ 1883 #define AR5K_PHY_TST2_AGC_OBS_SEL_3 0x00040000 /* AGC OBS Select 3 (?) */
1884 #define AR5K_PHY_TST2_BBB_OBS_SEL 0x00080000 /* BB OBS Select (field ?) */ 1884 #define AR5K_PHY_TST2_BBB_OBS_SEL 0x00080000 /* BB OBS Select (field ?) */
1885 #define AR5K_PHY_TST2_ADC_OBS_SEL 0x00800000 /* ADC OBS Select (field ?) */ 1885 #define AR5K_PHY_TST2_ADC_OBS_SEL 0x00800000 /* ADC OBS Select (field ?) */
1886 #define AR5K_PHY_TST2_RX_CLR_SEL 0x08000000 /* RX Clear Select (?) */ 1886 #define AR5K_PHY_TST2_RX_CLR_SEL 0x08000000 /* RX Clear Select (?) */
1887 #define AR5K_PHY_TST2_FORCE_AGC_CLR 0x10000000 /* Force AGC clear (?) */ 1887 #define AR5K_PHY_TST2_FORCE_AGC_CLR 0x10000000 /* Force AGC clear (?) */
1888 #define AR5K_PHY_SHIFT_2GHZ 0x00004007 /* Used to access 2GHz radios */ 1888 #define AR5K_PHY_SHIFT_2GHZ 0x00004007 /* Used to access 2GHz radios */
1889 #define AR5K_PHY_SHIFT_5GHZ 0x00000007 /* Used to access 5GHz radios (default) */ 1889 #define AR5K_PHY_SHIFT_5GHZ 0x00000007 /* Used to access 5GHz radios (default) */
1890 1890
1891 /* 1891 /*
1892 * PHY frame control register [5110] /turbo mode register [5111+] 1892 * PHY frame control register [5110] /turbo mode register [5111+]
1893 * 1893 *
1894 * There is another frame control register for [5111+] 1894 * There is another frame control register for [5111+]
1895 * at address 0x9944 (see below) but the 2 first flags 1895 * at address 0x9944 (see below) but the 2 first flags
1896 * are common here between 5110 frame control register 1896 * are common here between 5110 frame control register
1897 * and [5111+] turbo mode register, so this also works as 1897 * and [5111+] turbo mode register, so this also works as
1898 * a "turbo mode register" for 5110. We treat this one as 1898 * a "turbo mode register" for 5110. We treat this one as
1899 * a frame control register for 5110 below. 1899 * a frame control register for 5110 below.
1900 */ 1900 */
1901 #define AR5K_PHY_TURBO 0x9804 /* Register Address */ 1901 #define AR5K_PHY_TURBO 0x9804 /* Register Address */
1902 #define AR5K_PHY_TURBO_MODE 0x00000001 /* Enable turbo mode */ 1902 #define AR5K_PHY_TURBO_MODE 0x00000001 /* Enable turbo mode */
1903 #define AR5K_PHY_TURBO_SHORT 0x00000002 /* Set short symbols to turbo mode */ 1903 #define AR5K_PHY_TURBO_SHORT 0x00000002 /* Set short symbols to turbo mode */
1904 #define AR5K_PHY_TURBO_MIMO 0x00000004 /* Set turbo for mimo mimo */ 1904 #define AR5K_PHY_TURBO_MIMO 0x00000004 /* Set turbo for mimo mimo */
1905 1905
1906 /* 1906 /*
1907 * PHY agility command register 1907 * PHY agility command register
1908 * (aka TST_1) 1908 * (aka TST_1)
1909 */ 1909 */
1910 #define AR5K_PHY_AGC 0x9808 /* Register Address */ 1910 #define AR5K_PHY_AGC 0x9808 /* Register Address */
1911 #define AR5K_PHY_TST1 0x9808 1911 #define AR5K_PHY_TST1 0x9808
1912 #define AR5K_PHY_AGC_DISABLE 0x08000000 /* Disable AGC to A2 (?)*/ 1912 #define AR5K_PHY_AGC_DISABLE 0x08000000 /* Disable AGC to A2 (?)*/
1913 #define AR5K_PHY_TST1_TXHOLD 0x00003800 /* Set tx hold (?) */ 1913 #define AR5K_PHY_TST1_TXHOLD 0x00003800 /* Set tx hold (?) */
1914 #define AR5K_PHY_TST1_TXSRC_SRC 0x00000002 /* Used with bit 7 (?) */ 1914 #define AR5K_PHY_TST1_TXSRC_SRC 0x00000002 /* Used with bit 7 (?) */
1915 #define AR5K_PHY_TST1_TXSRC_SRC_S 1 1915 #define AR5K_PHY_TST1_TXSRC_SRC_S 1
1916 #define AR5K_PHY_TST1_TXSRC_ALT 0x00000080 /* Set input to tsdac (?) */ 1916 #define AR5K_PHY_TST1_TXSRC_ALT 0x00000080 /* Set input to tsdac (?) */
1917 #define AR5K_PHY_TST1_TXSRC_ALT_S 7 1917 #define AR5K_PHY_TST1_TXSRC_ALT_S 7
1918 1918
1919 1919
1920 /* 1920 /*
1921 * PHY timing register 3 [5112+] 1921 * PHY timing register 3 [5112+]
1922 */ 1922 */
1923 #define AR5K_PHY_TIMING_3 0x9814 1923 #define AR5K_PHY_TIMING_3 0x9814
1924 #define AR5K_PHY_TIMING_3_DSC_MAN 0xfffe0000 1924 #define AR5K_PHY_TIMING_3_DSC_MAN 0xfffe0000
1925 #define AR5K_PHY_TIMING_3_DSC_MAN_S 17 1925 #define AR5K_PHY_TIMING_3_DSC_MAN_S 17
1926 #define AR5K_PHY_TIMING_3_DSC_EXP 0x0001e000 1926 #define AR5K_PHY_TIMING_3_DSC_EXP 0x0001e000
1927 #define AR5K_PHY_TIMING_3_DSC_EXP_S 13 1927 #define AR5K_PHY_TIMING_3_DSC_EXP_S 13
1928 1928
1929 /* 1929 /*
1930 * PHY chip revision register 1930 * PHY chip revision register
1931 */ 1931 */
1932 #define AR5K_PHY_CHIP_ID 0x9818 1932 #define AR5K_PHY_CHIP_ID 0x9818
1933 1933
1934 /* 1934 /*
1935 * PHY activation register 1935 * PHY activation register
1936 */ 1936 */
1937 #define AR5K_PHY_ACT 0x981c /* Register Address */ 1937 #define AR5K_PHY_ACT 0x981c /* Register Address */
1938 #define AR5K_PHY_ACT_ENABLE 0x00000001 /* Activate PHY */ 1938 #define AR5K_PHY_ACT_ENABLE 0x00000001 /* Activate PHY */
1939 #define AR5K_PHY_ACT_DISABLE 0x00000002 /* Deactivate PHY */ 1939 #define AR5K_PHY_ACT_DISABLE 0x00000002 /* Deactivate PHY */
1940 1940
1941 /* 1941 /*
1942 * PHY RF control registers 1942 * PHY RF control registers
1943 */ 1943 */
1944 #define AR5K_PHY_RF_CTL2 0x9824 /* Register Address */ 1944 #define AR5K_PHY_RF_CTL2 0x9824 /* Register Address */
1945 #define AR5K_PHY_RF_CTL2_TXF2TXD_START 0x0000000f /* TX frame to TX data start */ 1945 #define AR5K_PHY_RF_CTL2_TXF2TXD_START 0x0000000f /* TX frame to TX data start */
1946 #define AR5K_PHY_RF_CTL2_TXF2TXD_START_S 0 1946 #define AR5K_PHY_RF_CTL2_TXF2TXD_START_S 0
1947 1947
1948 #define AR5K_PHY_RF_CTL3 0x9828 /* Register Address */ 1948 #define AR5K_PHY_RF_CTL3 0x9828 /* Register Address */
1949 #define AR5K_PHY_RF_CTL3_TXE2XLNA_ON 0x0000ff00 /* TX end to XLNA on */ 1949 #define AR5K_PHY_RF_CTL3_TXE2XLNA_ON 0x0000ff00 /* TX end to XLNA on */
1950 #define AR5K_PHY_RF_CTL3_TXE2XLNA_ON_S 8 1950 #define AR5K_PHY_RF_CTL3_TXE2XLNA_ON_S 8
1951 1951
1952 #define AR5K_PHY_ADC_CTL 0x982c 1952 #define AR5K_PHY_ADC_CTL 0x982c
1953 #define AR5K_PHY_ADC_CTL_INBUFGAIN_OFF 0x00000003 1953 #define AR5K_PHY_ADC_CTL_INBUFGAIN_OFF 0x00000003
1954 #define AR5K_PHY_ADC_CTL_INBUFGAIN_OFF_S 0 1954 #define AR5K_PHY_ADC_CTL_INBUFGAIN_OFF_S 0
1955 #define AR5K_PHY_ADC_CTL_PWD_DAC_OFF 0x00002000 1955 #define AR5K_PHY_ADC_CTL_PWD_DAC_OFF 0x00002000
1956 #define AR5K_PHY_ADC_CTL_PWD_BAND_GAP_OFF 0x00004000 1956 #define AR5K_PHY_ADC_CTL_PWD_BAND_GAP_OFF 0x00004000
1957 #define AR5K_PHY_ADC_CTL_PWD_ADC_OFF 0x00008000 1957 #define AR5K_PHY_ADC_CTL_PWD_ADC_OFF 0x00008000
1958 #define AR5K_PHY_ADC_CTL_INBUFGAIN_ON 0x00030000 1958 #define AR5K_PHY_ADC_CTL_INBUFGAIN_ON 0x00030000
1959 #define AR5K_PHY_ADC_CTL_INBUFGAIN_ON_S 16 1959 #define AR5K_PHY_ADC_CTL_INBUFGAIN_ON_S 16
1960 1960
1961 #define AR5K_PHY_RF_CTL4 0x9834 /* Register Address */ 1961 #define AR5K_PHY_RF_CTL4 0x9834 /* Register Address */
1962 #define AR5K_PHY_RF_CTL4_TXF2XPA_A_ON 0x00000001 /* TX frame to XPA A on (field) */ 1962 #define AR5K_PHY_RF_CTL4_TXF2XPA_A_ON 0x00000001 /* TX frame to XPA A on (field) */
1963 #define AR5K_PHY_RF_CTL4_TXF2XPA_B_ON 0x00000100 /* TX frame to XPA B on (field) */ 1963 #define AR5K_PHY_RF_CTL4_TXF2XPA_B_ON 0x00000100 /* TX frame to XPA B on (field) */
1964 #define AR5K_PHY_RF_CTL4_TXE2XPA_A_OFF 0x00010000 /* TX end to XPA A off (field) */ 1964 #define AR5K_PHY_RF_CTL4_TXE2XPA_A_OFF 0x00010000 /* TX end to XPA A off (field) */
1965 #define AR5K_PHY_RF_CTL4_TXE2XPA_B_OFF 0x01000000 /* TX end to XPA B off (field) */ 1965 #define AR5K_PHY_RF_CTL4_TXE2XPA_B_OFF 0x01000000 /* TX end to XPA B off (field) */
1966 1966
1967 /* 1967 /*
1968 * Pre-Amplifier control register 1968 * Pre-Amplifier control register
1969 * (XPA -> external pre-amplifier) 1969 * (XPA -> external pre-amplifier)
1970 */ 1970 */
1971 #define AR5K_PHY_PA_CTL 0x9838 /* Register Address */ 1971 #define AR5K_PHY_PA_CTL 0x9838 /* Register Address */
1972 #define AR5K_PHY_PA_CTL_XPA_A_HI 0x00000001 /* XPA A high (?) */ 1972 #define AR5K_PHY_PA_CTL_XPA_A_HI 0x00000001 /* XPA A high (?) */
1973 #define AR5K_PHY_PA_CTL_XPA_B_HI 0x00000002 /* XPA B high (?) */ 1973 #define AR5K_PHY_PA_CTL_XPA_B_HI 0x00000002 /* XPA B high (?) */
1974 #define AR5K_PHY_PA_CTL_XPA_A_EN 0x00000004 /* Enable XPA A */ 1974 #define AR5K_PHY_PA_CTL_XPA_A_EN 0x00000004 /* Enable XPA A */
1975 #define AR5K_PHY_PA_CTL_XPA_B_EN 0x00000008 /* Enable XPA B */ 1975 #define AR5K_PHY_PA_CTL_XPA_B_EN 0x00000008 /* Enable XPA B */
1976 1976
1977 /* 1977 /*
1978 * PHY settling register 1978 * PHY settling register
1979 */ 1979 */
1980 #define AR5K_PHY_SETTLING 0x9844 /* Register Address */ 1980 #define AR5K_PHY_SETTLING 0x9844 /* Register Address */
1981 #define AR5K_PHY_SETTLING_AGC 0x0000007f /* AGC settling time */ 1981 #define AR5K_PHY_SETTLING_AGC 0x0000007f /* AGC settling time */
1982 #define AR5K_PHY_SETTLING_AGC_S 0 1982 #define AR5K_PHY_SETTLING_AGC_S 0
1983 #define AR5K_PHY_SETTLING_SWITCH 0x00003f80 /* Switch settlig time */ 1983 #define AR5K_PHY_SETTLING_SWITCH 0x00003f80 /* Switch settlig time */
1984 #define AR5K_PHY_SETTLING_SWITCH_S 7 1984 #define AR5K_PHY_SETTLING_SWITCH_S 7
1985 1985
1986 /* 1986 /*
1987 * PHY Gain registers 1987 * PHY Gain registers
1988 */ 1988 */
1989 #define AR5K_PHY_GAIN 0x9848 /* Register Address */ 1989 #define AR5K_PHY_GAIN 0x9848 /* Register Address */
1990 #define AR5K_PHY_GAIN_TXRX_ATTEN 0x0003f000 /* TX-RX Attenuation */ 1990 #define AR5K_PHY_GAIN_TXRX_ATTEN 0x0003f000 /* TX-RX Attenuation */
1991 #define AR5K_PHY_GAIN_TXRX_ATTEN_S 12 1991 #define AR5K_PHY_GAIN_TXRX_ATTEN_S 12
1992 #define AR5K_PHY_GAIN_TXRX_RF_MAX 0x007c0000 1992 #define AR5K_PHY_GAIN_TXRX_RF_MAX 0x007c0000
1993 #define AR5K_PHY_GAIN_TXRX_RF_MAX_S 18 1993 #define AR5K_PHY_GAIN_TXRX_RF_MAX_S 18
1994 1994
1995 #define AR5K_PHY_GAIN_OFFSET 0x984c /* Register Address */ 1995 #define AR5K_PHY_GAIN_OFFSET 0x984c /* Register Address */
1996 #define AR5K_PHY_GAIN_OFFSET_RXTX_FLAG 0x00020000 /* RX-TX flag (?) */ 1996 #define AR5K_PHY_GAIN_OFFSET_RXTX_FLAG 0x00020000 /* RX-TX flag (?) */
1997 1997
1998 /* 1998 /*
1999 * Desired ADC/PGA size register 1999 * Desired ADC/PGA size register
2000 * (for more infos read ANI patent) 2000 * (for more infos read ANI patent)
2001 */ 2001 */
2002 #define AR5K_PHY_DESIRED_SIZE 0x9850 /* Register Address */ 2002 #define AR5K_PHY_DESIRED_SIZE 0x9850 /* Register Address */
2003 #define AR5K_PHY_DESIRED_SIZE_ADC 0x000000ff /* ADC desired size */ 2003 #define AR5K_PHY_DESIRED_SIZE_ADC 0x000000ff /* ADC desired size */
2004 #define AR5K_PHY_DESIRED_SIZE_ADC_S 0 2004 #define AR5K_PHY_DESIRED_SIZE_ADC_S 0
2005 #define AR5K_PHY_DESIRED_SIZE_PGA 0x0000ff00 /* PGA desired size */ 2005 #define AR5K_PHY_DESIRED_SIZE_PGA 0x0000ff00 /* PGA desired size */
2006 #define AR5K_PHY_DESIRED_SIZE_PGA_S 8 2006 #define AR5K_PHY_DESIRED_SIZE_PGA_S 8
2007 #define AR5K_PHY_DESIRED_SIZE_TOT 0x0ff00000 /* Total desired size */ 2007 #define AR5K_PHY_DESIRED_SIZE_TOT 0x0ff00000 /* Total desired size */
2008 #define AR5K_PHY_DESIRED_SIZE_TOT_S 20 2008 #define AR5K_PHY_DESIRED_SIZE_TOT_S 20
2009 2009
2010 /* 2010 /*
2011 * PHY signal register 2011 * PHY signal register
2012 * (for more infos read ANI patent) 2012 * (for more infos read ANI patent)
2013 */ 2013 */
2014 #define AR5K_PHY_SIG 0x9858 /* Register Address */ 2014 #define AR5K_PHY_SIG 0x9858 /* Register Address */
2015 #define AR5K_PHY_SIG_FIRSTEP 0x0003f000 /* FIRSTEP */ 2015 #define AR5K_PHY_SIG_FIRSTEP 0x0003f000 /* FIRSTEP */
2016 #define AR5K_PHY_SIG_FIRSTEP_S 12 2016 #define AR5K_PHY_SIG_FIRSTEP_S 12
2017 #define AR5K_PHY_SIG_FIRPWR 0x03fc0000 /* FIPWR */ 2017 #define AR5K_PHY_SIG_FIRPWR 0x03fc0000 /* FIPWR */
2018 #define AR5K_PHY_SIG_FIRPWR_S 18 2018 #define AR5K_PHY_SIG_FIRPWR_S 18
2019 2019
2020 /* 2020 /*
2021 * PHY coarse agility control register 2021 * PHY coarse agility control register
2022 * (for more infos read ANI patent) 2022 * (for more infos read ANI patent)
2023 */ 2023 */
2024 #define AR5K_PHY_AGCCOARSE 0x985c /* Register Address */ 2024 #define AR5K_PHY_AGCCOARSE 0x985c /* Register Address */
2025 #define AR5K_PHY_AGCCOARSE_LO 0x00007f80 /* AGC Coarse low */ 2025 #define AR5K_PHY_AGCCOARSE_LO 0x00007f80 /* AGC Coarse low */
2026 #define AR5K_PHY_AGCCOARSE_LO_S 7 2026 #define AR5K_PHY_AGCCOARSE_LO_S 7
2027 #define AR5K_PHY_AGCCOARSE_HI 0x003f8000 /* AGC Coarse high */ 2027 #define AR5K_PHY_AGCCOARSE_HI 0x003f8000 /* AGC Coarse high */
2028 #define AR5K_PHY_AGCCOARSE_HI_S 15 2028 #define AR5K_PHY_AGCCOARSE_HI_S 15
2029 2029
2030 /* 2030 /*
2031 * PHY agility control register 2031 * PHY agility control register
2032 */ 2032 */
2033 #define AR5K_PHY_AGCCTL 0x9860 /* Register address */ 2033 #define AR5K_PHY_AGCCTL 0x9860 /* Register address */
2034 #define AR5K_PHY_AGCCTL_CAL 0x00000001 /* Enable PHY calibration */ 2034 #define AR5K_PHY_AGCCTL_CAL 0x00000001 /* Enable PHY calibration */
2035 #define AR5K_PHY_AGCCTL_NF 0x00000002 /* Enable Noise Floor calibration */ 2035 #define AR5K_PHY_AGCCTL_NF 0x00000002 /* Enable Noise Floor calibration */
2036 #define AR5K_PHY_AGCCTL_OFDM_DIV_DIS 0x00000008 /* Disable antenna diversity on OFDM modes */ 2036 #define AR5K_PHY_AGCCTL_OFDM_DIV_DIS 0x00000008 /* Disable antenna diversity on OFDM modes */
2037 #define AR5K_PHY_AGCCTL_NF_EN 0x00008000 /* Enable nf calibration to happen (?) */ 2037 #define AR5K_PHY_AGCCTL_NF_EN 0x00008000 /* Enable nf calibration to happen (?) */
2038 #define AR5K_PHY_AGCTL_FLTR_CAL 0x00010000 /* Allow filter calibration (?) */ 2038 #define AR5K_PHY_AGCTL_FLTR_CAL 0x00010000 /* Allow filter calibration (?) */
2039 #define AR5K_PHY_AGCCTL_NF_NOUPDATE 0x00020000 /* Don't update nf automaticaly */ 2039 #define AR5K_PHY_AGCCTL_NF_NOUPDATE 0x00020000 /* Don't update nf automaticaly */
2040 2040
2041 /* 2041 /*
2042 * PHY noise floor status register 2042 * PHY noise floor status register
2043 */ 2043 */
2044 #define AR5K_PHY_NF 0x9864 /* Register address */ 2044 #define AR5K_PHY_NF 0x9864 /* Register address */
2045 #define AR5K_PHY_NF_M 0x000001ff /* Noise floor mask */ 2045 #define AR5K_PHY_NF_M 0x000001ff /* Noise floor mask */
2046 #define AR5K_PHY_NF_ACTIVE 0x00000100 /* Noise floor calibration still active */ 2046 #define AR5K_PHY_NF_ACTIVE 0x00000100 /* Noise floor calibration still active */
2047 #define AR5K_PHY_NF_RVAL(_n) (((_n) >> 19) & AR5K_PHY_NF_M) 2047 #define AR5K_PHY_NF_RVAL(_n) (((_n) >> 19) & AR5K_PHY_NF_M)
2048 #define AR5K_PHY_NF_AVAL(_n) (-((_n) ^ AR5K_PHY_NF_M) + 1) 2048 #define AR5K_PHY_NF_AVAL(_n) (-((_n) ^ AR5K_PHY_NF_M) + 1)
2049 #define AR5K_PHY_NF_SVAL(_n) (((_n) & AR5K_PHY_NF_M) | (1 << 9)) 2049 #define AR5K_PHY_NF_SVAL(_n) (((_n) & AR5K_PHY_NF_M) | (1 << 9))
2050 #define AR5K_PHY_NF_THRESH62 0x0007f000 /* Thresh62 -check ANI patent- (field) */ 2050 #define AR5K_PHY_NF_THRESH62 0x0007f000 /* Thresh62 -check ANI patent- (field) */
2051 #define AR5K_PHY_NF_THRESH62_S 12 2051 #define AR5K_PHY_NF_THRESH62_S 12
2052 #define AR5K_PHY_NF_MINCCA_PWR 0x0ff80000 /* ??? */ 2052 #define AR5K_PHY_NF_MINCCA_PWR 0x0ff80000 /* ??? */
2053 #define AR5K_PHY_NF_MINCCA_PWR_S 19 2053 #define AR5K_PHY_NF_MINCCA_PWR_S 19
2054 2054
2055 /* 2055 /*
2056 * PHY ADC saturation register [5110] 2056 * PHY ADC saturation register [5110]
2057 */ 2057 */
2058 #define AR5K_PHY_ADCSAT 0x9868 2058 #define AR5K_PHY_ADCSAT 0x9868
2059 #define AR5K_PHY_ADCSAT_ICNT 0x0001f800 2059 #define AR5K_PHY_ADCSAT_ICNT 0x0001f800
2060 #define AR5K_PHY_ADCSAT_ICNT_S 11 2060 #define AR5K_PHY_ADCSAT_ICNT_S 11
2061 #define AR5K_PHY_ADCSAT_THR 0x000007e0 2061 #define AR5K_PHY_ADCSAT_THR 0x000007e0
2062 #define AR5K_PHY_ADCSAT_THR_S 5 2062 #define AR5K_PHY_ADCSAT_THR_S 5
2063 2063
2064 /* 2064 /*
2065 * PHY Weak ofdm signal detection threshold registers (ANI) [5212+] 2065 * PHY Weak ofdm signal detection threshold registers (ANI) [5212+]
2066 */ 2066 */
2067 2067
2068 /* High thresholds */ 2068 /* High thresholds */
2069 #define AR5K_PHY_WEAK_OFDM_HIGH_THR 0x9868 2069 #define AR5K_PHY_WEAK_OFDM_HIGH_THR 0x9868
2070 #define AR5K_PHY_WEAK_OFDM_HIGH_THR_M2_COUNT 0x0000001f 2070 #define AR5K_PHY_WEAK_OFDM_HIGH_THR_M2_COUNT 0x0000001f
2071 #define AR5K_PHY_WEAK_OFDM_HIGH_THR_M2_COUNT_S 0 2071 #define AR5K_PHY_WEAK_OFDM_HIGH_THR_M2_COUNT_S 0
2072 #define AR5K_PHY_WEAK_OFDM_HIGH_THR_M1 0x00fe0000 2072 #define AR5K_PHY_WEAK_OFDM_HIGH_THR_M1 0x00fe0000
2073 #define AR5K_PHY_WEAK_OFDM_HIGH_THR_M1_S 17 2073 #define AR5K_PHY_WEAK_OFDM_HIGH_THR_M1_S 17
2074 #define AR5K_PHY_WEAK_OFDM_HIGH_THR_M2 0x7f000000 2074 #define AR5K_PHY_WEAK_OFDM_HIGH_THR_M2 0x7f000000
2075 #define AR5K_PHY_WEAK_OFDM_HIGH_THR_M2_S 24 2075 #define AR5K_PHY_WEAK_OFDM_HIGH_THR_M2_S 24
2076 2076
2077 /* Low thresholds */ 2077 /* Low thresholds */
2078 #define AR5K_PHY_WEAK_OFDM_LOW_THR 0x986c 2078 #define AR5K_PHY_WEAK_OFDM_LOW_THR 0x986c
2079 #define AR5K_PHY_WEAK_OFDM_LOW_THR_SELFCOR_EN 0x00000001 2079 #define AR5K_PHY_WEAK_OFDM_LOW_THR_SELFCOR_EN 0x00000001
2080 #define AR5K_PHY_WEAK_OFDM_LOW_THR_M2_COUNT 0x00003f00 2080 #define AR5K_PHY_WEAK_OFDM_LOW_THR_M2_COUNT 0x00003f00
2081 #define AR5K_PHY_WEAK_OFDM_LOW_THR_M2_COUNT_S 8 2081 #define AR5K_PHY_WEAK_OFDM_LOW_THR_M2_COUNT_S 8
2082 #define AR5K_PHY_WEAK_OFDM_LOW_THR_M1 0x001fc000 2082 #define AR5K_PHY_WEAK_OFDM_LOW_THR_M1 0x001fc000
2083 #define AR5K_PHY_WEAK_OFDM_LOW_THR_M1_S 14 2083 #define AR5K_PHY_WEAK_OFDM_LOW_THR_M1_S 14
2084 #define AR5K_PHY_WEAK_OFDM_LOW_THR_M2 0x0fe00000 2084 #define AR5K_PHY_WEAK_OFDM_LOW_THR_M2 0x0fe00000
2085 #define AR5K_PHY_WEAK_OFDM_LOW_THR_M2_S 21 2085 #define AR5K_PHY_WEAK_OFDM_LOW_THR_M2_S 21
2086 2086
2087 2087
2088 /* 2088 /*
2089 * PHY sleep registers [5112+] 2089 * PHY sleep registers [5112+]
2090 */ 2090 */
2091 #define AR5K_PHY_SCR 0x9870 2091 #define AR5K_PHY_SCR 0x9870
2092 2092
2093 #define AR5K_PHY_SLMT 0x9874 2093 #define AR5K_PHY_SLMT 0x9874
2094 #define AR5K_PHY_SLMT_32MHZ 0x0000007f 2094 #define AR5K_PHY_SLMT_32MHZ 0x0000007f
2095 2095
2096 #define AR5K_PHY_SCAL 0x9878 2096 #define AR5K_PHY_SCAL 0x9878
2097 #define AR5K_PHY_SCAL_32MHZ 0x0000000e 2097 #define AR5K_PHY_SCAL_32MHZ 0x0000000e
2098 #define AR5K_PHY_SCAL_32MHZ_2417 0x0000000a 2098 #define AR5K_PHY_SCAL_32MHZ_2417 0x0000000a
2099 #define AR5K_PHY_SCAL_32MHZ_HB63 0x00000032 2099 #define AR5K_PHY_SCAL_32MHZ_HB63 0x00000032
2100 2100
2101 /* 2101 /*
2102 * PHY PLL (Phase Locked Loop) control register 2102 * PHY PLL (Phase Locked Loop) control register
2103 */ 2103 */
2104 #define AR5K_PHY_PLL 0x987c 2104 #define AR5K_PHY_PLL 0x987c
2105 #define AR5K_PHY_PLL_20MHZ 0x00000013 /* For half rate (?) */ 2105 #define AR5K_PHY_PLL_20MHZ 0x00000013 /* For half rate (?) */
2106 /* 40MHz -> 5GHz band */ 2106 /* 40MHz -> 5GHz band */
2107 #define AR5K_PHY_PLL_40MHZ_5211 0x00000018 2107 #define AR5K_PHY_PLL_40MHZ_5211 0x00000018
2108 #define AR5K_PHY_PLL_40MHZ_5212 0x000000aa 2108 #define AR5K_PHY_PLL_40MHZ_5212 0x000000aa
2109 #define AR5K_PHY_PLL_40MHZ_5413 0x00000004 2109 #define AR5K_PHY_PLL_40MHZ_5413 0x00000004
2110 #define AR5K_PHY_PLL_40MHZ (ah->ah_version == AR5K_AR5211 ? \ 2110 #define AR5K_PHY_PLL_40MHZ (ah->ah_version == AR5K_AR5211 ? \
2111 AR5K_PHY_PLL_40MHZ_5211 : AR5K_PHY_PLL_40MHZ_5212) 2111 AR5K_PHY_PLL_40MHZ_5211 : AR5K_PHY_PLL_40MHZ_5212)
2112 /* 44MHz -> 2.4GHz band */ 2112 /* 44MHz -> 2.4GHz band */
2113 #define AR5K_PHY_PLL_44MHZ_5211 0x00000019 2113 #define AR5K_PHY_PLL_44MHZ_5211 0x00000019
2114 #define AR5K_PHY_PLL_44MHZ_5212 0x000000ab 2114 #define AR5K_PHY_PLL_44MHZ_5212 0x000000ab
2115 #define AR5K_PHY_PLL_44MHZ (ah->ah_version == AR5K_AR5211 ? \ 2115 #define AR5K_PHY_PLL_44MHZ (ah->ah_version == AR5K_AR5211 ? \
2116 AR5K_PHY_PLL_44MHZ_5211 : AR5K_PHY_PLL_44MHZ_5212) 2116 AR5K_PHY_PLL_44MHZ_5211 : AR5K_PHY_PLL_44MHZ_5212)
2117 2117
2118 #define AR5K_PHY_PLL_RF5111 0x00000000 2118 #define AR5K_PHY_PLL_RF5111 0x00000000
2119 #define AR5K_PHY_PLL_RF5112 0x00000040 2119 #define AR5K_PHY_PLL_RF5112 0x00000040
2120 #define AR5K_PHY_PLL_HALF_RATE 0x00000100 2120 #define AR5K_PHY_PLL_HALF_RATE 0x00000100
2121 #define AR5K_PHY_PLL_QUARTER_RATE 0x00000200 2121 #define AR5K_PHY_PLL_QUARTER_RATE 0x00000200
2122 2122
2123 /* 2123 /*
2124 * RF Buffer register 2124 * RF Buffer register
2125 * 2125 *
2126 * It's obvious from the code that 0x989c is the buffer register but 2126 * It's obvious from the code that 0x989c is the buffer register but
2127 * for the other special registers that we write to after sending each 2127 * for the other special registers that we write to after sending each
2128 * packet, i have no idea. So i'll name them BUFFER_CONTROL_X registers 2128 * packet, i have no idea. So i'll name them BUFFER_CONTROL_X registers
2129 * for now. It's interesting that they are also used for some other operations. 2129 * for now. It's interesting that they are also used for some other operations.
2130 */ 2130 */
2131 2131
2132 #define AR5K_RF_BUFFER 0x989c 2132 #define AR5K_RF_BUFFER 0x989c
2133 #define AR5K_RF_BUFFER_CONTROL_0 0x98c0 /* Channel on 5110 */ 2133 #define AR5K_RF_BUFFER_CONTROL_0 0x98c0 /* Channel on 5110 */
2134 #define AR5K_RF_BUFFER_CONTROL_1 0x98c4 /* Bank 7 on 5112 */ 2134 #define AR5K_RF_BUFFER_CONTROL_1 0x98c4 /* Bank 7 on 5112 */
2135 #define AR5K_RF_BUFFER_CONTROL_2 0x98cc /* Bank 7 on 5111 */ 2135 #define AR5K_RF_BUFFER_CONTROL_2 0x98cc /* Bank 7 on 5111 */
2136 2136
2137 #define AR5K_RF_BUFFER_CONTROL_3 0x98d0 /* Bank 2 on 5112 */ 2137 #define AR5K_RF_BUFFER_CONTROL_3 0x98d0 /* Bank 2 on 5112 */
2138 /* Channel set on 5111 */ 2138 /* Channel set on 5111 */
2139 /* Used to read radio revision*/ 2139 /* Used to read radio revision*/
2140 2140
2141 #define AR5K_RF_BUFFER_CONTROL_4 0x98d4 /* RF Stage register on 5110 */ 2141 #define AR5K_RF_BUFFER_CONTROL_4 0x98d4 /* RF Stage register on 5110 */
2142 /* Bank 0,1,2,6 on 5111 */ 2142 /* Bank 0,1,2,6 on 5111 */
2143 /* Bank 1 on 5112 */ 2143 /* Bank 1 on 5112 */
2144 /* Used during activation on 5111 */ 2144 /* Used during activation on 5111 */
2145 2145
2146 #define AR5K_RF_BUFFER_CONTROL_5 0x98d8 /* Bank 3 on 5111 */ 2146 #define AR5K_RF_BUFFER_CONTROL_5 0x98d8 /* Bank 3 on 5111 */
2147 /* Used during activation on 5111 */ 2147 /* Used during activation on 5111 */
2148 /* Channel on 5112 */ 2148 /* Channel on 5112 */
2149 /* Bank 6 on 5112 */ 2149 /* Bank 6 on 5112 */
2150 2150
2151 #define AR5K_RF_BUFFER_CONTROL_6 0x98dc /* Bank 3 on 5112 */ 2151 #define AR5K_RF_BUFFER_CONTROL_6 0x98dc /* Bank 3 on 5112 */
2152 2152
2153 /* 2153 /*
2154 * PHY RF stage register [5210] 2154 * PHY RF stage register [5210]
2155 */ 2155 */
2156 #define AR5K_PHY_RFSTG 0x98d4 2156 #define AR5K_PHY_RFSTG 0x98d4
2157 #define AR5K_PHY_RFSTG_DISABLE 0x00000021 2157 #define AR5K_PHY_RFSTG_DISABLE 0x00000021
2158 2158
2159 /* 2159 /*
2160 * BIN masks (?) 2160 * BIN masks (?)
2161 */ 2161 */
2162 #define AR5K_PHY_BIN_MASK_1 0x9900 2162 #define AR5K_PHY_BIN_MASK_1 0x9900
2163 #define AR5K_PHY_BIN_MASK_2 0x9904 2163 #define AR5K_PHY_BIN_MASK_2 0x9904
2164 #define AR5K_PHY_BIN_MASK_3 0x9908 2164 #define AR5K_PHY_BIN_MASK_3 0x9908
2165 2165
2166 #define AR5K_PHY_BIN_MASK_CTL 0x990c 2166 #define AR5K_PHY_BIN_MASK_CTL 0x990c
2167 #define AR5K_PHY_BIN_MASK_CTL_MASK_4 0x00003fff 2167 #define AR5K_PHY_BIN_MASK_CTL_MASK_4 0x00003fff
2168 #define AR5K_PHY_BIN_MASK_CTL_MASK_4_S 0 2168 #define AR5K_PHY_BIN_MASK_CTL_MASK_4_S 0
2169 #define AR5K_PHY_BIN_MASK_CTL_RATE 0xff000000 2169 #define AR5K_PHY_BIN_MASK_CTL_RATE 0xff000000
2170 #define AR5K_PHY_BIN_MASK_CTL_RATE_S 24 2170 #define AR5K_PHY_BIN_MASK_CTL_RATE_S 24
2171 2171
2172 /* 2172 /*
2173 * PHY Antenna control register 2173 * PHY Antenna control register
2174 */ 2174 */
2175 #define AR5K_PHY_ANT_CTL 0x9910 /* Register Address */ 2175 #define AR5K_PHY_ANT_CTL 0x9910 /* Register Address */
2176 #define AR5K_PHY_ANT_CTL_TXRX_EN 0x00000001 /* Enable TX/RX (?) */ 2176 #define AR5K_PHY_ANT_CTL_TXRX_EN 0x00000001 /* Enable TX/RX (?) */
2177 #define AR5K_PHY_ANT_CTL_SECTORED_ANT 0x00000004 /* Sectored Antenna */ 2177 #define AR5K_PHY_ANT_CTL_SECTORED_ANT 0x00000004 /* Sectored Antenna */
2178 #define AR5K_PHY_ANT_CTL_HITUNE5 0x00000008 /* Hitune5 (?) */ 2178 #define AR5K_PHY_ANT_CTL_HITUNE5 0x00000008 /* Hitune5 (?) */
2179 #define AR5K_PHY_ANT_CTL_SWTABLE_IDLE 0x000003f0 /* Switch table idle (?) */ 2179 #define AR5K_PHY_ANT_CTL_SWTABLE_IDLE 0x000003f0 /* Switch table idle (?) */
2180 #define AR5K_PHY_ANT_CTL_SWTABLE_IDLE_S 4 2180 #define AR5K_PHY_ANT_CTL_SWTABLE_IDLE_S 4
2181 2181
2182 /* 2182 /*
2183 * PHY receiver delay register [5111+] 2183 * PHY receiver delay register [5111+]
2184 */ 2184 */
2185 #define AR5K_PHY_RX_DELAY 0x9914 /* Register Address */ 2185 #define AR5K_PHY_RX_DELAY 0x9914 /* Register Address */
2186 #define AR5K_PHY_RX_DELAY_M 0x00003fff /* Mask for RX activate to receive delay (/100ns) */ 2186 #define AR5K_PHY_RX_DELAY_M 0x00003fff /* Mask for RX activate to receive delay (/100ns) */
2187 2187
2188 /* 2188 /*
2189 * PHY max rx length register (?) [5111] 2189 * PHY max rx length register (?) [5111]
2190 */ 2190 */
2191 #define AR5K_PHY_MAX_RX_LEN 0x991c 2191 #define AR5K_PHY_MAX_RX_LEN 0x991c
2192 2192
2193 /* 2193 /*
2194 * PHY timing register 4 2194 * PHY timing register 4
2195 * I(nphase)/Q(adrature) calibration register [5111+] 2195 * I(nphase)/Q(adrature) calibration register [5111+]
2196 */ 2196 */
2197 #define AR5K_PHY_IQ 0x9920 /* Register Address */ 2197 #define AR5K_PHY_IQ 0x9920 /* Register Address */
2198 #define AR5K_PHY_IQ_CORR_Q_Q_COFF 0x0000001f /* Mask for q correction info */ 2198 #define AR5K_PHY_IQ_CORR_Q_Q_COFF 0x0000001f /* Mask for q correction info */
2199 #define AR5K_PHY_IQ_CORR_Q_I_COFF 0x000007e0 /* Mask for i correction info */ 2199 #define AR5K_PHY_IQ_CORR_Q_I_COFF 0x000007e0 /* Mask for i correction info */
2200 #define AR5K_PHY_IQ_CORR_Q_I_COFF_S 5 2200 #define AR5K_PHY_IQ_CORR_Q_I_COFF_S 5
2201 #define AR5K_PHY_IQ_CORR_ENABLE 0x00000800 /* Enable i/q correction */ 2201 #define AR5K_PHY_IQ_CORR_ENABLE 0x00000800 /* Enable i/q correction */
2202 #define AR5K_PHY_IQ_CAL_NUM_LOG_MAX 0x0000f000 /* Mask for max number of samples in log scale */ 2202 #define AR5K_PHY_IQ_CAL_NUM_LOG_MAX 0x0000f000 /* Mask for max number of samples in log scale */
2203 #define AR5K_PHY_IQ_CAL_NUM_LOG_MAX_S 12 2203 #define AR5K_PHY_IQ_CAL_NUM_LOG_MAX_S 12
2204 #define AR5K_PHY_IQ_RUN 0x00010000 /* Run i/q calibration */ 2204 #define AR5K_PHY_IQ_RUN 0x00010000 /* Run i/q calibration */
2205 #define AR5K_PHY_IQ_USE_PT_DF 0x00020000 /* Use pilot track df (?) */ 2205 #define AR5K_PHY_IQ_USE_PT_DF 0x00020000 /* Use pilot track df (?) */
2206 #define AR5K_PHY_IQ_EARLY_TRIG_THR 0x00200000 /* Early trigger threshold (?) (field) */ 2206 #define AR5K_PHY_IQ_EARLY_TRIG_THR 0x00200000 /* Early trigger threshold (?) (field) */
2207 #define AR5K_PHY_IQ_PILOT_MASK_EN 0x10000000 /* Enable pilot mask (?) */ 2207 #define AR5K_PHY_IQ_PILOT_MASK_EN 0x10000000 /* Enable pilot mask (?) */
2208 #define AR5K_PHY_IQ_CHAN_MASK_EN 0x20000000 /* Enable channel mask (?) */ 2208 #define AR5K_PHY_IQ_CHAN_MASK_EN 0x20000000 /* Enable channel mask (?) */
2209 #define AR5K_PHY_IQ_SPUR_FILT_EN 0x40000000 /* Enable spur filter */ 2209 #define AR5K_PHY_IQ_SPUR_FILT_EN 0x40000000 /* Enable spur filter */
2210 #define AR5K_PHY_IQ_SPUR_RSSI_EN 0x80000000 /* Enable spur rssi */ 2210 #define AR5K_PHY_IQ_SPUR_RSSI_EN 0x80000000 /* Enable spur rssi */
2211 2211
2212 /* 2212 /*
2213 * PHY timing register 5 2213 * PHY timing register 5
2214 * OFDM Self-correlator Cyclic RSSI threshold params 2214 * OFDM Self-correlator Cyclic RSSI threshold params
2215 * (Check out bb_cycpwr_thr1 on ANI patent) 2215 * (Check out bb_cycpwr_thr1 on ANI patent)
2216 */ 2216 */
2217 #define AR5K_PHY_OFDM_SELFCORR 0x9924 /* Register Address */ 2217 #define AR5K_PHY_OFDM_SELFCORR 0x9924 /* Register Address */
2218 #define AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1_EN 0x00000001 /* Enable cyclic RSSI thr 1 */ 2218 #define AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1_EN 0x00000001 /* Enable cyclic RSSI thr 1 */
2219 #define AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1 0x000000fe /* Mask for Cyclic RSSI threshold 1 */ 2219 #define AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1 0x000000fe /* Mask for Cyclic RSSI threshold 1 */
2220 #define AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1_S 1 2220 #define AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1_S 1
2221 #define AR5K_PHY_OFDM_SELFCORR_CYPWR_THR3 0x00000100 /* Cyclic RSSI threshold 3 (field) (?) */ 2221 #define AR5K_PHY_OFDM_SELFCORR_CYPWR_THR3 0x00000100 /* Cyclic RSSI threshold 3 (field) (?) */
2222 #define AR5K_PHY_OFDM_SELFCORR_RSSI_1ATHR_EN 0x00008000 /* Enable 1A RSSI threshold (?) */ 2222 #define AR5K_PHY_OFDM_SELFCORR_RSSI_1ATHR_EN 0x00008000 /* Enable 1A RSSI threshold (?) */
2223 #define AR5K_PHY_OFDM_SELFCORR_RSSI_1ATHR 0x00010000 /* 1A RSSI threshold (field) (?) */ 2223 #define AR5K_PHY_OFDM_SELFCORR_RSSI_1ATHR 0x00010000 /* 1A RSSI threshold (field) (?) */
2224 #define AR5K_PHY_OFDM_SELFCORR_LSCTHR_HIRSSI 0x00800000 /* Long sc threshold hi rssi (?) */ 2224 #define AR5K_PHY_OFDM_SELFCORR_LSCTHR_HIRSSI 0x00800000 /* Long sc threshold hi rssi (?) */
2225 2225
2226 /* 2226 /*
2227 * PHY-only warm reset register 2227 * PHY-only warm reset register
2228 */ 2228 */
2229 #define AR5K_PHY_WARM_RESET 0x9928 2229 #define AR5K_PHY_WARM_RESET 0x9928
2230 2230
2231 /* 2231 /*
2232 * PHY-only control register 2232 * PHY-only control register
2233 */ 2233 */
2234 #define AR5K_PHY_CTL 0x992c /* Register Address */ 2234 #define AR5K_PHY_CTL 0x992c /* Register Address */
2235 #define AR5K_PHY_CTL_RX_DRAIN_RATE 0x00000001 /* RX drain rate (?) */ 2235 #define AR5K_PHY_CTL_RX_DRAIN_RATE 0x00000001 /* RX drain rate (?) */
2236 #define AR5K_PHY_CTL_LATE_TX_SIG_SYM 0x00000002 /* Late tx signal symbol (?) */ 2236 #define AR5K_PHY_CTL_LATE_TX_SIG_SYM 0x00000002 /* Late tx signal symbol (?) */
2237 #define AR5K_PHY_CTL_GEN_SCRAMBLER 0x00000004 /* Generate scrambler */ 2237 #define AR5K_PHY_CTL_GEN_SCRAMBLER 0x00000004 /* Generate scrambler */
2238 #define AR5K_PHY_CTL_TX_ANT_SEL 0x00000008 /* TX antenna select */ 2238 #define AR5K_PHY_CTL_TX_ANT_SEL 0x00000008 /* TX antenna select */
2239 #define AR5K_PHY_CTL_TX_ANT_STATIC 0x00000010 /* Static TX antenna */ 2239 #define AR5K_PHY_CTL_TX_ANT_STATIC 0x00000010 /* Static TX antenna */
2240 #define AR5K_PHY_CTL_RX_ANT_SEL 0x00000020 /* RX antenna select */ 2240 #define AR5K_PHY_CTL_RX_ANT_SEL 0x00000020 /* RX antenna select */
2241 #define AR5K_PHY_CTL_RX_ANT_STATIC 0x00000040 /* Static RX antenna */ 2241 #define AR5K_PHY_CTL_RX_ANT_STATIC 0x00000040 /* Static RX antenna */
2242 #define AR5K_PHY_CTL_LOW_FREQ_SLE_EN 0x00000080 /* Enable low freq sleep */ 2242 #define AR5K_PHY_CTL_LOW_FREQ_SLE_EN 0x00000080 /* Enable low freq sleep */
2243 2243
2244 /* 2244 /*
2245 * PHY PAPD probe register [5111+] 2245 * PHY PAPD probe register [5111+]
2246 */ 2246 */
2247 #define AR5K_PHY_PAPD_PROBE 0x9930 2247 #define AR5K_PHY_PAPD_PROBE 0x9930
2248 #define AR5K_PHY_PAPD_PROBE_SH_HI_PAR 0x00000001 2248 #define AR5K_PHY_PAPD_PROBE_SH_HI_PAR 0x00000001
2249 #define AR5K_PHY_PAPD_PROBE_PCDAC_BIAS 0x00000002 2249 #define AR5K_PHY_PAPD_PROBE_PCDAC_BIAS 0x00000002
2250 #define AR5K_PHY_PAPD_PROBE_COMP_GAIN 0x00000040 2250 #define AR5K_PHY_PAPD_PROBE_COMP_GAIN 0x00000040
2251 #define AR5K_PHY_PAPD_PROBE_TXPOWER 0x00007e00 2251 #define AR5K_PHY_PAPD_PROBE_TXPOWER 0x00007e00
2252 #define AR5K_PHY_PAPD_PROBE_TXPOWER_S 9 2252 #define AR5K_PHY_PAPD_PROBE_TXPOWER_S 9
2253 #define AR5K_PHY_PAPD_PROBE_TX_NEXT 0x00008000 2253 #define AR5K_PHY_PAPD_PROBE_TX_NEXT 0x00008000
2254 #define AR5K_PHY_PAPD_PROBE_PREDIST_EN 0x00010000 2254 #define AR5K_PHY_PAPD_PROBE_PREDIST_EN 0x00010000
2255 #define AR5K_PHY_PAPD_PROBE_TYPE 0x01800000 /* [5112+] */ 2255 #define AR5K_PHY_PAPD_PROBE_TYPE 0x01800000 /* [5112+] */
2256 #define AR5K_PHY_PAPD_PROBE_TYPE_S 23 2256 #define AR5K_PHY_PAPD_PROBE_TYPE_S 23
2257 #define AR5K_PHY_PAPD_PROBE_TYPE_OFDM 0 2257 #define AR5K_PHY_PAPD_PROBE_TYPE_OFDM 0
2258 #define AR5K_PHY_PAPD_PROBE_TYPE_XR 1 2258 #define AR5K_PHY_PAPD_PROBE_TYPE_XR 1
2259 #define AR5K_PHY_PAPD_PROBE_TYPE_CCK 2 2259 #define AR5K_PHY_PAPD_PROBE_TYPE_CCK 2
2260 #define AR5K_PHY_PAPD_PROBE_GAINF 0xfe000000 2260 #define AR5K_PHY_PAPD_PROBE_GAINF 0xfe000000
2261 #define AR5K_PHY_PAPD_PROBE_GAINF_S 25 2261 #define AR5K_PHY_PAPD_PROBE_GAINF_S 25
2262 #define AR5K_PHY_PAPD_PROBE_INI_5111 0x00004883 /* [5212+] */ 2262 #define AR5K_PHY_PAPD_PROBE_INI_5111 0x00004883 /* [5212+] */
2263 #define AR5K_PHY_PAPD_PROBE_INI_5112 0x00004882 /* [5212+] */ 2263 #define AR5K_PHY_PAPD_PROBE_INI_5112 0x00004882 /* [5212+] */
2264 2264
2265 /* 2265 /*
2266 * PHY TX rate power registers [5112+] 2266 * PHY TX rate power registers [5112+]
2267 */ 2267 */
2268 #define AR5K_PHY_TXPOWER_RATE1 0x9934 2268 #define AR5K_PHY_TXPOWER_RATE1 0x9934
2269 #define AR5K_PHY_TXPOWER_RATE2 0x9938 2269 #define AR5K_PHY_TXPOWER_RATE2 0x9938
2270 #define AR5K_PHY_TXPOWER_RATE_MAX 0x993c 2270 #define AR5K_PHY_TXPOWER_RATE_MAX 0x993c
2271 #define AR5K_PHY_TXPOWER_RATE_MAX_TPC_ENABLE 0x00000040 2271 #define AR5K_PHY_TXPOWER_RATE_MAX_TPC_ENABLE 0x00000040
2272 #define AR5K_PHY_TXPOWER_RATE3 0xa234 2272 #define AR5K_PHY_TXPOWER_RATE3 0xa234
2273 #define AR5K_PHY_TXPOWER_RATE4 0xa238 2273 #define AR5K_PHY_TXPOWER_RATE4 0xa238
2274 2274
2275 /* 2275 /*
2276 * PHY frame control register [5111+] 2276 * PHY frame control register [5111+]
2277 */ 2277 */
2278 #define AR5K_PHY_FRAME_CTL_5210 0x9804 2278 #define AR5K_PHY_FRAME_CTL_5210 0x9804
2279 #define AR5K_PHY_FRAME_CTL_5211 0x9944 2279 #define AR5K_PHY_FRAME_CTL_5211 0x9944
2280 #define AR5K_PHY_FRAME_CTL (ah->ah_version == AR5K_AR5210 ? \ 2280 #define AR5K_PHY_FRAME_CTL (ah->ah_version == AR5K_AR5210 ? \
2281 AR5K_PHY_FRAME_CTL_5210 : AR5K_PHY_FRAME_CTL_5211) 2281 AR5K_PHY_FRAME_CTL_5210 : AR5K_PHY_FRAME_CTL_5211)
2282 /*---[5111+]---*/ 2282 /*---[5111+]---*/
2283 #define AR5K_PHY_FRAME_CTL_TX_CLIP 0x00000038 /* Mask for tx clip (?) */ 2283 #define AR5K_PHY_FRAME_CTL_TX_CLIP 0x00000038 /* Mask for tx clip (?) */
2284 #define AR5K_PHY_FRAME_CTL_TX_CLIP_S 3 2284 #define AR5K_PHY_FRAME_CTL_TX_CLIP_S 3
2285 #define AR5K_PHY_FRAME_CTL_PREP_CHINFO 0x00010000 /* Prepend chan info */ 2285 #define AR5K_PHY_FRAME_CTL_PREP_CHINFO 0x00010000 /* Prepend chan info */
2286 #define AR5K_PHY_FRAME_CTL_EMU 0x80000000 2286 #define AR5K_PHY_FRAME_CTL_EMU 0x80000000
2287 #define AR5K_PHY_FRAME_CTL_EMU_S 31 2287 #define AR5K_PHY_FRAME_CTL_EMU_S 31
2288 /*---[5110/5111]---*/ 2288 /*---[5110/5111]---*/
2289 #define AR5K_PHY_FRAME_CTL_TIMING_ERR 0x01000000 /* PHY timing error */ 2289 #define AR5K_PHY_FRAME_CTL_TIMING_ERR 0x01000000 /* PHY timing error */
2290 #define AR5K_PHY_FRAME_CTL_PARITY_ERR 0x02000000 /* Parity error */ 2290 #define AR5K_PHY_FRAME_CTL_PARITY_ERR 0x02000000 /* Parity error */
2291 #define AR5K_PHY_FRAME_CTL_ILLRATE_ERR 0x04000000 /* Illegal rate */ 2291 #define AR5K_PHY_FRAME_CTL_ILLRATE_ERR 0x04000000 /* Illegal rate */
2292 #define AR5K_PHY_FRAME_CTL_ILLLEN_ERR 0x08000000 /* Illegal length */ 2292 #define AR5K_PHY_FRAME_CTL_ILLLEN_ERR 0x08000000 /* Illegal length */
2293 #define AR5K_PHY_FRAME_CTL_SERVICE_ERR 0x20000000 2293 #define AR5K_PHY_FRAME_CTL_SERVICE_ERR 0x20000000
2294 #define AR5K_PHY_FRAME_CTL_TXURN_ERR 0x40000000 /* TX underrun */ 2294 #define AR5K_PHY_FRAME_CTL_TXURN_ERR 0x40000000 /* TX underrun */
2295 #define AR5K_PHY_FRAME_CTL_INI AR5K_PHY_FRAME_CTL_SERVICE_ERR | \ 2295 #define AR5K_PHY_FRAME_CTL_INI AR5K_PHY_FRAME_CTL_SERVICE_ERR | \
2296 AR5K_PHY_FRAME_CTL_TXURN_ERR | \ 2296 AR5K_PHY_FRAME_CTL_TXURN_ERR | \
2297 AR5K_PHY_FRAME_CTL_ILLLEN_ERR | \ 2297 AR5K_PHY_FRAME_CTL_ILLLEN_ERR | \
2298 AR5K_PHY_FRAME_CTL_ILLRATE_ERR | \ 2298 AR5K_PHY_FRAME_CTL_ILLRATE_ERR | \
2299 AR5K_PHY_FRAME_CTL_PARITY_ERR | \ 2299 AR5K_PHY_FRAME_CTL_PARITY_ERR | \
2300 AR5K_PHY_FRAME_CTL_TIMING_ERR 2300 AR5K_PHY_FRAME_CTL_TIMING_ERR
2301 2301
2302 /* 2302 /*
2303 * PHY Tx Power adjustment register [5212A+] 2303 * PHY Tx Power adjustment register [5212A+]
2304 */ 2304 */
2305 #define AR5K_PHY_TX_PWR_ADJ 0x994c 2305 #define AR5K_PHY_TX_PWR_ADJ 0x994c
2306 #define AR5K_PHY_TX_PWR_ADJ_CCK_GAIN_DELTA 0x00000fc0 2306 #define AR5K_PHY_TX_PWR_ADJ_CCK_GAIN_DELTA 0x00000fc0
2307 #define AR5K_PHY_TX_PWR_ADJ_CCK_GAIN_DELTA_S 6 2307 #define AR5K_PHY_TX_PWR_ADJ_CCK_GAIN_DELTA_S 6
2308 #define AR5K_PHY_TX_PWR_ADJ_CCK_PCDAC_INDEX 0x00fc0000 2308 #define AR5K_PHY_TX_PWR_ADJ_CCK_PCDAC_INDEX 0x00fc0000
2309 #define AR5K_PHY_TX_PWR_ADJ_CCK_PCDAC_INDEX_S 18 2309 #define AR5K_PHY_TX_PWR_ADJ_CCK_PCDAC_INDEX_S 18
2310 2310
2311 /* 2311 /*
2312 * PHY radar detection register [5111+] 2312 * PHY radar detection register [5111+]
2313 */ 2313 */
2314 #define AR5K_PHY_RADAR 0x9954 2314 #define AR5K_PHY_RADAR 0x9954
2315 #define AR5K_PHY_RADAR_ENABLE 0x00000001 2315 #define AR5K_PHY_RADAR_ENABLE 0x00000001
2316 #define AR5K_PHY_RADAR_DISABLE 0x00000000 2316 #define AR5K_PHY_RADAR_DISABLE 0x00000000
2317 #define AR5K_PHY_RADAR_INBANDTHR 0x0000003e /* Inband threshold 2317 #define AR5K_PHY_RADAR_INBANDTHR 0x0000003e /* Inband threshold
2318 5-bits, units unknown {0..31} 2318 5-bits, units unknown {0..31}
2319 (? MHz ?) */ 2319 (? MHz ?) */
2320 #define AR5K_PHY_RADAR_INBANDTHR_S 1 2320 #define AR5K_PHY_RADAR_INBANDTHR_S 1
2321 2321
2322 #define AR5K_PHY_RADAR_PRSSI_THR 0x00000fc0 /* Pulse RSSI/SNR threshold 2322 #define AR5K_PHY_RADAR_PRSSI_THR 0x00000fc0 /* Pulse RSSI/SNR threshold
2323 6-bits, dBm range {0..63} 2323 6-bits, dBm range {0..63}
2324 in dBm units. */ 2324 in dBm units. */
2325 #define AR5K_PHY_RADAR_PRSSI_THR_S 6 2325 #define AR5K_PHY_RADAR_PRSSI_THR_S 6
2326 2326
2327 #define AR5K_PHY_RADAR_PHEIGHT_THR 0x0003f000 /* Pulse height threshold 2327 #define AR5K_PHY_RADAR_PHEIGHT_THR 0x0003f000 /* Pulse height threshold
2328 6-bits, dBm range {0..63} 2328 6-bits, dBm range {0..63}
2329 in dBm units. */ 2329 in dBm units. */
2330 #define AR5K_PHY_RADAR_PHEIGHT_THR_S 12 2330 #define AR5K_PHY_RADAR_PHEIGHT_THR_S 12
2331 2331
2332 #define AR5K_PHY_RADAR_RSSI_THR 0x00fc0000 /* Radar RSSI/SNR threshold. 2332 #define AR5K_PHY_RADAR_RSSI_THR 0x00fc0000 /* Radar RSSI/SNR threshold.
2333 6-bits, dBm range {0..63} 2333 6-bits, dBm range {0..63}
2334 in dBm units. */ 2334 in dBm units. */
2335 #define AR5K_PHY_RADAR_RSSI_THR_S 18 2335 #define AR5K_PHY_RADAR_RSSI_THR_S 18
2336 2336
2337 #define AR5K_PHY_RADAR_FIRPWR_THR 0x7f000000 /* Finite Impulse Response 2337 #define AR5K_PHY_RADAR_FIRPWR_THR 0x7f000000 /* Finite Impulse Response
2338 filter power out threshold. 2338 filter power out threshold.
2339 7-bits, standard power range 2339 7-bits, standard power range
2340 {0..127} in 1/2 dBm units. */ 2340 {0..127} in 1/2 dBm units. */
2341 #define AR5K_PHY_RADAR_FIRPWR_THRS 24 2341 #define AR5K_PHY_RADAR_FIRPWR_THRS 24
2342 2342
2343 /* 2343 /*
2344 * PHY antenna switch table registers 2344 * PHY antenna switch table registers
2345 */ 2345 */
2346 #define AR5K_PHY_ANT_SWITCH_TABLE_0 0x9960 2346 #define AR5K_PHY_ANT_SWITCH_TABLE_0 0x9960
2347 #define AR5K_PHY_ANT_SWITCH_TABLE_1 0x9964 2347 #define AR5K_PHY_ANT_SWITCH_TABLE_1 0x9964
2348 2348
2349 /* 2349 /*
2350 * PHY Noise floor threshold 2350 * PHY Noise floor threshold
2351 */ 2351 */
2352 #define AR5K_PHY_NFTHRES 0x9968 2352 #define AR5K_PHY_NFTHRES 0x9968
2353 2353
2354 /* 2354 /*
2355 * Sigma Delta register (?) [5213] 2355 * Sigma Delta register (?) [5213]
2356 */ 2356 */
2357 #define AR5K_PHY_SIGMA_DELTA 0x996C 2357 #define AR5K_PHY_SIGMA_DELTA 0x996C
2358 #define AR5K_PHY_SIGMA_DELTA_ADC_SEL 0x00000003 2358 #define AR5K_PHY_SIGMA_DELTA_ADC_SEL 0x00000003
2359 #define AR5K_PHY_SIGMA_DELTA_ADC_SEL_S 0 2359 #define AR5K_PHY_SIGMA_DELTA_ADC_SEL_S 0
2360 #define AR5K_PHY_SIGMA_DELTA_FILT2 0x000000f8 2360 #define AR5K_PHY_SIGMA_DELTA_FILT2 0x000000f8
2361 #define AR5K_PHY_SIGMA_DELTA_FILT2_S 3 2361 #define AR5K_PHY_SIGMA_DELTA_FILT2_S 3
2362 #define AR5K_PHY_SIGMA_DELTA_FILT1 0x00001f00 2362 #define AR5K_PHY_SIGMA_DELTA_FILT1 0x00001f00
2363 #define AR5K_PHY_SIGMA_DELTA_FILT1_S 8 2363 #define AR5K_PHY_SIGMA_DELTA_FILT1_S 8
2364 #define AR5K_PHY_SIGMA_DELTA_ADC_CLIP 0x01ffe000 2364 #define AR5K_PHY_SIGMA_DELTA_ADC_CLIP 0x01ffe000
2365 #define AR5K_PHY_SIGMA_DELTA_ADC_CLIP_S 13 2365 #define AR5K_PHY_SIGMA_DELTA_ADC_CLIP_S 13
2366 2366
2367 /* 2367 /*
2368 * RF restart register [5112+] (?) 2368 * RF restart register [5112+] (?)
2369 */ 2369 */
2370 #define AR5K_PHY_RESTART 0x9970 /* restart */ 2370 #define AR5K_PHY_RESTART 0x9970 /* restart */
2371 #define AR5K_PHY_RESTART_DIV_GC 0x001c0000 /* Fast diversity gc_limit (?) */ 2371 #define AR5K_PHY_RESTART_DIV_GC 0x001c0000 /* Fast diversity gc_limit (?) */
2372 #define AR5K_PHY_RESTART_DIV_GC_S 18 2372 #define AR5K_PHY_RESTART_DIV_GC_S 18
2373 2373
2374 /* 2374 /*
2375 * RF Bus access request register (for synth-oly channel switching) 2375 * RF Bus access request register (for synth-oly channel switching)
2376 */ 2376 */
2377 #define AR5K_PHY_RFBUS_REQ 0x997C 2377 #define AR5K_PHY_RFBUS_REQ 0x997C
2378 #define AR5K_PHY_RFBUS_REQ_REQUEST 0x00000001 2378 #define AR5K_PHY_RFBUS_REQ_REQUEST 0x00000001
2379 2379
2380 /* 2380 /*
2381 * Spur mitigation masks (?) 2381 * Spur mitigation masks (?)
2382 */ 2382 */
2383 #define AR5K_PHY_TIMING_7 0x9980 2383 #define AR5K_PHY_TIMING_7 0x9980
2384 #define AR5K_PHY_TIMING_8 0x9984 2384 #define AR5K_PHY_TIMING_8 0x9984
2385 #define AR5K_PHY_TIMING_8_PILOT_MASK_2 0x000fffff 2385 #define AR5K_PHY_TIMING_8_PILOT_MASK_2 0x000fffff
2386 #define AR5K_PHY_TIMING_8_PILOT_MASK_2_S 0 2386 #define AR5K_PHY_TIMING_8_PILOT_MASK_2_S 0
2387 2387
2388 #define AR5K_PHY_BIN_MASK2_1 0x9988 2388 #define AR5K_PHY_BIN_MASK2_1 0x9988
2389 #define AR5K_PHY_BIN_MASK2_2 0x998c 2389 #define AR5K_PHY_BIN_MASK2_2 0x998c
2390 #define AR5K_PHY_BIN_MASK2_3 0x9990 2390 #define AR5K_PHY_BIN_MASK2_3 0x9990
2391 2391
2392 #define AR5K_PHY_BIN_MASK2_4 0x9994 2392 #define AR5K_PHY_BIN_MASK2_4 0x9994
2393 #define AR5K_PHY_BIN_MASK2_4_MASK_4 0x00003fff 2393 #define AR5K_PHY_BIN_MASK2_4_MASK_4 0x00003fff
2394 #define AR5K_PHY_BIN_MASK2_4_MASK_4_S 0 2394 #define AR5K_PHY_BIN_MASK2_4_MASK_4_S 0
2395 2395
2396 #define AR5K_PHY_TIMING_9 0x9998 2396 #define AR5K_PHY_TIMING_9 0x9998
2397 #define AR5K_PHY_TIMING_10 0x999c 2397 #define AR5K_PHY_TIMING_10 0x999c
2398 #define AR5K_PHY_TIMING_10_PILOT_MASK_2 0x000fffff 2398 #define AR5K_PHY_TIMING_10_PILOT_MASK_2 0x000fffff
2399 #define AR5K_PHY_TIMING_10_PILOT_MASK_2_S 0 2399 #define AR5K_PHY_TIMING_10_PILOT_MASK_2_S 0
2400 2400
2401 /* 2401 /*
2402 * Spur mitigation control 2402 * Spur mitigation control
2403 */ 2403 */
2404 #define AR5K_PHY_TIMING_11 0x99a0 /* Register address */ 2404 #define AR5K_PHY_TIMING_11 0x99a0 /* Register address */
2405 #define AR5K_PHY_TIMING_11_SPUR_DELTA_PHASE 0x000fffff /* Spur delta phase */ 2405 #define AR5K_PHY_TIMING_11_SPUR_DELTA_PHASE 0x000fffff /* Spur delta phase */
2406 #define AR5K_PHY_TIMING_11_SPUR_DELTA_PHASE_S 0 2406 #define AR5K_PHY_TIMING_11_SPUR_DELTA_PHASE_S 0
2407 #define AR5K_PHY_TIMING_11_SPUR_FREQ_SD 0x3ff00000 /* Freq sigma delta */ 2407 #define AR5K_PHY_TIMING_11_SPUR_FREQ_SD 0x3ff00000 /* Freq sigma delta */
2408 #define AR5K_PHY_TIMING_11_SPUR_FREQ_SD_S 20 2408 #define AR5K_PHY_TIMING_11_SPUR_FREQ_SD_S 20
2409 #define AR5K_PHY_TIMING_11_USE_SPUR_IN_AGC 0x40000000 /* Spur filter in AGC detector */ 2409 #define AR5K_PHY_TIMING_11_USE_SPUR_IN_AGC 0x40000000 /* Spur filter in AGC detector */
2410 #define AR5K_PHY_TIMING_11_USE_SPUR_IN_SELFCOR 0x80000000 /* Spur filter in OFDM self correlator */ 2410 #define AR5K_PHY_TIMING_11_USE_SPUR_IN_SELFCOR 0x80000000 /* Spur filter in OFDM self correlator */
2411 2411
2412 /* 2412 /*
2413 * Gain tables 2413 * Gain tables
2414 */ 2414 */
2415 #define AR5K_BB_GAIN_BASE 0x9b00 /* BaseBand Amplifier Gain table base address */ 2415 #define AR5K_BB_GAIN_BASE 0x9b00 /* BaseBand Amplifier Gain table base address */
2416 #define AR5K_BB_GAIN(_n) (AR5K_BB_GAIN_BASE + ((_n) << 2)) 2416 #define AR5K_BB_GAIN(_n) (AR5K_BB_GAIN_BASE + ((_n) << 2))
2417 #define AR5K_RF_GAIN_BASE 0x9a00 /* RF Amplrifier Gain table base address */ 2417 #define AR5K_RF_GAIN_BASE 0x9a00 /* RF Amplrifier Gain table base address */
2418 #define AR5K_RF_GAIN(_n) (AR5K_RF_GAIN_BASE + ((_n) << 2)) 2418 #define AR5K_RF_GAIN(_n) (AR5K_RF_GAIN_BASE + ((_n) << 2))
2419 2419
2420 /* 2420 /*
2421 * PHY timing IQ calibration result register [5111+] 2421 * PHY timing IQ calibration result register [5111+]
2422 */ 2422 */
2423 #define AR5K_PHY_IQRES_CAL_PWR_I 0x9c10 /* I (Inphase) power value */ 2423 #define AR5K_PHY_IQRES_CAL_PWR_I 0x9c10 /* I (Inphase) power value */
2424 #define AR5K_PHY_IQRES_CAL_PWR_Q 0x9c14 /* Q (Quadrature) power value */ 2424 #define AR5K_PHY_IQRES_CAL_PWR_Q 0x9c14 /* Q (Quadrature) power value */
2425 #define AR5K_PHY_IQRES_CAL_CORR 0x9c18 /* I/Q Correlation */ 2425 #define AR5K_PHY_IQRES_CAL_CORR 0x9c18 /* I/Q Correlation */
2426 2426
2427 /* 2427 /*
2428 * PHY current RSSI register [5111+] 2428 * PHY current RSSI register [5111+]
2429 */ 2429 */
2430 #define AR5K_PHY_CURRENT_RSSI 0x9c1c 2430 #define AR5K_PHY_CURRENT_RSSI 0x9c1c
2431 2431
2432 /* 2432 /*
2433 * PHY RF Bus grant register 2433 * PHY RF Bus grant register
2434 */ 2434 */
2435 #define AR5K_PHY_RFBUS_GRANT 0x9c20 2435 #define AR5K_PHY_RFBUS_GRANT 0x9c20
2436 #define AR5K_PHY_RFBUS_GRANT_OK 0x00000001 2436 #define AR5K_PHY_RFBUS_GRANT_OK 0x00000001
2437 2437
2438 /* 2438 /*
2439 * PHY ADC test register 2439 * PHY ADC test register
2440 */ 2440 */
2441 #define AR5K_PHY_ADC_TEST 0x9c24 2441 #define AR5K_PHY_ADC_TEST 0x9c24
2442 #define AR5K_PHY_ADC_TEST_I 0x00000001 2442 #define AR5K_PHY_ADC_TEST_I 0x00000001
2443 #define AR5K_PHY_ADC_TEST_Q 0x00000200 2443 #define AR5K_PHY_ADC_TEST_Q 0x00000200
2444 2444
2445 /* 2445 /*
2446 * PHY DAC test register 2446 * PHY DAC test register
2447 */ 2447 */
2448 #define AR5K_PHY_DAC_TEST 0x9c28 2448 #define AR5K_PHY_DAC_TEST 0x9c28
2449 #define AR5K_PHY_DAC_TEST_I 0x00000001 2449 #define AR5K_PHY_DAC_TEST_I 0x00000001
2450 #define AR5K_PHY_DAC_TEST_Q 0x00000200 2450 #define AR5K_PHY_DAC_TEST_Q 0x00000200
2451 2451
2452 /* 2452 /*
2453 * PHY PTAT register (?) 2453 * PHY PTAT register (?)
2454 */ 2454 */
2455 #define AR5K_PHY_PTAT 0x9c2c 2455 #define AR5K_PHY_PTAT 0x9c2c
2456 2456
2457 /* 2457 /*
2458 * PHY Illegal TX rate register [5112+] 2458 * PHY Illegal TX rate register [5112+]
2459 */ 2459 */
2460 #define AR5K_PHY_BAD_TX_RATE 0x9c30 2460 #define AR5K_PHY_BAD_TX_RATE 0x9c30
2461 2461
2462 /* 2462 /*
2463 * PHY SPUR Power register [5112+] 2463 * PHY SPUR Power register [5112+]
2464 */ 2464 */
2465 #define AR5K_PHY_SPUR_PWR 0x9c34 /* Register Address */ 2465 #define AR5K_PHY_SPUR_PWR 0x9c34 /* Register Address */
2466 #define AR5K_PHY_SPUR_PWR_I 0x00000001 /* SPUR Power estimate for I (field) */ 2466 #define AR5K_PHY_SPUR_PWR_I 0x00000001 /* SPUR Power estimate for I (field) */
2467 #define AR5K_PHY_SPUR_PWR_Q 0x00000100 /* SPUR Power estimate for Q (field) */ 2467 #define AR5K_PHY_SPUR_PWR_Q 0x00000100 /* SPUR Power estimate for Q (field) */
2468 #define AR5K_PHY_SPUR_PWR_FILT 0x00010000 /* Power with SPUR removed (field) */ 2468 #define AR5K_PHY_SPUR_PWR_FILT 0x00010000 /* Power with SPUR removed (field) */
2469 2469
2470 /* 2470 /*
2471 * PHY Channel status register [5112+] (?) 2471 * PHY Channel status register [5112+] (?)
2472 */ 2472 */
2473 #define AR5K_PHY_CHAN_STATUS 0x9c38 2473 #define AR5K_PHY_CHAN_STATUS 0x9c38
2474 #define AR5K_PHY_CHAN_STATUS_BT_ACT 0x00000001 2474 #define AR5K_PHY_CHAN_STATUS_BT_ACT 0x00000001
2475 #define AR5K_PHY_CHAN_STATUS_RX_CLR_RAW 0x00000002 2475 #define AR5K_PHY_CHAN_STATUS_RX_CLR_RAW 0x00000002
2476 #define AR5K_PHY_CHAN_STATUS_RX_CLR_MAC 0x00000004 2476 #define AR5K_PHY_CHAN_STATUS_RX_CLR_MAC 0x00000004
2477 #define AR5K_PHY_CHAN_STATUS_RX_CLR_PAP 0x00000008 2477 #define AR5K_PHY_CHAN_STATUS_RX_CLR_PAP 0x00000008
2478 2478
2479 /* 2479 /*
2480 * Heavy clip enable register 2480 * Heavy clip enable register
2481 */ 2481 */
2482 #define AR5K_PHY_HEAVY_CLIP_ENABLE 0x99e0 2482 #define AR5K_PHY_HEAVY_CLIP_ENABLE 0x99e0
2483 2483
2484 /* 2484 /*
2485 * PHY clock sleep registers [5112+] 2485 * PHY clock sleep registers [5112+]
2486 */ 2486 */
2487 #define AR5K_PHY_SCLOCK 0x99f0 2487 #define AR5K_PHY_SCLOCK 0x99f0
2488 #define AR5K_PHY_SCLOCK_32MHZ 0x0000000c 2488 #define AR5K_PHY_SCLOCK_32MHZ 0x0000000c
2489 #define AR5K_PHY_SDELAY 0x99f4 2489 #define AR5K_PHY_SDELAY 0x99f4
2490 #define AR5K_PHY_SDELAY_32MHZ 0x000000ff 2490 #define AR5K_PHY_SDELAY_32MHZ 0x000000ff
2491 #define AR5K_PHY_SPENDING 0x99f8 2491 #define AR5K_PHY_SPENDING 0x99f8
2492 2492
2493 2493
2494 /* 2494 /*
2495 * PHY PAPD I (power?) table (?) 2495 * PHY PAPD I (power?) table (?)
2496 * (92! entries) 2496 * (92! entries)
2497 */ 2497 */
2498 #define AR5K_PHY_PAPD_I_BASE 0xa000 2498 #define AR5K_PHY_PAPD_I_BASE 0xa000
2499 #define AR5K_PHY_PAPD_I(_n) (AR5K_PHY_PAPD_I_BASE + ((_n) << 2)) 2499 #define AR5K_PHY_PAPD_I(_n) (AR5K_PHY_PAPD_I_BASE + ((_n) << 2))
2500 2500
2501 /* 2501 /*
2502 * PHY PCDAC TX power table 2502 * PHY PCDAC TX power table
2503 */ 2503 */
2504 #define AR5K_PHY_PCDAC_TXPOWER_BASE 0xa180 2504 #define AR5K_PHY_PCDAC_TXPOWER_BASE 0xa180
2505 #define AR5K_PHY_PCDAC_TXPOWER(_n) (AR5K_PHY_PCDAC_TXPOWER_BASE + ((_n) << 2)) 2505 #define AR5K_PHY_PCDAC_TXPOWER(_n) (AR5K_PHY_PCDAC_TXPOWER_BASE + ((_n) << 2))
2506 2506
2507 /* 2507 /*
2508 * PHY mode register [5111+] 2508 * PHY mode register [5111+]
2509 */ 2509 */
2510 #define AR5K_PHY_MODE 0x0a200 /* Register Address */ 2510 #define AR5K_PHY_MODE 0x0a200 /* Register Address */
2511 #define AR5K_PHY_MODE_MOD 0x00000001 /* PHY Modulation bit */ 2511 #define AR5K_PHY_MODE_MOD 0x00000001 /* PHY Modulation bit */
2512 #define AR5K_PHY_MODE_MOD_OFDM 0 2512 #define AR5K_PHY_MODE_MOD_OFDM 0
2513 #define AR5K_PHY_MODE_MOD_CCK 1 2513 #define AR5K_PHY_MODE_MOD_CCK 1
2514 #define AR5K_PHY_MODE_FREQ 0x00000002 /* Freq mode bit */ 2514 #define AR5K_PHY_MODE_FREQ 0x00000002 /* Freq mode bit */
2515 #define AR5K_PHY_MODE_FREQ_5GHZ 0 2515 #define AR5K_PHY_MODE_FREQ_5GHZ 0
2516 #define AR5K_PHY_MODE_FREQ_2GHZ 2 2516 #define AR5K_PHY_MODE_FREQ_2GHZ 2
2517 #define AR5K_PHY_MODE_MOD_DYN 0x00000004 /* Enable Dynamic OFDM/CCK mode [5112+] */ 2517 #define AR5K_PHY_MODE_MOD_DYN 0x00000004 /* Enable Dynamic OFDM/CCK mode [5112+] */
2518 #define AR5K_PHY_MODE_RAD 0x00000008 /* [5212+] */ 2518 #define AR5K_PHY_MODE_RAD 0x00000008 /* [5212+] */
2519 #define AR5K_PHY_MODE_RAD_RF5111 0 2519 #define AR5K_PHY_MODE_RAD_RF5111 0
2520 #define AR5K_PHY_MODE_RAD_RF5112 8 2520 #define AR5K_PHY_MODE_RAD_RF5112 8
2521 #define AR5K_PHY_MODE_XR 0x00000010 /* Enable XR mode [5112+] */ 2521 #define AR5K_PHY_MODE_XR 0x00000010 /* Enable XR mode [5112+] */
2522 #define AR5K_PHY_MODE_HALF_RATE 0x00000020 /* Enable Half rate (test) */ 2522 #define AR5K_PHY_MODE_HALF_RATE 0x00000020 /* Enable Half rate (test) */
2523 #define AR5K_PHY_MODE_QUARTER_RATE 0x00000040 /* Enable Quarter rat (test) */ 2523 #define AR5K_PHY_MODE_QUARTER_RATE 0x00000040 /* Enable Quarter rat (test) */
2524 2524
2525 /* 2525 /*
2526 * PHY CCK transmit control register [5111+ (?)] 2526 * PHY CCK transmit control register [5111+ (?)]
2527 */ 2527 */
2528 #define AR5K_PHY_CCKTXCTL 0xa204 2528 #define AR5K_PHY_CCKTXCTL 0xa204
2529 #define AR5K_PHY_CCKTXCTL_WORLD 0x00000000 2529 #define AR5K_PHY_CCKTXCTL_WORLD 0x00000000
2530 #define AR5K_PHY_CCKTXCTL_JAPAN 0x00000010 2530 #define AR5K_PHY_CCKTXCTL_JAPAN 0x00000010
2531 #define AR5K_PHY_CCKTXCTL_SCRAMBLER_DIS 0x00000001 2531 #define AR5K_PHY_CCKTXCTL_SCRAMBLER_DIS 0x00000001
2532 #define AR5K_PHY_CCKTXCTK_DAC_SCALE 0x00000004 2532 #define AR5K_PHY_CCKTXCTK_DAC_SCALE 0x00000004
2533 2533
2534 /* 2534 /*
2535 * PHY CCK Cross-correlator Barker RSSI threshold register [5212+] 2535 * PHY CCK Cross-correlator Barker RSSI threshold register [5212+]
2536 */ 2536 */
2537 #define AR5K_PHY_CCK_CROSSCORR 0xa208 2537 #define AR5K_PHY_CCK_CROSSCORR 0xa208
2538 #define AR5K_PHY_CCK_CROSSCORR_WEAK_SIG_THR 0x0000003f 2538 #define AR5K_PHY_CCK_CROSSCORR_WEAK_SIG_THR 0x0000003f
2539 #define AR5K_PHY_CCK_CROSSCORR_WEAK_SIG_THR_S 0 2539 #define AR5K_PHY_CCK_CROSSCORR_WEAK_SIG_THR_S 0
2540 2540
2541 /* Same address is used for antenna diversity activation */ 2541 /* Same address is used for antenna diversity activation */
2542 #define AR5K_PHY_FAST_ANT_DIV 0xa208 2542 #define AR5K_PHY_FAST_ANT_DIV 0xa208
2543 #define AR5K_PHY_FAST_ANT_DIV_EN 0x00002000 2543 #define AR5K_PHY_FAST_ANT_DIV_EN 0x00002000
2544 2544
2545 /* 2545 /*
2546 * PHY 2GHz gain register [5111+] 2546 * PHY 2GHz gain register [5111+]
2547 */ 2547 */
2548 #define AR5K_PHY_GAIN_2GHZ 0xa20c 2548 #define AR5K_PHY_GAIN_2GHZ 0xa20c
2549 #define AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX 0x00fc0000 2549 #define AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX 0x00fc0000
2550 #define AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX_S 18 2550 #define AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX_S 18
2551 #define AR5K_PHY_GAIN_2GHZ_INI_5111 0x6480416c 2551 #define AR5K_PHY_GAIN_2GHZ_INI_5111 0x6480416c
2552 2552
2553 #define AR5K_PHY_CCK_RX_CTL_4 0xa21c 2553 #define AR5K_PHY_CCK_RX_CTL_4 0xa21c
2554 #define AR5K_PHY_CCK_RX_CTL_4_FREQ_EST_SHORT 0x01f80000 2554 #define AR5K_PHY_CCK_RX_CTL_4_FREQ_EST_SHORT 0x01f80000
2555 #define AR5K_PHY_CCK_RX_CTL_4_FREQ_EST_SHORT_S 19 2555 #define AR5K_PHY_CCK_RX_CTL_4_FREQ_EST_SHORT_S 19
2556 2556
2557 #define AR5K_PHY_DAG_CCK_CTL 0xa228 2557 #define AR5K_PHY_DAG_CCK_CTL 0xa228
2558 #define AR5K_PHY_DAG_CCK_CTL_EN_RSSI_THR 0x00000200 2558 #define AR5K_PHY_DAG_CCK_CTL_EN_RSSI_THR 0x00000200
2559 #define AR5K_PHY_DAG_CCK_CTL_RSSI_THR 0x0001fc00 2559 #define AR5K_PHY_DAG_CCK_CTL_RSSI_THR 0x0001fc00
2560 #define AR5K_PHY_DAG_CCK_CTL_RSSI_THR_S 10 2560 #define AR5K_PHY_DAG_CCK_CTL_RSSI_THR_S 10
2561 2561
2562 #define AR5K_PHY_FAST_ADC 0xa24c 2562 #define AR5K_PHY_FAST_ADC 0xa24c
2563 2563
2564 #define AR5K_PHY_BLUETOOTH 0xa254 2564 #define AR5K_PHY_BLUETOOTH 0xa254
2565 2565
2566 /* 2566 /*
2567 * Transmit Power Control register 2567 * Transmit Power Control register
2568 * [2413+] 2568 * [2413+]
2569 */ 2569 */
2570 #define AR5K_PHY_TPC_RG1 0xa258 2570 #define AR5K_PHY_TPC_RG1 0xa258
2571 #define AR5K_PHY_TPC_RG1_NUM_PD_GAIN 0x0000c000 2571 #define AR5K_PHY_TPC_RG1_NUM_PD_GAIN 0x0000c000
2572 #define AR5K_PHY_TPC_RG1_NUM_PD_GAIN_S 14 2572 #define AR5K_PHY_TPC_RG1_NUM_PD_GAIN_S 14
2573 #define AR5K_PHY_TPC_RG1_PDGAIN_1 0x00030000 2573 #define AR5K_PHY_TPC_RG1_PDGAIN_1 0x00030000
2574 #define AR5K_PHY_TPC_RG1_PDGAIN_1_S 16 2574 #define AR5K_PHY_TPC_RG1_PDGAIN_1_S 16
2575 #define AR5K_PHY_TPC_RG1_PDGAIN_2 0x000c0000 2575 #define AR5K_PHY_TPC_RG1_PDGAIN_2 0x000c0000
2576 #define AR5K_PHY_TPC_RG1_PDGAIN_2_S 18 2576 #define AR5K_PHY_TPC_RG1_PDGAIN_2_S 18
2577 #define AR5K_PHY_TPC_RG1_PDGAIN_3 0x00300000 2577 #define AR5K_PHY_TPC_RG1_PDGAIN_3 0x00300000
2578 #define AR5K_PHY_TPC_RG1_PDGAIN_3_S 20 2578 #define AR5K_PHY_TPC_RG1_PDGAIN_3_S 20
2579 2579
2580 #define AR5K_PHY_TPC_RG5 0xa26C 2580 #define AR5K_PHY_TPC_RG5 0xa26C
2581 #define AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP 0x0000000F 2581 #define AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP 0x0000000F
2582 #define AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP_S 0 2582 #define AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP_S 0
2583 #define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_1 0x000003F0 2583 #define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_1 0x000003F0
2584 #define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_1_S 4 2584 #define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_1_S 4
2585 #define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_2 0x0000FC00 2585 #define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_2 0x0000FC00
2586 #define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_2_S 10 2586 #define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_2_S 10
2587 #define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_3 0x003F0000 2587 #define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_3 0x003F0000
2588 #define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_3_S 16 2588 #define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_3_S 16
2589 #define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_4 0x0FC00000 2589 #define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_4 0x0FC00000
2590 #define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_4_S 22 2590 #define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_4_S 22
2591 2591
2592 /* 2592 /*
2593 * PHY PDADC Tx power table 2593 * PHY PDADC Tx power table
2594 */ 2594 */
2595 #define AR5K_PHY_PDADC_TXPOWER_BASE 0xa280 2595 #define AR5K_PHY_PDADC_TXPOWER_BASE 0xa280
2596 #define AR5K_PHY_PDADC_TXPOWER(_n) (AR5K_PHY_PDADC_TXPOWER_BASE + ((_n) << 2)) 2596 #define AR5K_PHY_PDADC_TXPOWER(_n) (AR5K_PHY_PDADC_TXPOWER_BASE + ((_n) << 2))
2597 2597
drivers/net/wireless/atmel.c
1 /*** -*- linux-c -*- ********************************************************** 1 /*** -*- linux-c -*- **********************************************************
2 2
3 Driver for Atmel at76c502 at76c504 and at76c506 wireless cards. 3 Driver for Atmel at76c502 at76c504 and at76c506 wireless cards.
4 4
5 Copyright 2000-2001 ATMEL Corporation. 5 Copyright 2000-2001 ATMEL Corporation.
6 Copyright 2003-2004 Simon Kelley. 6 Copyright 2003-2004 Simon Kelley.
7 7
8 This code was developed from version 2.1.1 of the Atmel drivers, 8 This code was developed from version 2.1.1 of the Atmel drivers,
9 released by Atmel corp. under the GPL in December 2002. It also 9 released by Atmel corp. under the GPL in December 2002. It also
10 includes code from the Linux aironet drivers (C) Benjamin Reed, 10 includes code from the Linux aironet drivers (C) Benjamin Reed,
11 and the Linux PCMCIA package, (C) David Hinds and the Linux wireless 11 and the Linux PCMCIA package, (C) David Hinds and the Linux wireless
12 extensions, (C) Jean Tourrilhes. 12 extensions, (C) Jean Tourrilhes.
13 13
14 The firmware module for reading the MAC address of the card comes from 14 The firmware module for reading the MAC address of the card comes from
15 net.russotto.AtmelMACFW, written by Matthew T. Russotto and copyright 15 net.russotto.AtmelMACFW, written by Matthew T. Russotto and copyright
16 by him. net.russotto.AtmelMACFW is used under the GPL license version 2. 16 by him. net.russotto.AtmelMACFW is used under the GPL license version 2.
17 This file contains the module in binary form and, under the terms 17 This file contains the module in binary form and, under the terms
18 of the GPL, in source form. The source is located at the end of the file. 18 of the GPL, in source form. The source is located at the end of the file.
19 19
20 This program is free software; you can redistribute it and/or modify 20 This program is free software; you can redistribute it and/or modify
21 it under the terms of the GNU General Public License as published by 21 it under the terms of the GNU General Public License as published by
22 the Free Software Foundation; either version 2 of the License, or 22 the Free Software Foundation; either version 2 of the License, or
23 (at your option) any later version. 23 (at your option) any later version.
24 24
25 This software is distributed in the hope that it will be useful, 25 This software is distributed in the hope that it will be useful,
26 but WITHOUT ANY WARRANTY; without even the implied warranty of 26 but WITHOUT ANY WARRANTY; without even the implied warranty of
27 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 27 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 GNU General Public License for more details. 28 GNU General Public License for more details.
29 29
30 You should have received a copy of the GNU General Public License 30 You should have received a copy of the GNU General Public License
31 along with Atmel wireless lan drivers; if not, write to the Free Software 31 along with Atmel wireless lan drivers; if not, write to the Free Software
32 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 32 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
33 33
34 For all queries about this code, please contact the current author, 34 For all queries about this code, please contact the current author,
35 Simon Kelley <simon@thekelleys.org.uk> and not Atmel Corporation. 35 Simon Kelley <simon@thekelleys.org.uk> and not Atmel Corporation.
36 36
37 Credit is due to HP UK and Cambridge Online Systems Ltd for supplying 37 Credit is due to HP UK and Cambridge Online Systems Ltd for supplying
38 hardware used during development of this driver. 38 hardware used during development of this driver.
39 39
40 ******************************************************************************/ 40 ******************************************************************************/
41 41
42 #include <linux/init.h> 42 #include <linux/init.h>
43 43
44 #include <linux/kernel.h> 44 #include <linux/kernel.h>
45 #include <linux/ptrace.h> 45 #include <linux/ptrace.h>
46 #include <linux/slab.h> 46 #include <linux/slab.h>
47 #include <linux/string.h> 47 #include <linux/string.h>
48 #include <linux/ctype.h> 48 #include <linux/ctype.h>
49 #include <linux/timer.h> 49 #include <linux/timer.h>
50 #include <asm/byteorder.h> 50 #include <asm/byteorder.h>
51 #include <asm/io.h> 51 #include <asm/io.h>
52 #include <asm/system.h> 52 #include <asm/system.h>
53 #include <asm/uaccess.h> 53 #include <asm/uaccess.h>
54 #include <linux/module.h> 54 #include <linux/module.h>
55 #include <linux/netdevice.h> 55 #include <linux/netdevice.h>
56 #include <linux/etherdevice.h> 56 #include <linux/etherdevice.h>
57 #include <linux/skbuff.h> 57 #include <linux/skbuff.h>
58 #include <linux/if_arp.h> 58 #include <linux/if_arp.h>
59 #include <linux/ioport.h> 59 #include <linux/ioport.h>
60 #include <linux/fcntl.h> 60 #include <linux/fcntl.h>
61 #include <linux/delay.h> 61 #include <linux/delay.h>
62 #include <linux/wireless.h> 62 #include <linux/wireless.h>
63 #include <net/iw_handler.h> 63 #include <net/iw_handler.h>
64 #include <linux/crc32.h> 64 #include <linux/crc32.h>
65 #include <linux/proc_fs.h> 65 #include <linux/proc_fs.h>
66 #include <linux/device.h> 66 #include <linux/device.h>
67 #include <linux/moduleparam.h> 67 #include <linux/moduleparam.h>
68 #include <linux/firmware.h> 68 #include <linux/firmware.h>
69 #include <linux/jiffies.h> 69 #include <linux/jiffies.h>
70 #include <linux/ieee80211.h> 70 #include <linux/ieee80211.h>
71 #include "atmel.h" 71 #include "atmel.h"
72 72
73 #define DRIVER_MAJOR 0 73 #define DRIVER_MAJOR 0
74 #define DRIVER_MINOR 98 74 #define DRIVER_MINOR 98
75 75
76 MODULE_AUTHOR("Simon Kelley"); 76 MODULE_AUTHOR("Simon Kelley");
77 MODULE_DESCRIPTION("Support for Atmel at76c50x 802.11 wireless ethernet cards."); 77 MODULE_DESCRIPTION("Support for Atmel at76c50x 802.11 wireless ethernet cards.");
78 MODULE_LICENSE("GPL"); 78 MODULE_LICENSE("GPL");
79 MODULE_SUPPORTED_DEVICE("Atmel at76c50x wireless cards"); 79 MODULE_SUPPORTED_DEVICE("Atmel at76c50x wireless cards");
80 80
81 /* The name of the firmware file to be loaded 81 /* The name of the firmware file to be loaded
82 over-rides any automatic selection */ 82 over-rides any automatic selection */
83 static char *firmware = NULL; 83 static char *firmware = NULL;
84 module_param(firmware, charp, 0); 84 module_param(firmware, charp, 0);
85 85
86 /* table of firmware file names */ 86 /* table of firmware file names */
87 static struct { 87 static struct {
88 AtmelFWType fw_type; 88 AtmelFWType fw_type;
89 const char *fw_file; 89 const char *fw_file;
90 const char *fw_file_ext; 90 const char *fw_file_ext;
91 } fw_table[] = { 91 } fw_table[] = {
92 { ATMEL_FW_TYPE_502, "atmel_at76c502", "bin" }, 92 { ATMEL_FW_TYPE_502, "atmel_at76c502", "bin" },
93 { ATMEL_FW_TYPE_502D, "atmel_at76c502d", "bin" }, 93 { ATMEL_FW_TYPE_502D, "atmel_at76c502d", "bin" },
94 { ATMEL_FW_TYPE_502E, "atmel_at76c502e", "bin" }, 94 { ATMEL_FW_TYPE_502E, "atmel_at76c502e", "bin" },
95 { ATMEL_FW_TYPE_502_3COM, "atmel_at76c502_3com", "bin" }, 95 { ATMEL_FW_TYPE_502_3COM, "atmel_at76c502_3com", "bin" },
96 { ATMEL_FW_TYPE_504, "atmel_at76c504", "bin" }, 96 { ATMEL_FW_TYPE_504, "atmel_at76c504", "bin" },
97 { ATMEL_FW_TYPE_504_2958, "atmel_at76c504_2958", "bin" }, 97 { ATMEL_FW_TYPE_504_2958, "atmel_at76c504_2958", "bin" },
98 { ATMEL_FW_TYPE_504A_2958, "atmel_at76c504a_2958", "bin" }, 98 { ATMEL_FW_TYPE_504A_2958, "atmel_at76c504a_2958", "bin" },
99 { ATMEL_FW_TYPE_506, "atmel_at76c506", "bin" }, 99 { ATMEL_FW_TYPE_506, "atmel_at76c506", "bin" },
100 { ATMEL_FW_TYPE_NONE, NULL, NULL } 100 { ATMEL_FW_TYPE_NONE, NULL, NULL }
101 }; 101 };
102 102
103 #define MAX_SSID_LENGTH 32 103 #define MAX_SSID_LENGTH 32
104 #define MGMT_JIFFIES (256 * HZ / 100) 104 #define MGMT_JIFFIES (256 * HZ / 100)
105 105
106 #define MAX_BSS_ENTRIES 64 106 #define MAX_BSS_ENTRIES 64
107 107
108 /* registers */ 108 /* registers */
109 #define GCR 0x00 /* (SIR0) General Configuration Register */ 109 #define GCR 0x00 /* (SIR0) General Configuration Register */
110 #define BSR 0x02 /* (SIR1) Bank Switching Select Register */ 110 #define BSR 0x02 /* (SIR1) Bank Switching Select Register */
111 #define AR 0x04 111 #define AR 0x04
112 #define DR 0x08 112 #define DR 0x08
113 #define MR1 0x12 /* Mirror Register 1 */ 113 #define MR1 0x12 /* Mirror Register 1 */
114 #define MR2 0x14 /* Mirror Register 2 */ 114 #define MR2 0x14 /* Mirror Register 2 */
115 #define MR3 0x16 /* Mirror Register 3 */ 115 #define MR3 0x16 /* Mirror Register 3 */
116 #define MR4 0x18 /* Mirror Register 4 */ 116 #define MR4 0x18 /* Mirror Register 4 */
117 117
118 #define GPR1 0x0c 118 #define GPR1 0x0c
119 #define GPR2 0x0e 119 #define GPR2 0x0e
120 #define GPR3 0x10 120 #define GPR3 0x10
121 /* 121 /*
122 * Constants for the GCR register. 122 * Constants for the GCR register.
123 */ 123 */
124 #define GCR_REMAP 0x0400 /* Remap internal SRAM to 0 */ 124 #define GCR_REMAP 0x0400 /* Remap internal SRAM to 0 */
125 #define GCR_SWRES 0x0080 /* BIU reset (ARM and PAI are NOT reset) */ 125 #define GCR_SWRES 0x0080 /* BIU reset (ARM and PAI are NOT reset) */
126 #define GCR_CORES 0x0060 /* Core Reset (ARM and PAI are reset) */ 126 #define GCR_CORES 0x0060 /* Core Reset (ARM and PAI are reset) */
127 #define GCR_ENINT 0x0002 /* Enable Interrupts */ 127 #define GCR_ENINT 0x0002 /* Enable Interrupts */
128 #define GCR_ACKINT 0x0008 /* Acknowledge Interrupts */ 128 #define GCR_ACKINT 0x0008 /* Acknowledge Interrupts */
129 129
130 #define BSS_SRAM 0x0200 /* AMBA module selection --> SRAM */ 130 #define BSS_SRAM 0x0200 /* AMBA module selection --> SRAM */
131 #define BSS_IRAM 0x0100 /* AMBA module selection --> IRAM */ 131 #define BSS_IRAM 0x0100 /* AMBA module selection --> IRAM */
132 /* 132 /*
133 *Constants for the MR registers. 133 *Constants for the MR registers.
134 */ 134 */
135 #define MAC_INIT_COMPLETE 0x0001 /* MAC init has been completed */ 135 #define MAC_INIT_COMPLETE 0x0001 /* MAC init has been completed */
136 #define MAC_BOOT_COMPLETE 0x0010 /* MAC boot has been completed */ 136 #define MAC_BOOT_COMPLETE 0x0010 /* MAC boot has been completed */
137 #define MAC_INIT_OK 0x0002 /* MAC boot has been completed */ 137 #define MAC_INIT_OK 0x0002 /* MAC boot has been completed */
138 138
139 #define MIB_MAX_DATA_BYTES 212 139 #define MIB_MAX_DATA_BYTES 212
140 #define MIB_HEADER_SIZE 4 /* first four fields */ 140 #define MIB_HEADER_SIZE 4 /* first four fields */
141 141
142 struct get_set_mib { 142 struct get_set_mib {
143 u8 type; 143 u8 type;
144 u8 size; 144 u8 size;
145 u8 index; 145 u8 index;
146 u8 reserved; 146 u8 reserved;
147 u8 data[MIB_MAX_DATA_BYTES]; 147 u8 data[MIB_MAX_DATA_BYTES];
148 }; 148 };
149 149
150 struct rx_desc { 150 struct rx_desc {
151 u32 Next; 151 u32 Next;
152 u16 MsduPos; 152 u16 MsduPos;
153 u16 MsduSize; 153 u16 MsduSize;
154 154
155 u8 State; 155 u8 State;
156 u8 Status; 156 u8 Status;
157 u8 Rate; 157 u8 Rate;
158 u8 Rssi; 158 u8 Rssi;
159 u8 LinkQuality; 159 u8 LinkQuality;
160 u8 PreambleType; 160 u8 PreambleType;
161 u16 Duration; 161 u16 Duration;
162 u32 RxTime; 162 u32 RxTime;
163 }; 163 };
164 164
165 #define RX_DESC_FLAG_VALID 0x80 165 #define RX_DESC_FLAG_VALID 0x80
166 #define RX_DESC_FLAG_CONSUMED 0x40 166 #define RX_DESC_FLAG_CONSUMED 0x40
167 #define RX_DESC_FLAG_IDLE 0x00 167 #define RX_DESC_FLAG_IDLE 0x00
168 168
169 #define RX_STATUS_SUCCESS 0x00 169 #define RX_STATUS_SUCCESS 0x00
170 170
171 #define RX_DESC_MSDU_POS_OFFSET 4 171 #define RX_DESC_MSDU_POS_OFFSET 4
172 #define RX_DESC_MSDU_SIZE_OFFSET 6 172 #define RX_DESC_MSDU_SIZE_OFFSET 6
173 #define RX_DESC_FLAGS_OFFSET 8 173 #define RX_DESC_FLAGS_OFFSET 8
174 #define RX_DESC_STATUS_OFFSET 9 174 #define RX_DESC_STATUS_OFFSET 9
175 #define RX_DESC_RSSI_OFFSET 11 175 #define RX_DESC_RSSI_OFFSET 11
176 #define RX_DESC_LINK_QUALITY_OFFSET 12 176 #define RX_DESC_LINK_QUALITY_OFFSET 12
177 #define RX_DESC_PREAMBLE_TYPE_OFFSET 13 177 #define RX_DESC_PREAMBLE_TYPE_OFFSET 13
178 #define RX_DESC_DURATION_OFFSET 14 178 #define RX_DESC_DURATION_OFFSET 14
179 #define RX_DESC_RX_TIME_OFFSET 16 179 #define RX_DESC_RX_TIME_OFFSET 16
180 180
181 struct tx_desc { 181 struct tx_desc {
182 u32 NextDescriptor; 182 u32 NextDescriptor;
183 u16 TxStartOfFrame; 183 u16 TxStartOfFrame;
184 u16 TxLength; 184 u16 TxLength;
185 185
186 u8 TxState; 186 u8 TxState;
187 u8 TxStatus; 187 u8 TxStatus;
188 u8 RetryCount; 188 u8 RetryCount;
189 189
190 u8 TxRate; 190 u8 TxRate;
191 191
192 u8 KeyIndex; 192 u8 KeyIndex;
193 u8 ChiperType; 193 u8 ChiperType;
194 u8 ChipreLength; 194 u8 ChipreLength;
195 u8 Reserved1; 195 u8 Reserved1;
196 196
197 u8 Reserved; 197 u8 Reserved;
198 u8 PacketType; 198 u8 PacketType;
199 u16 HostTxLength; 199 u16 HostTxLength;
200 }; 200 };
201 201
202 #define TX_DESC_NEXT_OFFSET 0 202 #define TX_DESC_NEXT_OFFSET 0
203 #define TX_DESC_POS_OFFSET 4 203 #define TX_DESC_POS_OFFSET 4
204 #define TX_DESC_SIZE_OFFSET 6 204 #define TX_DESC_SIZE_OFFSET 6
205 #define TX_DESC_FLAGS_OFFSET 8 205 #define TX_DESC_FLAGS_OFFSET 8
206 #define TX_DESC_STATUS_OFFSET 9 206 #define TX_DESC_STATUS_OFFSET 9
207 #define TX_DESC_RETRY_OFFSET 10 207 #define TX_DESC_RETRY_OFFSET 10
208 #define TX_DESC_RATE_OFFSET 11 208 #define TX_DESC_RATE_OFFSET 11
209 #define TX_DESC_KEY_INDEX_OFFSET 12 209 #define TX_DESC_KEY_INDEX_OFFSET 12
210 #define TX_DESC_CIPHER_TYPE_OFFSET 13 210 #define TX_DESC_CIPHER_TYPE_OFFSET 13
211 #define TX_DESC_CIPHER_LENGTH_OFFSET 14 211 #define TX_DESC_CIPHER_LENGTH_OFFSET 14
212 #define TX_DESC_PACKET_TYPE_OFFSET 17 212 #define TX_DESC_PACKET_TYPE_OFFSET 17
213 #define TX_DESC_HOST_LENGTH_OFFSET 18 213 #define TX_DESC_HOST_LENGTH_OFFSET 18
214 214
215 /* 215 /*
216 * Host-MAC interface 216 * Host-MAC interface
217 */ 217 */
218 218
219 #define TX_STATUS_SUCCESS 0x00 219 #define TX_STATUS_SUCCESS 0x00
220 220
221 #define TX_FIRM_OWN 0x80 221 #define TX_FIRM_OWN 0x80
222 #define TX_DONE 0x40 222 #define TX_DONE 0x40
223 223
224 #define TX_ERROR 0x01 224 #define TX_ERROR 0x01
225 225
226 #define TX_PACKET_TYPE_DATA 0x01 226 #define TX_PACKET_TYPE_DATA 0x01
227 #define TX_PACKET_TYPE_MGMT 0x02 227 #define TX_PACKET_TYPE_MGMT 0x02
228 228
229 #define ISR_EMPTY 0x00 /* no bits set in ISR */ 229 #define ISR_EMPTY 0x00 /* no bits set in ISR */
230 #define ISR_TxCOMPLETE 0x01 /* packet transmitted */ 230 #define ISR_TxCOMPLETE 0x01 /* packet transmitted */
231 #define ISR_RxCOMPLETE 0x02 /* packet received */ 231 #define ISR_RxCOMPLETE 0x02 /* packet received */
232 #define ISR_RxFRAMELOST 0x04 /* Rx Frame lost */ 232 #define ISR_RxFRAMELOST 0x04 /* Rx Frame lost */
233 #define ISR_FATAL_ERROR 0x08 /* Fatal error */ 233 #define ISR_FATAL_ERROR 0x08 /* Fatal error */
234 #define ISR_COMMAND_COMPLETE 0x10 /* command completed */ 234 #define ISR_COMMAND_COMPLETE 0x10 /* command completed */
235 #define ISR_OUT_OF_RANGE 0x20 /* command completed */ 235 #define ISR_OUT_OF_RANGE 0x20 /* command completed */
236 #define ISR_IBSS_MERGE 0x40 /* (4.1.2.30): IBSS merge */ 236 #define ISR_IBSS_MERGE 0x40 /* (4.1.2.30): IBSS merge */
237 #define ISR_GENERIC_IRQ 0x80 237 #define ISR_GENERIC_IRQ 0x80
238 238
239 #define Local_Mib_Type 0x01 239 #define Local_Mib_Type 0x01
240 #define Mac_Address_Mib_Type 0x02 240 #define Mac_Address_Mib_Type 0x02
241 #define Mac_Mib_Type 0x03 241 #define Mac_Mib_Type 0x03
242 #define Statistics_Mib_Type 0x04 242 #define Statistics_Mib_Type 0x04
243 #define Mac_Mgmt_Mib_Type 0x05 243 #define Mac_Mgmt_Mib_Type 0x05
244 #define Mac_Wep_Mib_Type 0x06 244 #define Mac_Wep_Mib_Type 0x06
245 #define Phy_Mib_Type 0x07 245 #define Phy_Mib_Type 0x07
246 #define Multi_Domain_MIB 0x08 246 #define Multi_Domain_MIB 0x08
247 247
248 #define MAC_MGMT_MIB_CUR_BSSID_POS 14 248 #define MAC_MGMT_MIB_CUR_BSSID_POS 14
249 #define MAC_MIB_FRAG_THRESHOLD_POS 8 249 #define MAC_MIB_FRAG_THRESHOLD_POS 8
250 #define MAC_MIB_RTS_THRESHOLD_POS 10 250 #define MAC_MIB_RTS_THRESHOLD_POS 10
251 #define MAC_MIB_SHORT_RETRY_POS 16 251 #define MAC_MIB_SHORT_RETRY_POS 16
252 #define MAC_MIB_LONG_RETRY_POS 17 252 #define MAC_MIB_LONG_RETRY_POS 17
253 #define MAC_MIB_SHORT_RETRY_LIMIT_POS 16 253 #define MAC_MIB_SHORT_RETRY_LIMIT_POS 16
254 #define MAC_MGMT_MIB_BEACON_PER_POS 0 254 #define MAC_MGMT_MIB_BEACON_PER_POS 0
255 #define MAC_MGMT_MIB_STATION_ID_POS 6 255 #define MAC_MGMT_MIB_STATION_ID_POS 6
256 #define MAC_MGMT_MIB_CUR_PRIVACY_POS 11 256 #define MAC_MGMT_MIB_CUR_PRIVACY_POS 11
257 #define MAC_MGMT_MIB_CUR_BSSID_POS 14 257 #define MAC_MGMT_MIB_CUR_BSSID_POS 14
258 #define MAC_MGMT_MIB_PS_MODE_POS 53 258 #define MAC_MGMT_MIB_PS_MODE_POS 53
259 #define MAC_MGMT_MIB_LISTEN_INTERVAL_POS 54 259 #define MAC_MGMT_MIB_LISTEN_INTERVAL_POS 54
260 #define MAC_MGMT_MIB_MULTI_DOMAIN_IMPLEMENTED 56 260 #define MAC_MGMT_MIB_MULTI_DOMAIN_IMPLEMENTED 56
261 #define MAC_MGMT_MIB_MULTI_DOMAIN_ENABLED 57 261 #define MAC_MGMT_MIB_MULTI_DOMAIN_ENABLED 57
262 #define PHY_MIB_CHANNEL_POS 14 262 #define PHY_MIB_CHANNEL_POS 14
263 #define PHY_MIB_RATE_SET_POS 20 263 #define PHY_MIB_RATE_SET_POS 20
264 #define PHY_MIB_REG_DOMAIN_POS 26 264 #define PHY_MIB_REG_DOMAIN_POS 26
265 #define LOCAL_MIB_AUTO_TX_RATE_POS 3 265 #define LOCAL_MIB_AUTO_TX_RATE_POS 3
266 #define LOCAL_MIB_SSID_SIZE 5 266 #define LOCAL_MIB_SSID_SIZE 5
267 #define LOCAL_MIB_TX_PROMISCUOUS_POS 6 267 #define LOCAL_MIB_TX_PROMISCUOUS_POS 6
268 #define LOCAL_MIB_TX_MGMT_RATE_POS 7 268 #define LOCAL_MIB_TX_MGMT_RATE_POS 7
269 #define LOCAL_MIB_TX_CONTROL_RATE_POS 8 269 #define LOCAL_MIB_TX_CONTROL_RATE_POS 8
270 #define LOCAL_MIB_PREAMBLE_TYPE 9 270 #define LOCAL_MIB_PREAMBLE_TYPE 9
271 #define MAC_ADDR_MIB_MAC_ADDR_POS 0 271 #define MAC_ADDR_MIB_MAC_ADDR_POS 0
272 272
273 #define CMD_Set_MIB_Vars 0x01 273 #define CMD_Set_MIB_Vars 0x01
274 #define CMD_Get_MIB_Vars 0x02 274 #define CMD_Get_MIB_Vars 0x02
275 #define CMD_Scan 0x03 275 #define CMD_Scan 0x03
276 #define CMD_Join 0x04 276 #define CMD_Join 0x04
277 #define CMD_Start 0x05 277 #define CMD_Start 0x05
278 #define CMD_EnableRadio 0x06 278 #define CMD_EnableRadio 0x06
279 #define CMD_DisableRadio 0x07 279 #define CMD_DisableRadio 0x07
280 #define CMD_SiteSurvey 0x0B 280 #define CMD_SiteSurvey 0x0B
281 281
282 #define CMD_STATUS_IDLE 0x00 282 #define CMD_STATUS_IDLE 0x00
283 #define CMD_STATUS_COMPLETE 0x01 283 #define CMD_STATUS_COMPLETE 0x01
284 #define CMD_STATUS_UNKNOWN 0x02 284 #define CMD_STATUS_UNKNOWN 0x02
285 #define CMD_STATUS_INVALID_PARAMETER 0x03 285 #define CMD_STATUS_INVALID_PARAMETER 0x03
286 #define CMD_STATUS_FUNCTION_NOT_SUPPORTED 0x04 286 #define CMD_STATUS_FUNCTION_NOT_SUPPORTED 0x04
287 #define CMD_STATUS_TIME_OUT 0x07 287 #define CMD_STATUS_TIME_OUT 0x07
288 #define CMD_STATUS_IN_PROGRESS 0x08 288 #define CMD_STATUS_IN_PROGRESS 0x08
289 #define CMD_STATUS_REJECTED_RADIO_OFF 0x09 289 #define CMD_STATUS_REJECTED_RADIO_OFF 0x09
290 #define CMD_STATUS_HOST_ERROR 0xFF 290 #define CMD_STATUS_HOST_ERROR 0xFF
291 #define CMD_STATUS_BUSY 0xFE 291 #define CMD_STATUS_BUSY 0xFE
292 292
293 #define CMD_BLOCK_COMMAND_OFFSET 0 293 #define CMD_BLOCK_COMMAND_OFFSET 0
294 #define CMD_BLOCK_STATUS_OFFSET 1 294 #define CMD_BLOCK_STATUS_OFFSET 1
295 #define CMD_BLOCK_PARAMETERS_OFFSET 4 295 #define CMD_BLOCK_PARAMETERS_OFFSET 4
296 296
297 #define SCAN_OPTIONS_SITE_SURVEY 0x80 297 #define SCAN_OPTIONS_SITE_SURVEY 0x80
298 298
299 #define MGMT_FRAME_BODY_OFFSET 24 299 #define MGMT_FRAME_BODY_OFFSET 24
300 #define MAX_AUTHENTICATION_RETRIES 3 300 #define MAX_AUTHENTICATION_RETRIES 3
301 #define MAX_ASSOCIATION_RETRIES 3 301 #define MAX_ASSOCIATION_RETRIES 3
302 302
303 #define AUTHENTICATION_RESPONSE_TIME_OUT 1000 303 #define AUTHENTICATION_RESPONSE_TIME_OUT 1000
304 304
305 #define MAX_WIRELESS_BODY 2316 /* mtu is 2312, CRC is 4 */ 305 #define MAX_WIRELESS_BODY 2316 /* mtu is 2312, CRC is 4 */
306 #define LOOP_RETRY_LIMIT 500000 306 #define LOOP_RETRY_LIMIT 500000
307 307
308 #define ACTIVE_MODE 1 308 #define ACTIVE_MODE 1
309 #define PS_MODE 2 309 #define PS_MODE 2
310 310
311 #define MAX_ENCRYPTION_KEYS 4 311 #define MAX_ENCRYPTION_KEYS 4
312 #define MAX_ENCRYPTION_KEY_SIZE 40 312 #define MAX_ENCRYPTION_KEY_SIZE 40
313 313
314 /* 314 /*
315 * 802.11 related definitions 315 * 802.11 related definitions
316 */ 316 */
317 317
318 /* 318 /*
319 * Regulatory Domains 319 * Regulatory Domains
320 */ 320 */
321 321
322 #define REG_DOMAIN_FCC 0x10 /* Channels 1-11 USA */ 322 #define REG_DOMAIN_FCC 0x10 /* Channels 1-11 USA */
323 #define REG_DOMAIN_DOC 0x20 /* Channel 1-11 Canada */ 323 #define REG_DOMAIN_DOC 0x20 /* Channel 1-11 Canada */
324 #define REG_DOMAIN_ETSI 0x30 /* Channel 1-13 Europe (ex Spain/France) */ 324 #define REG_DOMAIN_ETSI 0x30 /* Channel 1-13 Europe (ex Spain/France) */
325 #define REG_DOMAIN_SPAIN 0x31 /* Channel 10-11 Spain */ 325 #define REG_DOMAIN_SPAIN 0x31 /* Channel 10-11 Spain */
326 #define REG_DOMAIN_FRANCE 0x32 /* Channel 10-13 France */ 326 #define REG_DOMAIN_FRANCE 0x32 /* Channel 10-13 France */
327 #define REG_DOMAIN_MKK 0x40 /* Channel 14 Japan */ 327 #define REG_DOMAIN_MKK 0x40 /* Channel 14 Japan */
328 #define REG_DOMAIN_MKK1 0x41 /* Channel 1-14 Japan(MKK1) */ 328 #define REG_DOMAIN_MKK1 0x41 /* Channel 1-14 Japan(MKK1) */
329 #define REG_DOMAIN_ISRAEL 0x50 /* Channel 3-9 ISRAEL */ 329 #define REG_DOMAIN_ISRAEL 0x50 /* Channel 3-9 ISRAEL */
330 330
331 #define BSS_TYPE_AD_HOC 1 331 #define BSS_TYPE_AD_HOC 1
332 #define BSS_TYPE_INFRASTRUCTURE 2 332 #define BSS_TYPE_INFRASTRUCTURE 2
333 333
334 #define SCAN_TYPE_ACTIVE 0 334 #define SCAN_TYPE_ACTIVE 0
335 #define SCAN_TYPE_PASSIVE 1 335 #define SCAN_TYPE_PASSIVE 1
336 336
337 #define LONG_PREAMBLE 0 337 #define LONG_PREAMBLE 0
338 #define SHORT_PREAMBLE 1 338 #define SHORT_PREAMBLE 1
339 #define AUTO_PREAMBLE 2 339 #define AUTO_PREAMBLE 2
340 340
341 #define DATA_FRAME_WS_HEADER_SIZE 30 341 #define DATA_FRAME_WS_HEADER_SIZE 30
342 342
343 /* promiscuous mode control */ 343 /* promiscuous mode control */
344 #define PROM_MODE_OFF 0x0 344 #define PROM_MODE_OFF 0x0
345 #define PROM_MODE_UNKNOWN 0x1 345 #define PROM_MODE_UNKNOWN 0x1
346 #define PROM_MODE_CRC_FAILED 0x2 346 #define PROM_MODE_CRC_FAILED 0x2
347 #define PROM_MODE_DUPLICATED 0x4 347 #define PROM_MODE_DUPLICATED 0x4
348 #define PROM_MODE_MGMT 0x8 348 #define PROM_MODE_MGMT 0x8
349 #define PROM_MODE_CTRL 0x10 349 #define PROM_MODE_CTRL 0x10
350 #define PROM_MODE_BAD_PROTOCOL 0x20 350 #define PROM_MODE_BAD_PROTOCOL 0x20
351 351
352 #define IFACE_INT_STATUS_OFFSET 0 352 #define IFACE_INT_STATUS_OFFSET 0
353 #define IFACE_INT_MASK_OFFSET 1 353 #define IFACE_INT_MASK_OFFSET 1
354 #define IFACE_LOCKOUT_HOST_OFFSET 2 354 #define IFACE_LOCKOUT_HOST_OFFSET 2
355 #define IFACE_LOCKOUT_MAC_OFFSET 3 355 #define IFACE_LOCKOUT_MAC_OFFSET 3
356 #define IFACE_FUNC_CTRL_OFFSET 28 356 #define IFACE_FUNC_CTRL_OFFSET 28
357 #define IFACE_MAC_STAT_OFFSET 30 357 #define IFACE_MAC_STAT_OFFSET 30
358 #define IFACE_GENERIC_INT_TYPE_OFFSET 32 358 #define IFACE_GENERIC_INT_TYPE_OFFSET 32
359 359
360 #define CIPHER_SUITE_NONE 0 360 #define CIPHER_SUITE_NONE 0
361 #define CIPHER_SUITE_WEP_64 1 361 #define CIPHER_SUITE_WEP_64 1
362 #define CIPHER_SUITE_TKIP 2 362 #define CIPHER_SUITE_TKIP 2
363 #define CIPHER_SUITE_AES 3 363 #define CIPHER_SUITE_AES 3
364 #define CIPHER_SUITE_CCX 4 364 #define CIPHER_SUITE_CCX 4
365 #define CIPHER_SUITE_WEP_128 5 365 #define CIPHER_SUITE_WEP_128 5
366 366
367 /* 367 /*
368 * IFACE MACROS & definitions 368 * IFACE MACROS & definitions
369 */ 369 */
370 370
371 /* 371 /*
372 * FuncCtrl field: 372 * FuncCtrl field:
373 */ 373 */
374 #define FUNC_CTRL_TxENABLE 0x10 374 #define FUNC_CTRL_TxENABLE 0x10
375 #define FUNC_CTRL_RxENABLE 0x20 375 #define FUNC_CTRL_RxENABLE 0x20
376 #define FUNC_CTRL_INIT_COMPLETE 0x01 376 #define FUNC_CTRL_INIT_COMPLETE 0x01
377 377
378 /* A stub firmware image which reads the MAC address from NVRAM on the card. 378 /* A stub firmware image which reads the MAC address from NVRAM on the card.
379 For copyright information and source see the end of this file. */ 379 For copyright information and source see the end of this file. */
380 static u8 mac_reader[] = { 380 static u8 mac_reader[] = {
381 0x06, 0x00, 0x00, 0xea, 0x04, 0x00, 0x00, 0xea, 0x03, 0x00, 0x00, 0xea, 0x02, 0x00, 0x00, 0xea, 381 0x06, 0x00, 0x00, 0xea, 0x04, 0x00, 0x00, 0xea, 0x03, 0x00, 0x00, 0xea, 0x02, 0x00, 0x00, 0xea,
382 0x01, 0x00, 0x00, 0xea, 0x00, 0x00, 0x00, 0xea, 0xff, 0xff, 0xff, 0xea, 0xfe, 0xff, 0xff, 0xea, 382 0x01, 0x00, 0x00, 0xea, 0x00, 0x00, 0x00, 0xea, 0xff, 0xff, 0xff, 0xea, 0xfe, 0xff, 0xff, 0xea,
383 0xd3, 0x00, 0xa0, 0xe3, 0x00, 0xf0, 0x21, 0xe1, 0x0e, 0x04, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3, 383 0xd3, 0x00, 0xa0, 0xe3, 0x00, 0xf0, 0x21, 0xe1, 0x0e, 0x04, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3,
384 0x81, 0x11, 0xa0, 0xe1, 0x00, 0x10, 0x81, 0xe3, 0x00, 0x10, 0x80, 0xe5, 0x1c, 0x10, 0x90, 0xe5, 384 0x81, 0x11, 0xa0, 0xe1, 0x00, 0x10, 0x81, 0xe3, 0x00, 0x10, 0x80, 0xe5, 0x1c, 0x10, 0x90, 0xe5,
385 0x10, 0x10, 0xc1, 0xe3, 0x1c, 0x10, 0x80, 0xe5, 0x01, 0x10, 0xa0, 0xe3, 0x08, 0x10, 0x80, 0xe5, 385 0x10, 0x10, 0xc1, 0xe3, 0x1c, 0x10, 0x80, 0xe5, 0x01, 0x10, 0xa0, 0xe3, 0x08, 0x10, 0x80, 0xe5,
386 0x02, 0x03, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3, 0xb0, 0x10, 0xc0, 0xe1, 0xb4, 0x10, 0xc0, 0xe1, 386 0x02, 0x03, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3, 0xb0, 0x10, 0xc0, 0xe1, 0xb4, 0x10, 0xc0, 0xe1,
387 0xb8, 0x10, 0xc0, 0xe1, 0xbc, 0x10, 0xc0, 0xe1, 0x56, 0xdc, 0xa0, 0xe3, 0x21, 0x00, 0x00, 0xeb, 387 0xb8, 0x10, 0xc0, 0xe1, 0xbc, 0x10, 0xc0, 0xe1, 0x56, 0xdc, 0xa0, 0xe3, 0x21, 0x00, 0x00, 0xeb,
388 0x0a, 0x00, 0xa0, 0xe3, 0x1a, 0x00, 0x00, 0xeb, 0x10, 0x00, 0x00, 0xeb, 0x07, 0x00, 0x00, 0xeb, 388 0x0a, 0x00, 0xa0, 0xe3, 0x1a, 0x00, 0x00, 0xeb, 0x10, 0x00, 0x00, 0xeb, 0x07, 0x00, 0x00, 0xeb,
389 0x02, 0x03, 0xa0, 0xe3, 0x02, 0x14, 0xa0, 0xe3, 0xb4, 0x10, 0xc0, 0xe1, 0x4c, 0x10, 0x9f, 0xe5, 389 0x02, 0x03, 0xa0, 0xe3, 0x02, 0x14, 0xa0, 0xe3, 0xb4, 0x10, 0xc0, 0xe1, 0x4c, 0x10, 0x9f, 0xe5,
390 0xbc, 0x10, 0xc0, 0xe1, 0x10, 0x10, 0xa0, 0xe3, 0xb8, 0x10, 0xc0, 0xe1, 0xfe, 0xff, 0xff, 0xea, 390 0xbc, 0x10, 0xc0, 0xe1, 0x10, 0x10, 0xa0, 0xe3, 0xb8, 0x10, 0xc0, 0xe1, 0xfe, 0xff, 0xff, 0xea,
391 0x00, 0x40, 0x2d, 0xe9, 0x00, 0x20, 0xa0, 0xe3, 0x02, 0x3c, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3, 391 0x00, 0x40, 0x2d, 0xe9, 0x00, 0x20, 0xa0, 0xe3, 0x02, 0x3c, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3,
392 0x28, 0x00, 0x9f, 0xe5, 0x37, 0x00, 0x00, 0xeb, 0x00, 0x40, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1, 392 0x28, 0x00, 0x9f, 0xe5, 0x37, 0x00, 0x00, 0xeb, 0x00, 0x40, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1,
393 0x00, 0x40, 0x2d, 0xe9, 0x12, 0x2e, 0xa0, 0xe3, 0x06, 0x30, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3, 393 0x00, 0x40, 0x2d, 0xe9, 0x12, 0x2e, 0xa0, 0xe3, 0x06, 0x30, 0xa0, 0xe3, 0x00, 0x10, 0xa0, 0xe3,
394 0x02, 0x04, 0xa0, 0xe3, 0x2f, 0x00, 0x00, 0xeb, 0x00, 0x40, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1, 394 0x02, 0x04, 0xa0, 0xe3, 0x2f, 0x00, 0x00, 0xeb, 0x00, 0x40, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1,
395 0x00, 0x02, 0x00, 0x02, 0x80, 0x01, 0x90, 0xe0, 0x01, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x50, 0xe2, 395 0x00, 0x02, 0x00, 0x02, 0x80, 0x01, 0x90, 0xe0, 0x01, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x50, 0xe2,
396 0xfc, 0xff, 0xff, 0xea, 0x1e, 0xff, 0x2f, 0xe1, 0x80, 0x10, 0xa0, 0xe3, 0xf3, 0x06, 0xa0, 0xe3, 396 0xfc, 0xff, 0xff, 0xea, 0x1e, 0xff, 0x2f, 0xe1, 0x80, 0x10, 0xa0, 0xe3, 0xf3, 0x06, 0xa0, 0xe3,
397 0x00, 0x10, 0x80, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x80, 0xe5, 0x01, 0x10, 0xa0, 0xe3, 397 0x00, 0x10, 0x80, 0xe5, 0x00, 0x10, 0xa0, 0xe3, 0x00, 0x10, 0x80, 0xe5, 0x01, 0x10, 0xa0, 0xe3,
398 0x04, 0x10, 0x80, 0xe5, 0x00, 0x10, 0x80, 0xe5, 0x0e, 0x34, 0xa0, 0xe3, 0x1c, 0x10, 0x93, 0xe5, 398 0x04, 0x10, 0x80, 0xe5, 0x00, 0x10, 0x80, 0xe5, 0x0e, 0x34, 0xa0, 0xe3, 0x1c, 0x10, 0x93, 0xe5,
399 0x02, 0x1a, 0x81, 0xe3, 0x1c, 0x10, 0x83, 0xe5, 0x58, 0x11, 0x9f, 0xe5, 0x30, 0x10, 0x80, 0xe5, 399 0x02, 0x1a, 0x81, 0xe3, 0x1c, 0x10, 0x83, 0xe5, 0x58, 0x11, 0x9f, 0xe5, 0x30, 0x10, 0x80, 0xe5,
400 0x54, 0x11, 0x9f, 0xe5, 0x34, 0x10, 0x80, 0xe5, 0x38, 0x10, 0x80, 0xe5, 0x3c, 0x10, 0x80, 0xe5, 400 0x54, 0x11, 0x9f, 0xe5, 0x34, 0x10, 0x80, 0xe5, 0x38, 0x10, 0x80, 0xe5, 0x3c, 0x10, 0x80, 0xe5,
401 0x10, 0x10, 0x90, 0xe5, 0x08, 0x00, 0x90, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0xf3, 0x16, 0xa0, 0xe3, 401 0x10, 0x10, 0x90, 0xe5, 0x08, 0x00, 0x90, 0xe5, 0x1e, 0xff, 0x2f, 0xe1, 0xf3, 0x16, 0xa0, 0xe3,
402 0x08, 0x00, 0x91, 0xe5, 0x05, 0x00, 0xa0, 0xe3, 0x0c, 0x00, 0x81, 0xe5, 0x10, 0x00, 0x91, 0xe5, 402 0x08, 0x00, 0x91, 0xe5, 0x05, 0x00, 0xa0, 0xe3, 0x0c, 0x00, 0x81, 0xe5, 0x10, 0x00, 0x91, 0xe5,
403 0x02, 0x00, 0x10, 0xe3, 0xfc, 0xff, 0xff, 0x0a, 0xff, 0x00, 0xa0, 0xe3, 0x0c, 0x00, 0x81, 0xe5, 403 0x02, 0x00, 0x10, 0xe3, 0xfc, 0xff, 0xff, 0x0a, 0xff, 0x00, 0xa0, 0xe3, 0x0c, 0x00, 0x81, 0xe5,
404 0x10, 0x00, 0x91, 0xe5, 0x02, 0x00, 0x10, 0xe3, 0xfc, 0xff, 0xff, 0x0a, 0x08, 0x00, 0x91, 0xe5, 404 0x10, 0x00, 0x91, 0xe5, 0x02, 0x00, 0x10, 0xe3, 0xfc, 0xff, 0xff, 0x0a, 0x08, 0x00, 0x91, 0xe5,
405 0x10, 0x00, 0x91, 0xe5, 0x01, 0x00, 0x10, 0xe3, 0xfc, 0xff, 0xff, 0x0a, 0x08, 0x00, 0x91, 0xe5, 405 0x10, 0x00, 0x91, 0xe5, 0x01, 0x00, 0x10, 0xe3, 0xfc, 0xff, 0xff, 0x0a, 0x08, 0x00, 0x91, 0xe5,
406 0xff, 0x00, 0x00, 0xe2, 0x1e, 0xff, 0x2f, 0xe1, 0x30, 0x40, 0x2d, 0xe9, 0x00, 0x50, 0xa0, 0xe1, 406 0xff, 0x00, 0x00, 0xe2, 0x1e, 0xff, 0x2f, 0xe1, 0x30, 0x40, 0x2d, 0xe9, 0x00, 0x50, 0xa0, 0xe1,
407 0x03, 0x40, 0xa0, 0xe1, 0xa2, 0x02, 0xa0, 0xe1, 0x08, 0x00, 0x00, 0xe2, 0x03, 0x00, 0x80, 0xe2, 407 0x03, 0x40, 0xa0, 0xe1, 0xa2, 0x02, 0xa0, 0xe1, 0x08, 0x00, 0x00, 0xe2, 0x03, 0x00, 0x80, 0xe2,
408 0xd8, 0x10, 0x9f, 0xe5, 0x00, 0x00, 0xc1, 0xe5, 0x01, 0x20, 0xc1, 0xe5, 0xe2, 0xff, 0xff, 0xeb, 408 0xd8, 0x10, 0x9f, 0xe5, 0x00, 0x00, 0xc1, 0xe5, 0x01, 0x20, 0xc1, 0xe5, 0xe2, 0xff, 0xff, 0xeb,
409 0x01, 0x00, 0x10, 0xe3, 0xfc, 0xff, 0xff, 0x1a, 0x14, 0x00, 0xa0, 0xe3, 0xc4, 0xff, 0xff, 0xeb, 409 0x01, 0x00, 0x10, 0xe3, 0xfc, 0xff, 0xff, 0x1a, 0x14, 0x00, 0xa0, 0xe3, 0xc4, 0xff, 0xff, 0xeb,
410 0x04, 0x20, 0xa0, 0xe1, 0x05, 0x10, 0xa0, 0xe1, 0x02, 0x00, 0xa0, 0xe3, 0x01, 0x00, 0x00, 0xeb, 410 0x04, 0x20, 0xa0, 0xe1, 0x05, 0x10, 0xa0, 0xe1, 0x02, 0x00, 0xa0, 0xe3, 0x01, 0x00, 0x00, 0xeb,
411 0x30, 0x40, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1, 0x70, 0x40, 0x2d, 0xe9, 0xf3, 0x46, 0xa0, 0xe3, 411 0x30, 0x40, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1, 0x70, 0x40, 0x2d, 0xe9, 0xf3, 0x46, 0xa0, 0xe3,
412 0x00, 0x30, 0xa0, 0xe3, 0x00, 0x00, 0x50, 0xe3, 0x08, 0x00, 0x00, 0x9a, 0x8c, 0x50, 0x9f, 0xe5, 412 0x00, 0x30, 0xa0, 0xe3, 0x00, 0x00, 0x50, 0xe3, 0x08, 0x00, 0x00, 0x9a, 0x8c, 0x50, 0x9f, 0xe5,
413 0x03, 0x60, 0xd5, 0xe7, 0x0c, 0x60, 0x84, 0xe5, 0x10, 0x60, 0x94, 0xe5, 0x02, 0x00, 0x16, 0xe3, 413 0x03, 0x60, 0xd5, 0xe7, 0x0c, 0x60, 0x84, 0xe5, 0x10, 0x60, 0x94, 0xe5, 0x02, 0x00, 0x16, 0xe3,
414 0xfc, 0xff, 0xff, 0x0a, 0x01, 0x30, 0x83, 0xe2, 0x00, 0x00, 0x53, 0xe1, 0xf7, 0xff, 0xff, 0x3a, 414 0xfc, 0xff, 0xff, 0x0a, 0x01, 0x30, 0x83, 0xe2, 0x00, 0x00, 0x53, 0xe1, 0xf7, 0xff, 0xff, 0x3a,
415 0xff, 0x30, 0xa0, 0xe3, 0x0c, 0x30, 0x84, 0xe5, 0x08, 0x00, 0x94, 0xe5, 0x10, 0x00, 0x94, 0xe5, 415 0xff, 0x30, 0xa0, 0xe3, 0x0c, 0x30, 0x84, 0xe5, 0x08, 0x00, 0x94, 0xe5, 0x10, 0x00, 0x94, 0xe5,
416 0x01, 0x00, 0x10, 0xe3, 0xfc, 0xff, 0xff, 0x0a, 0x08, 0x00, 0x94, 0xe5, 0x00, 0x00, 0xa0, 0xe3, 416 0x01, 0x00, 0x10, 0xe3, 0xfc, 0xff, 0xff, 0x0a, 0x08, 0x00, 0x94, 0xe5, 0x00, 0x00, 0xa0, 0xe3,
417 0x00, 0x00, 0x52, 0xe3, 0x0b, 0x00, 0x00, 0x9a, 0x10, 0x50, 0x94, 0xe5, 0x02, 0x00, 0x15, 0xe3, 417 0x00, 0x00, 0x52, 0xe3, 0x0b, 0x00, 0x00, 0x9a, 0x10, 0x50, 0x94, 0xe5, 0x02, 0x00, 0x15, 0xe3,
418 0xfc, 0xff, 0xff, 0x0a, 0x0c, 0x30, 0x84, 0xe5, 0x10, 0x50, 0x94, 0xe5, 0x01, 0x00, 0x15, 0xe3, 418 0xfc, 0xff, 0xff, 0x0a, 0x0c, 0x30, 0x84, 0xe5, 0x10, 0x50, 0x94, 0xe5, 0x01, 0x00, 0x15, 0xe3,
419 0xfc, 0xff, 0xff, 0x0a, 0x08, 0x50, 0x94, 0xe5, 0x01, 0x50, 0xc1, 0xe4, 0x01, 0x00, 0x80, 0xe2, 419 0xfc, 0xff, 0xff, 0x0a, 0x08, 0x50, 0x94, 0xe5, 0x01, 0x50, 0xc1, 0xe4, 0x01, 0x00, 0x80, 0xe2,
420 0x02, 0x00, 0x50, 0xe1, 0xf3, 0xff, 0xff, 0x3a, 0xc8, 0x00, 0xa0, 0xe3, 0x98, 0xff, 0xff, 0xeb, 420 0x02, 0x00, 0x50, 0xe1, 0xf3, 0xff, 0xff, 0x3a, 0xc8, 0x00, 0xa0, 0xe3, 0x98, 0xff, 0xff, 0xeb,
421 0x70, 0x40, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1, 0x01, 0x0c, 0x00, 0x02, 0x01, 0x02, 0x00, 0x02, 421 0x70, 0x40, 0xbd, 0xe8, 0x1e, 0xff, 0x2f, 0xe1, 0x01, 0x0c, 0x00, 0x02, 0x01, 0x02, 0x00, 0x02,
422 0x00, 0x01, 0x00, 0x02 422 0x00, 0x01, 0x00, 0x02
423 }; 423 };
424 424
425 struct atmel_private { 425 struct atmel_private {
426 void *card; /* Bus dependent stucture varies for PCcard */ 426 void *card; /* Bus dependent stucture varies for PCcard */
427 int (*present_callback)(void *); /* And callback which uses it */ 427 int (*present_callback)(void *); /* And callback which uses it */
428 char firmware_id[32]; 428 char firmware_id[32];
429 AtmelFWType firmware_type; 429 AtmelFWType firmware_type;
430 u8 *firmware; 430 u8 *firmware;
431 int firmware_length; 431 int firmware_length;
432 struct timer_list management_timer; 432 struct timer_list management_timer;
433 struct net_device *dev; 433 struct net_device *dev;
434 struct device *sys_dev; 434 struct device *sys_dev;
435 struct iw_statistics wstats; 435 struct iw_statistics wstats;
436 spinlock_t irqlock, timerlock; /* spinlocks */ 436 spinlock_t irqlock, timerlock; /* spinlocks */
437 enum { BUS_TYPE_PCCARD, BUS_TYPE_PCI } bus_type; 437 enum { BUS_TYPE_PCCARD, BUS_TYPE_PCI } bus_type;
438 enum { 438 enum {
439 CARD_TYPE_PARALLEL_FLASH, 439 CARD_TYPE_PARALLEL_FLASH,
440 CARD_TYPE_SPI_FLASH, 440 CARD_TYPE_SPI_FLASH,
441 CARD_TYPE_EEPROM 441 CARD_TYPE_EEPROM
442 } card_type; 442 } card_type;
443 int do_rx_crc; /* If we need to CRC incoming packets */ 443 int do_rx_crc; /* If we need to CRC incoming packets */
444 int probe_crc; /* set if we don't yet know */ 444 int probe_crc; /* set if we don't yet know */
445 int crc_ok_cnt, crc_ko_cnt; /* counters for probing */ 445 int crc_ok_cnt, crc_ko_cnt; /* counters for probing */
446 u16 rx_desc_head; 446 u16 rx_desc_head;
447 u16 tx_desc_free, tx_desc_head, tx_desc_tail, tx_desc_previous; 447 u16 tx_desc_free, tx_desc_head, tx_desc_tail, tx_desc_previous;
448 u16 tx_free_mem, tx_buff_head, tx_buff_tail; 448 u16 tx_free_mem, tx_buff_head, tx_buff_tail;
449 449
450 u16 frag_seq, frag_len, frag_no; 450 u16 frag_seq, frag_len, frag_no;
451 u8 frag_source[6]; 451 u8 frag_source[6];
452 452
453 u8 wep_is_on, default_key, exclude_unencrypted, encryption_level; 453 u8 wep_is_on, default_key, exclude_unencrypted, encryption_level;
454 u8 group_cipher_suite, pairwise_cipher_suite; 454 u8 group_cipher_suite, pairwise_cipher_suite;
455 u8 wep_keys[MAX_ENCRYPTION_KEYS][MAX_ENCRYPTION_KEY_SIZE]; 455 u8 wep_keys[MAX_ENCRYPTION_KEYS][MAX_ENCRYPTION_KEY_SIZE];
456 int wep_key_len[MAX_ENCRYPTION_KEYS]; 456 int wep_key_len[MAX_ENCRYPTION_KEYS];
457 int use_wpa, radio_on_broken; /* firmware dependent stuff. */ 457 int use_wpa, radio_on_broken; /* firmware dependent stuff. */
458 458
459 u16 host_info_base; 459 u16 host_info_base;
460 struct host_info_struct { 460 struct host_info_struct {
461 /* NB this is matched to the hardware, don't change. */ 461 /* NB this is matched to the hardware, don't change. */
462 u8 volatile int_status; 462 u8 volatile int_status;
463 u8 volatile int_mask; 463 u8 volatile int_mask;
464 u8 volatile lockout_host; 464 u8 volatile lockout_host;
465 u8 volatile lockout_mac; 465 u8 volatile lockout_mac;
466 466
467 u16 tx_buff_pos; 467 u16 tx_buff_pos;
468 u16 tx_buff_size; 468 u16 tx_buff_size;
469 u16 tx_desc_pos; 469 u16 tx_desc_pos;
470 u16 tx_desc_count; 470 u16 tx_desc_count;
471 471
472 u16 rx_buff_pos; 472 u16 rx_buff_pos;
473 u16 rx_buff_size; 473 u16 rx_buff_size;
474 u16 rx_desc_pos; 474 u16 rx_desc_pos;
475 u16 rx_desc_count; 475 u16 rx_desc_count;
476 476
477 u16 build_version; 477 u16 build_version;
478 u16 command_pos; 478 u16 command_pos;
479 479
480 u16 major_version; 480 u16 major_version;
481 u16 minor_version; 481 u16 minor_version;
482 482
483 u16 func_ctrl; 483 u16 func_ctrl;
484 u16 mac_status; 484 u16 mac_status;
485 u16 generic_IRQ_type; 485 u16 generic_IRQ_type;
486 u8 reserved[2]; 486 u8 reserved[2];
487 } host_info; 487 } host_info;
488 488
489 enum { 489 enum {
490 STATION_STATE_SCANNING, 490 STATION_STATE_SCANNING,
491 STATION_STATE_JOINNING, 491 STATION_STATE_JOINNING,
492 STATION_STATE_AUTHENTICATING, 492 STATION_STATE_AUTHENTICATING,
493 STATION_STATE_ASSOCIATING, 493 STATION_STATE_ASSOCIATING,
494 STATION_STATE_READY, 494 STATION_STATE_READY,
495 STATION_STATE_REASSOCIATING, 495 STATION_STATE_REASSOCIATING,
496 STATION_STATE_DOWN, 496 STATION_STATE_DOWN,
497 STATION_STATE_MGMT_ERROR 497 STATION_STATE_MGMT_ERROR
498 } station_state; 498 } station_state;
499 499
500 int operating_mode, power_mode; 500 int operating_mode, power_mode;
501 time_t last_qual; 501 time_t last_qual;
502 int beacons_this_sec; 502 int beacons_this_sec;
503 int channel; 503 int channel;
504 int reg_domain, config_reg_domain; 504 int reg_domain, config_reg_domain;
505 int tx_rate; 505 int tx_rate;
506 int auto_tx_rate; 506 int auto_tx_rate;
507 int rts_threshold; 507 int rts_threshold;
508 int frag_threshold; 508 int frag_threshold;
509 int long_retry, short_retry; 509 int long_retry, short_retry;
510 int preamble; 510 int preamble;
511 int default_beacon_period, beacon_period, listen_interval; 511 int default_beacon_period, beacon_period, listen_interval;
512 int CurrentAuthentTransactionSeqNum, ExpectedAuthentTransactionSeqNum; 512 int CurrentAuthentTransactionSeqNum, ExpectedAuthentTransactionSeqNum;
513 int AuthenticationRequestRetryCnt, AssociationRequestRetryCnt, ReAssociationRequestRetryCnt; 513 int AuthenticationRequestRetryCnt, AssociationRequestRetryCnt, ReAssociationRequestRetryCnt;
514 enum { 514 enum {
515 SITE_SURVEY_IDLE, 515 SITE_SURVEY_IDLE,
516 SITE_SURVEY_IN_PROGRESS, 516 SITE_SURVEY_IN_PROGRESS,
517 SITE_SURVEY_COMPLETED 517 SITE_SURVEY_COMPLETED
518 } site_survey_state; 518 } site_survey_state;
519 unsigned long last_survey; 519 unsigned long last_survey;
520 520
521 int station_was_associated, station_is_associated; 521 int station_was_associated, station_is_associated;
522 int fast_scan; 522 int fast_scan;
523 523
524 struct bss_info { 524 struct bss_info {
525 int channel; 525 int channel;
526 int SSIDsize; 526 int SSIDsize;
527 int RSSI; 527 int RSSI;
528 int UsingWEP; 528 int UsingWEP;
529 int preamble; 529 int preamble;
530 int beacon_period; 530 int beacon_period;
531 int BSStype; 531 int BSStype;
532 u8 BSSID[6]; 532 u8 BSSID[6];
533 u8 SSID[MAX_SSID_LENGTH]; 533 u8 SSID[MAX_SSID_LENGTH];
534 } BSSinfo[MAX_BSS_ENTRIES]; 534 } BSSinfo[MAX_BSS_ENTRIES];
535 int BSS_list_entries, current_BSS; 535 int BSS_list_entries, current_BSS;
536 int connect_to_any_BSS; 536 int connect_to_any_BSS;
537 int SSID_size, new_SSID_size; 537 int SSID_size, new_SSID_size;
538 u8 CurrentBSSID[6], BSSID[6]; 538 u8 CurrentBSSID[6], BSSID[6];
539 u8 SSID[MAX_SSID_LENGTH], new_SSID[MAX_SSID_LENGTH]; 539 u8 SSID[MAX_SSID_LENGTH], new_SSID[MAX_SSID_LENGTH];
540 u64 last_beacon_timestamp; 540 u64 last_beacon_timestamp;
541 u8 rx_buf[MAX_WIRELESS_BODY]; 541 u8 rx_buf[MAX_WIRELESS_BODY];
542 }; 542 };
543 543
544 static u8 atmel_basic_rates[4] = {0x82, 0x84, 0x0b, 0x16}; 544 static u8 atmel_basic_rates[4] = {0x82, 0x84, 0x0b, 0x16};
545 545
546 static const struct { 546 static const struct {
547 int reg_domain; 547 int reg_domain;
548 int min, max; 548 int min, max;
549 char *name; 549 char *name;
550 } channel_table[] = { { REG_DOMAIN_FCC, 1, 11, "USA" }, 550 } channel_table[] = { { REG_DOMAIN_FCC, 1, 11, "USA" },
551 { REG_DOMAIN_DOC, 1, 11, "Canada" }, 551 { REG_DOMAIN_DOC, 1, 11, "Canada" },
552 { REG_DOMAIN_ETSI, 1, 13, "Europe" }, 552 { REG_DOMAIN_ETSI, 1, 13, "Europe" },
553 { REG_DOMAIN_SPAIN, 10, 11, "Spain" }, 553 { REG_DOMAIN_SPAIN, 10, 11, "Spain" },
554 { REG_DOMAIN_FRANCE, 10, 13, "France" }, 554 { REG_DOMAIN_FRANCE, 10, 13, "France" },
555 { REG_DOMAIN_MKK, 14, 14, "MKK" }, 555 { REG_DOMAIN_MKK, 14, 14, "MKK" },
556 { REG_DOMAIN_MKK1, 1, 14, "MKK1" }, 556 { REG_DOMAIN_MKK1, 1, 14, "MKK1" },
557 { REG_DOMAIN_ISRAEL, 3, 9, "Israel"} }; 557 { REG_DOMAIN_ISRAEL, 3, 9, "Israel"} };
558 558
559 static void build_wpa_mib(struct atmel_private *priv); 559 static void build_wpa_mib(struct atmel_private *priv);
560 static int atmel_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); 560 static int atmel_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
561 static void atmel_copy_to_card(struct net_device *dev, u16 dest, 561 static void atmel_copy_to_card(struct net_device *dev, u16 dest,
562 const unsigned char *src, u16 len); 562 const unsigned char *src, u16 len);
563 static void atmel_copy_to_host(struct net_device *dev, unsigned char *dest, 563 static void atmel_copy_to_host(struct net_device *dev, unsigned char *dest,
564 u16 src, u16 len); 564 u16 src, u16 len);
565 static void atmel_set_gcr(struct net_device *dev, u16 mask); 565 static void atmel_set_gcr(struct net_device *dev, u16 mask);
566 static void atmel_clear_gcr(struct net_device *dev, u16 mask); 566 static void atmel_clear_gcr(struct net_device *dev, u16 mask);
567 static int atmel_lock_mac(struct atmel_private *priv); 567 static int atmel_lock_mac(struct atmel_private *priv);
568 static void atmel_wmem32(struct atmel_private *priv, u16 pos, u32 data); 568 static void atmel_wmem32(struct atmel_private *priv, u16 pos, u32 data);
569 static void atmel_command_irq(struct atmel_private *priv); 569 static void atmel_command_irq(struct atmel_private *priv);
570 static int atmel_validate_channel(struct atmel_private *priv, int channel); 570 static int atmel_validate_channel(struct atmel_private *priv, int channel);
571 static void atmel_management_frame(struct atmel_private *priv, 571 static void atmel_management_frame(struct atmel_private *priv,
572 struct ieee80211_hdr *header, 572 struct ieee80211_hdr *header,
573 u16 frame_len, u8 rssi); 573 u16 frame_len, u8 rssi);
574 static void atmel_management_timer(u_long a); 574 static void atmel_management_timer(u_long a);
575 static void atmel_send_command(struct atmel_private *priv, int command, 575 static void atmel_send_command(struct atmel_private *priv, int command,
576 void *cmd, int cmd_size); 576 void *cmd, int cmd_size);
577 static int atmel_send_command_wait(struct atmel_private *priv, int command, 577 static int atmel_send_command_wait(struct atmel_private *priv, int command,
578 void *cmd, int cmd_size); 578 void *cmd, int cmd_size);
579 static void atmel_transmit_management_frame(struct atmel_private *priv, 579 static void atmel_transmit_management_frame(struct atmel_private *priv,
580 struct ieee80211_hdr *header, 580 struct ieee80211_hdr *header,
581 u8 *body, int body_len); 581 u8 *body, int body_len);
582 582
583 static u8 atmel_get_mib8(struct atmel_private *priv, u8 type, u8 index); 583 static u8 atmel_get_mib8(struct atmel_private *priv, u8 type, u8 index);
584 static void atmel_set_mib8(struct atmel_private *priv, u8 type, u8 index, 584 static void atmel_set_mib8(struct atmel_private *priv, u8 type, u8 index,
585 u8 data); 585 u8 data);
586 static void atmel_set_mib16(struct atmel_private *priv, u8 type, u8 index, 586 static void atmel_set_mib16(struct atmel_private *priv, u8 type, u8 index,
587 u16 data); 587 u16 data);
588 static void atmel_set_mib(struct atmel_private *priv, u8 type, u8 index, 588 static void atmel_set_mib(struct atmel_private *priv, u8 type, u8 index,
589 u8 *data, int data_len); 589 u8 *data, int data_len);
590 static void atmel_get_mib(struct atmel_private *priv, u8 type, u8 index, 590 static void atmel_get_mib(struct atmel_private *priv, u8 type, u8 index,
591 u8 *data, int data_len); 591 u8 *data, int data_len);
592 static void atmel_scan(struct atmel_private *priv, int specific_ssid); 592 static void atmel_scan(struct atmel_private *priv, int specific_ssid);
593 static void atmel_join_bss(struct atmel_private *priv, int bss_index); 593 static void atmel_join_bss(struct atmel_private *priv, int bss_index);
594 static void atmel_smooth_qual(struct atmel_private *priv); 594 static void atmel_smooth_qual(struct atmel_private *priv);
595 static void atmel_writeAR(struct net_device *dev, u16 data); 595 static void atmel_writeAR(struct net_device *dev, u16 data);
596 static int probe_atmel_card(struct net_device *dev); 596 static int probe_atmel_card(struct net_device *dev);
597 static int reset_atmel_card(struct net_device *dev); 597 static int reset_atmel_card(struct net_device *dev);
598 static void atmel_enter_state(struct atmel_private *priv, int new_state); 598 static void atmel_enter_state(struct atmel_private *priv, int new_state);
599 int atmel_open (struct net_device *dev); 599 int atmel_open (struct net_device *dev);
600 600
601 static inline u16 atmel_hi(struct atmel_private *priv, u16 offset) 601 static inline u16 atmel_hi(struct atmel_private *priv, u16 offset)
602 { 602 {
603 return priv->host_info_base + offset; 603 return priv->host_info_base + offset;
604 } 604 }
605 605
606 static inline u16 atmel_co(struct atmel_private *priv, u16 offset) 606 static inline u16 atmel_co(struct atmel_private *priv, u16 offset)
607 { 607 {
608 return priv->host_info.command_pos + offset; 608 return priv->host_info.command_pos + offset;
609 } 609 }
610 610
611 static inline u16 atmel_rx(struct atmel_private *priv, u16 offset, u16 desc) 611 static inline u16 atmel_rx(struct atmel_private *priv, u16 offset, u16 desc)
612 { 612 {
613 return priv->host_info.rx_desc_pos + (sizeof(struct rx_desc) * desc) + offset; 613 return priv->host_info.rx_desc_pos + (sizeof(struct rx_desc) * desc) + offset;
614 } 614 }
615 615
616 static inline u16 atmel_tx(struct atmel_private *priv, u16 offset, u16 desc) 616 static inline u16 atmel_tx(struct atmel_private *priv, u16 offset, u16 desc)
617 { 617 {
618 return priv->host_info.tx_desc_pos + (sizeof(struct tx_desc) * desc) + offset; 618 return priv->host_info.tx_desc_pos + (sizeof(struct tx_desc) * desc) + offset;
619 } 619 }
620 620
621 static inline u8 atmel_read8(struct net_device *dev, u16 offset) 621 static inline u8 atmel_read8(struct net_device *dev, u16 offset)
622 { 622 {
623 return inb(dev->base_addr + offset); 623 return inb(dev->base_addr + offset);
624 } 624 }
625 625
626 static inline void atmel_write8(struct net_device *dev, u16 offset, u8 data) 626 static inline void atmel_write8(struct net_device *dev, u16 offset, u8 data)
627 { 627 {
628 outb(data, dev->base_addr + offset); 628 outb(data, dev->base_addr + offset);
629 } 629 }
630 630
631 static inline u16 atmel_read16(struct net_device *dev, u16 offset) 631 static inline u16 atmel_read16(struct net_device *dev, u16 offset)
632 { 632 {
633 return inw(dev->base_addr + offset); 633 return inw(dev->base_addr + offset);
634 } 634 }
635 635
636 static inline void atmel_write16(struct net_device *dev, u16 offset, u16 data) 636 static inline void atmel_write16(struct net_device *dev, u16 offset, u16 data)
637 { 637 {
638 outw(data, dev->base_addr + offset); 638 outw(data, dev->base_addr + offset);
639 } 639 }
640 640
641 static inline u8 atmel_rmem8(struct atmel_private *priv, u16 pos) 641 static inline u8 atmel_rmem8(struct atmel_private *priv, u16 pos)
642 { 642 {
643 atmel_writeAR(priv->dev, pos); 643 atmel_writeAR(priv->dev, pos);
644 return atmel_read8(priv->dev, DR); 644 return atmel_read8(priv->dev, DR);
645 } 645 }
646 646
647 static inline void atmel_wmem8(struct atmel_private *priv, u16 pos, u16 data) 647 static inline void atmel_wmem8(struct atmel_private *priv, u16 pos, u16 data)
648 { 648 {
649 atmel_writeAR(priv->dev, pos); 649 atmel_writeAR(priv->dev, pos);
650 atmel_write8(priv->dev, DR, data); 650 atmel_write8(priv->dev, DR, data);
651 } 651 }
652 652
653 static inline u16 atmel_rmem16(struct atmel_private *priv, u16 pos) 653 static inline u16 atmel_rmem16(struct atmel_private *priv, u16 pos)
654 { 654 {
655 atmel_writeAR(priv->dev, pos); 655 atmel_writeAR(priv->dev, pos);
656 return atmel_read16(priv->dev, DR); 656 return atmel_read16(priv->dev, DR);
657 } 657 }
658 658
659 static inline void atmel_wmem16(struct atmel_private *priv, u16 pos, u16 data) 659 static inline void atmel_wmem16(struct atmel_private *priv, u16 pos, u16 data)
660 { 660 {
661 atmel_writeAR(priv->dev, pos); 661 atmel_writeAR(priv->dev, pos);
662 atmel_write16(priv->dev, DR, data); 662 atmel_write16(priv->dev, DR, data);
663 } 663 }
664 664
665 static const struct iw_handler_def atmel_handler_def; 665 static const struct iw_handler_def atmel_handler_def;
666 666
667 static void tx_done_irq(struct atmel_private *priv) 667 static void tx_done_irq(struct atmel_private *priv)
668 { 668 {
669 int i; 669 int i;
670 670
671 for (i = 0; 671 for (i = 0;
672 atmel_rmem8(priv, atmel_tx(priv, TX_DESC_FLAGS_OFFSET, priv->tx_desc_head)) == TX_DONE && 672 atmel_rmem8(priv, atmel_tx(priv, TX_DESC_FLAGS_OFFSET, priv->tx_desc_head)) == TX_DONE &&
673 i < priv->host_info.tx_desc_count; 673 i < priv->host_info.tx_desc_count;
674 i++) { 674 i++) {
675 u8 status = atmel_rmem8(priv, atmel_tx(priv, TX_DESC_STATUS_OFFSET, priv->tx_desc_head)); 675 u8 status = atmel_rmem8(priv, atmel_tx(priv, TX_DESC_STATUS_OFFSET, priv->tx_desc_head));
676 u16 msdu_size = atmel_rmem16(priv, atmel_tx(priv, TX_DESC_SIZE_OFFSET, priv->tx_desc_head)); 676 u16 msdu_size = atmel_rmem16(priv, atmel_tx(priv, TX_DESC_SIZE_OFFSET, priv->tx_desc_head));
677 u8 type = atmel_rmem8(priv, atmel_tx(priv, TX_DESC_PACKET_TYPE_OFFSET, priv->tx_desc_head)); 677 u8 type = atmel_rmem8(priv, atmel_tx(priv, TX_DESC_PACKET_TYPE_OFFSET, priv->tx_desc_head));
678 678
679 atmel_wmem8(priv, atmel_tx(priv, TX_DESC_FLAGS_OFFSET, priv->tx_desc_head), 0); 679 atmel_wmem8(priv, atmel_tx(priv, TX_DESC_FLAGS_OFFSET, priv->tx_desc_head), 0);
680 680
681 priv->tx_free_mem += msdu_size; 681 priv->tx_free_mem += msdu_size;
682 priv->tx_desc_free++; 682 priv->tx_desc_free++;
683 683
684 if (priv->tx_buff_head + msdu_size > (priv->host_info.tx_buff_pos + priv->host_info.tx_buff_size)) 684 if (priv->tx_buff_head + msdu_size > (priv->host_info.tx_buff_pos + priv->host_info.tx_buff_size))
685 priv->tx_buff_head = 0; 685 priv->tx_buff_head = 0;
686 else 686 else
687 priv->tx_buff_head += msdu_size; 687 priv->tx_buff_head += msdu_size;
688 688
689 if (priv->tx_desc_head < (priv->host_info.tx_desc_count - 1)) 689 if (priv->tx_desc_head < (priv->host_info.tx_desc_count - 1))
690 priv->tx_desc_head++ ; 690 priv->tx_desc_head++ ;
691 else 691 else
692 priv->tx_desc_head = 0; 692 priv->tx_desc_head = 0;
693 693
694 if (type == TX_PACKET_TYPE_DATA) { 694 if (type == TX_PACKET_TYPE_DATA) {
695 if (status == TX_STATUS_SUCCESS) 695 if (status == TX_STATUS_SUCCESS)
696 priv->dev->stats.tx_packets++; 696 priv->dev->stats.tx_packets++;
697 else 697 else
698 priv->dev->stats.tx_errors++; 698 priv->dev->stats.tx_errors++;
699 netif_wake_queue(priv->dev); 699 netif_wake_queue(priv->dev);
700 } 700 }
701 } 701 }
702 } 702 }
703 703
704 static u16 find_tx_buff(struct atmel_private *priv, u16 len) 704 static u16 find_tx_buff(struct atmel_private *priv, u16 len)
705 { 705 {
706 u16 bottom_free = priv->host_info.tx_buff_size - priv->tx_buff_tail; 706 u16 bottom_free = priv->host_info.tx_buff_size - priv->tx_buff_tail;
707 707
708 if (priv->tx_desc_free == 3 || priv->tx_free_mem < len) 708 if (priv->tx_desc_free == 3 || priv->tx_free_mem < len)
709 return 0; 709 return 0;
710 710
711 if (bottom_free >= len) 711 if (bottom_free >= len)
712 return priv->host_info.tx_buff_pos + priv->tx_buff_tail; 712 return priv->host_info.tx_buff_pos + priv->tx_buff_tail;
713 713
714 if (priv->tx_free_mem - bottom_free >= len) { 714 if (priv->tx_free_mem - bottom_free >= len) {
715 priv->tx_buff_tail = 0; 715 priv->tx_buff_tail = 0;
716 return priv->host_info.tx_buff_pos; 716 return priv->host_info.tx_buff_pos;
717 } 717 }
718 718
719 return 0; 719 return 0;
720 } 720 }
721 721
722 static void tx_update_descriptor(struct atmel_private *priv, int is_bcast, 722 static void tx_update_descriptor(struct atmel_private *priv, int is_bcast,
723 u16 len, u16 buff, u8 type) 723 u16 len, u16 buff, u8 type)
724 { 724 {
725 atmel_wmem16(priv, atmel_tx(priv, TX_DESC_POS_OFFSET, priv->tx_desc_tail), buff); 725 atmel_wmem16(priv, atmel_tx(priv, TX_DESC_POS_OFFSET, priv->tx_desc_tail), buff);
726 atmel_wmem16(priv, atmel_tx(priv, TX_DESC_SIZE_OFFSET, priv->tx_desc_tail), len); 726 atmel_wmem16(priv, atmel_tx(priv, TX_DESC_SIZE_OFFSET, priv->tx_desc_tail), len);
727 if (!priv->use_wpa) 727 if (!priv->use_wpa)
728 atmel_wmem16(priv, atmel_tx(priv, TX_DESC_HOST_LENGTH_OFFSET, priv->tx_desc_tail), len); 728 atmel_wmem16(priv, atmel_tx(priv, TX_DESC_HOST_LENGTH_OFFSET, priv->tx_desc_tail), len);
729 atmel_wmem8(priv, atmel_tx(priv, TX_DESC_PACKET_TYPE_OFFSET, priv->tx_desc_tail), type); 729 atmel_wmem8(priv, atmel_tx(priv, TX_DESC_PACKET_TYPE_OFFSET, priv->tx_desc_tail), type);
730 atmel_wmem8(priv, atmel_tx(priv, TX_DESC_RATE_OFFSET, priv->tx_desc_tail), priv->tx_rate); 730 atmel_wmem8(priv, atmel_tx(priv, TX_DESC_RATE_OFFSET, priv->tx_desc_tail), priv->tx_rate);
731 atmel_wmem8(priv, atmel_tx(priv, TX_DESC_RETRY_OFFSET, priv->tx_desc_tail), 0); 731 atmel_wmem8(priv, atmel_tx(priv, TX_DESC_RETRY_OFFSET, priv->tx_desc_tail), 0);
732 if (priv->use_wpa) { 732 if (priv->use_wpa) {
733 int cipher_type, cipher_length; 733 int cipher_type, cipher_length;
734 if (is_bcast) { 734 if (is_bcast) {
735 cipher_type = priv->group_cipher_suite; 735 cipher_type = priv->group_cipher_suite;
736 if (cipher_type == CIPHER_SUITE_WEP_64 || 736 if (cipher_type == CIPHER_SUITE_WEP_64 ||
737 cipher_type == CIPHER_SUITE_WEP_128) 737 cipher_type == CIPHER_SUITE_WEP_128)
738 cipher_length = 8; 738 cipher_length = 8;
739 else if (cipher_type == CIPHER_SUITE_TKIP) 739 else if (cipher_type == CIPHER_SUITE_TKIP)
740 cipher_length = 12; 740 cipher_length = 12;
741 else if (priv->pairwise_cipher_suite == CIPHER_SUITE_WEP_64 || 741 else if (priv->pairwise_cipher_suite == CIPHER_SUITE_WEP_64 ||
742 priv->pairwise_cipher_suite == CIPHER_SUITE_WEP_128) { 742 priv->pairwise_cipher_suite == CIPHER_SUITE_WEP_128) {
743 cipher_type = priv->pairwise_cipher_suite; 743 cipher_type = priv->pairwise_cipher_suite;
744 cipher_length = 8; 744 cipher_length = 8;
745 } else { 745 } else {
746 cipher_type = CIPHER_SUITE_NONE; 746 cipher_type = CIPHER_SUITE_NONE;
747 cipher_length = 0; 747 cipher_length = 0;
748 } 748 }
749 } else { 749 } else {
750 cipher_type = priv->pairwise_cipher_suite; 750 cipher_type = priv->pairwise_cipher_suite;
751 if (cipher_type == CIPHER_SUITE_WEP_64 || 751 if (cipher_type == CIPHER_SUITE_WEP_64 ||
752 cipher_type == CIPHER_SUITE_WEP_128) 752 cipher_type == CIPHER_SUITE_WEP_128)
753 cipher_length = 8; 753 cipher_length = 8;
754 else if (cipher_type == CIPHER_SUITE_TKIP) 754 else if (cipher_type == CIPHER_SUITE_TKIP)
755 cipher_length = 12; 755 cipher_length = 12;
756 else if (priv->group_cipher_suite == CIPHER_SUITE_WEP_64 || 756 else if (priv->group_cipher_suite == CIPHER_SUITE_WEP_64 ||
757 priv->group_cipher_suite == CIPHER_SUITE_WEP_128) { 757 priv->group_cipher_suite == CIPHER_SUITE_WEP_128) {
758 cipher_type = priv->group_cipher_suite; 758 cipher_type = priv->group_cipher_suite;
759 cipher_length = 8; 759 cipher_length = 8;
760 } else { 760 } else {
761 cipher_type = CIPHER_SUITE_NONE; 761 cipher_type = CIPHER_SUITE_NONE;
762 cipher_length = 0; 762 cipher_length = 0;
763 } 763 }
764 } 764 }
765 765
766 atmel_wmem8(priv, atmel_tx(priv, TX_DESC_CIPHER_TYPE_OFFSET, priv->tx_desc_tail), 766 atmel_wmem8(priv, atmel_tx(priv, TX_DESC_CIPHER_TYPE_OFFSET, priv->tx_desc_tail),
767 cipher_type); 767 cipher_type);
768 atmel_wmem8(priv, atmel_tx(priv, TX_DESC_CIPHER_LENGTH_OFFSET, priv->tx_desc_tail), 768 atmel_wmem8(priv, atmel_tx(priv, TX_DESC_CIPHER_LENGTH_OFFSET, priv->tx_desc_tail),
769 cipher_length); 769 cipher_length);
770 } 770 }
771 atmel_wmem32(priv, atmel_tx(priv, TX_DESC_NEXT_OFFSET, priv->tx_desc_tail), 0x80000000L); 771 atmel_wmem32(priv, atmel_tx(priv, TX_DESC_NEXT_OFFSET, priv->tx_desc_tail), 0x80000000L);
772 atmel_wmem8(priv, atmel_tx(priv, TX_DESC_FLAGS_OFFSET, priv->tx_desc_tail), TX_FIRM_OWN); 772 atmel_wmem8(priv, atmel_tx(priv, TX_DESC_FLAGS_OFFSET, priv->tx_desc_tail), TX_FIRM_OWN);
773 if (priv->tx_desc_previous != priv->tx_desc_tail) 773 if (priv->tx_desc_previous != priv->tx_desc_tail)
774 atmel_wmem32(priv, atmel_tx(priv, TX_DESC_NEXT_OFFSET, priv->tx_desc_previous), 0); 774 atmel_wmem32(priv, atmel_tx(priv, TX_DESC_NEXT_OFFSET, priv->tx_desc_previous), 0);
775 priv->tx_desc_previous = priv->tx_desc_tail; 775 priv->tx_desc_previous = priv->tx_desc_tail;
776 if (priv->tx_desc_tail < (priv->host_info.tx_desc_count - 1)) 776 if (priv->tx_desc_tail < (priv->host_info.tx_desc_count - 1))
777 priv->tx_desc_tail++; 777 priv->tx_desc_tail++;
778 else 778 else
779 priv->tx_desc_tail = 0; 779 priv->tx_desc_tail = 0;
780 priv->tx_desc_free--; 780 priv->tx_desc_free--;
781 priv->tx_free_mem -= len; 781 priv->tx_free_mem -= len;
782 } 782 }
783 783
784 static netdev_tx_t start_tx(struct sk_buff *skb, struct net_device *dev) 784 static netdev_tx_t start_tx(struct sk_buff *skb, struct net_device *dev)
785 { 785 {
786 static const u8 SNAP_RFC1024[6] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 }; 786 static const u8 SNAP_RFC1024[6] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
787 struct atmel_private *priv = netdev_priv(dev); 787 struct atmel_private *priv = netdev_priv(dev);
788 struct ieee80211_hdr header; 788 struct ieee80211_hdr header;
789 unsigned long flags; 789 unsigned long flags;
790 u16 buff, frame_ctl, len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN; 790 u16 buff, frame_ctl, len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN;
791 791
792 if (priv->card && priv->present_callback && 792 if (priv->card && priv->present_callback &&
793 !(*priv->present_callback)(priv->card)) { 793 !(*priv->present_callback)(priv->card)) {
794 dev->stats.tx_errors++; 794 dev->stats.tx_errors++;
795 dev_kfree_skb(skb); 795 dev_kfree_skb(skb);
796 return NETDEV_TX_OK; 796 return NETDEV_TX_OK;
797 } 797 }
798 798
799 if (priv->station_state != STATION_STATE_READY) { 799 if (priv->station_state != STATION_STATE_READY) {
800 dev->stats.tx_errors++; 800 dev->stats.tx_errors++;
801 dev_kfree_skb(skb); 801 dev_kfree_skb(skb);
802 return NETDEV_TX_OK; 802 return NETDEV_TX_OK;
803 } 803 }
804 804
805 /* first ensure the timer func cannot run */ 805 /* first ensure the timer func cannot run */
806 spin_lock_bh(&priv->timerlock); 806 spin_lock_bh(&priv->timerlock);
807 /* then stop the hardware ISR */ 807 /* then stop the hardware ISR */
808 spin_lock_irqsave(&priv->irqlock, flags); 808 spin_lock_irqsave(&priv->irqlock, flags);
809 /* nb doing the above in the opposite order will deadlock */ 809 /* nb doing the above in the opposite order will deadlock */
810 810
811 /* The Wireless Header is 30 bytes. In the Ethernet packet we "cut" the 811 /* The Wireless Header is 30 bytes. In the Ethernet packet we "cut" the
812 12 first bytes (containing DA/SA) and put them in the appropriate 812 12 first bytes (containing DA/SA) and put them in the appropriate
813 fields of the Wireless Header. Thus the packet length is then the 813 fields of the Wireless Header. Thus the packet length is then the
814 initial + 18 (+30-12) */ 814 initial + 18 (+30-12) */
815 815
816 if (!(buff = find_tx_buff(priv, len + 18))) { 816 if (!(buff = find_tx_buff(priv, len + 18))) {
817 dev->stats.tx_dropped++; 817 dev->stats.tx_dropped++;
818 spin_unlock_irqrestore(&priv->irqlock, flags); 818 spin_unlock_irqrestore(&priv->irqlock, flags);
819 spin_unlock_bh(&priv->timerlock); 819 spin_unlock_bh(&priv->timerlock);
820 netif_stop_queue(dev); 820 netif_stop_queue(dev);
821 return NETDEV_TX_BUSY; 821 return NETDEV_TX_BUSY;
822 } 822 }
823 823
824 frame_ctl = IEEE80211_FTYPE_DATA; 824 frame_ctl = IEEE80211_FTYPE_DATA;
825 header.duration_id = 0; 825 header.duration_id = 0;
826 header.seq_ctrl = 0; 826 header.seq_ctrl = 0;
827 if (priv->wep_is_on) 827 if (priv->wep_is_on)
828 frame_ctl |= IEEE80211_FCTL_PROTECTED; 828 frame_ctl |= IEEE80211_FCTL_PROTECTED;
829 if (priv->operating_mode == IW_MODE_ADHOC) { 829 if (priv->operating_mode == IW_MODE_ADHOC) {
830 skb_copy_from_linear_data(skb, &header.addr1, 6); 830 skb_copy_from_linear_data(skb, &header.addr1, 6);
831 memcpy(&header.addr2, dev->dev_addr, 6); 831 memcpy(&header.addr2, dev->dev_addr, 6);
832 memcpy(&header.addr3, priv->BSSID, 6); 832 memcpy(&header.addr3, priv->BSSID, 6);
833 } else { 833 } else {
834 frame_ctl |= IEEE80211_FCTL_TODS; 834 frame_ctl |= IEEE80211_FCTL_TODS;
835 memcpy(&header.addr1, priv->CurrentBSSID, 6); 835 memcpy(&header.addr1, priv->CurrentBSSID, 6);
836 memcpy(&header.addr2, dev->dev_addr, 6); 836 memcpy(&header.addr2, dev->dev_addr, 6);
837 skb_copy_from_linear_data(skb, &header.addr3, 6); 837 skb_copy_from_linear_data(skb, &header.addr3, 6);
838 } 838 }
839 839
840 if (priv->use_wpa) 840 if (priv->use_wpa)
841 memcpy(&header.addr4, SNAP_RFC1024, 6); 841 memcpy(&header.addr4, SNAP_RFC1024, 6);
842 842
843 header.frame_control = cpu_to_le16(frame_ctl); 843 header.frame_control = cpu_to_le16(frame_ctl);
844 /* Copy the wireless header into the card */ 844 /* Copy the wireless header into the card */
845 atmel_copy_to_card(dev, buff, (unsigned char *)&header, DATA_FRAME_WS_HEADER_SIZE); 845 atmel_copy_to_card(dev, buff, (unsigned char *)&header, DATA_FRAME_WS_HEADER_SIZE);
846 /* Copy the packet sans its 802.3 header addresses which have been replaced */ 846 /* Copy the packet sans its 802.3 header addresses which have been replaced */
847 atmel_copy_to_card(dev, buff + DATA_FRAME_WS_HEADER_SIZE, skb->data + 12, len - 12); 847 atmel_copy_to_card(dev, buff + DATA_FRAME_WS_HEADER_SIZE, skb->data + 12, len - 12);
848 priv->tx_buff_tail += len - 12 + DATA_FRAME_WS_HEADER_SIZE; 848 priv->tx_buff_tail += len - 12 + DATA_FRAME_WS_HEADER_SIZE;
849 849
850 /* low bit of first byte of destination tells us if broadcast */ 850 /* low bit of first byte of destination tells us if broadcast */
851 tx_update_descriptor(priv, *(skb->data) & 0x01, len + 18, buff, TX_PACKET_TYPE_DATA); 851 tx_update_descriptor(priv, *(skb->data) & 0x01, len + 18, buff, TX_PACKET_TYPE_DATA);
852 dev->trans_start = jiffies; 852 dev->trans_start = jiffies;
853 dev->stats.tx_bytes += len; 853 dev->stats.tx_bytes += len;
854 854
855 spin_unlock_irqrestore(&priv->irqlock, flags); 855 spin_unlock_irqrestore(&priv->irqlock, flags);
856 spin_unlock_bh(&priv->timerlock); 856 spin_unlock_bh(&priv->timerlock);
857 dev_kfree_skb(skb); 857 dev_kfree_skb(skb);
858 858
859 return NETDEV_TX_OK; 859 return NETDEV_TX_OK;
860 } 860 }
861 861
862 static void atmel_transmit_management_frame(struct atmel_private *priv, 862 static void atmel_transmit_management_frame(struct atmel_private *priv,
863 struct ieee80211_hdr *header, 863 struct ieee80211_hdr *header,
864 u8 *body, int body_len) 864 u8 *body, int body_len)
865 { 865 {
866 u16 buff; 866 u16 buff;
867 int len = MGMT_FRAME_BODY_OFFSET + body_len; 867 int len = MGMT_FRAME_BODY_OFFSET + body_len;
868 868
869 if (!(buff = find_tx_buff(priv, len))) 869 if (!(buff = find_tx_buff(priv, len)))
870 return; 870 return;
871 871
872 atmel_copy_to_card(priv->dev, buff, (u8 *)header, MGMT_FRAME_BODY_OFFSET); 872 atmel_copy_to_card(priv->dev, buff, (u8 *)header, MGMT_FRAME_BODY_OFFSET);
873 atmel_copy_to_card(priv->dev, buff + MGMT_FRAME_BODY_OFFSET, body, body_len); 873 atmel_copy_to_card(priv->dev, buff + MGMT_FRAME_BODY_OFFSET, body, body_len);
874 priv->tx_buff_tail += len; 874 priv->tx_buff_tail += len;
875 tx_update_descriptor(priv, header->addr1[0] & 0x01, len, buff, TX_PACKET_TYPE_MGMT); 875 tx_update_descriptor(priv, header->addr1[0] & 0x01, len, buff, TX_PACKET_TYPE_MGMT);
876 } 876 }
877 877
878 static void fast_rx_path(struct atmel_private *priv, 878 static void fast_rx_path(struct atmel_private *priv,
879 struct ieee80211_hdr *header, 879 struct ieee80211_hdr *header,
880 u16 msdu_size, u16 rx_packet_loc, u32 crc) 880 u16 msdu_size, u16 rx_packet_loc, u32 crc)
881 { 881 {
882 /* fast path: unfragmented packet copy directly into skbuf */ 882 /* fast path: unfragmented packet copy directly into skbuf */
883 u8 mac4[6]; 883 u8 mac4[6];
884 struct sk_buff *skb; 884 struct sk_buff *skb;
885 unsigned char *skbp; 885 unsigned char *skbp;
886 886
887 /* get the final, mac 4 header field, this tells us encapsulation */ 887 /* get the final, mac 4 header field, this tells us encapsulation */
888 atmel_copy_to_host(priv->dev, mac4, rx_packet_loc + 24, 6); 888 atmel_copy_to_host(priv->dev, mac4, rx_packet_loc + 24, 6);
889 msdu_size -= 6; 889 msdu_size -= 6;
890 890
891 if (priv->do_rx_crc) { 891 if (priv->do_rx_crc) {
892 crc = crc32_le(crc, mac4, 6); 892 crc = crc32_le(crc, mac4, 6);
893 msdu_size -= 4; 893 msdu_size -= 4;
894 } 894 }
895 895
896 if (!(skb = dev_alloc_skb(msdu_size + 14))) { 896 if (!(skb = dev_alloc_skb(msdu_size + 14))) {
897 priv->dev->stats.rx_dropped++; 897 priv->dev->stats.rx_dropped++;
898 return; 898 return;
899 } 899 }
900 900
901 skb_reserve(skb, 2); 901 skb_reserve(skb, 2);
902 skbp = skb_put(skb, msdu_size + 12); 902 skbp = skb_put(skb, msdu_size + 12);
903 atmel_copy_to_host(priv->dev, skbp + 12, rx_packet_loc + 30, msdu_size); 903 atmel_copy_to_host(priv->dev, skbp + 12, rx_packet_loc + 30, msdu_size);
904 904
905 if (priv->do_rx_crc) { 905 if (priv->do_rx_crc) {
906 u32 netcrc; 906 u32 netcrc;
907 crc = crc32_le(crc, skbp + 12, msdu_size); 907 crc = crc32_le(crc, skbp + 12, msdu_size);
908 atmel_copy_to_host(priv->dev, (void *)&netcrc, rx_packet_loc + 30 + msdu_size, 4); 908 atmel_copy_to_host(priv->dev, (void *)&netcrc, rx_packet_loc + 30 + msdu_size, 4);
909 if ((crc ^ 0xffffffff) != netcrc) { 909 if ((crc ^ 0xffffffff) != netcrc) {
910 priv->dev->stats.rx_crc_errors++; 910 priv->dev->stats.rx_crc_errors++;
911 dev_kfree_skb(skb); 911 dev_kfree_skb(skb);
912 return; 912 return;
913 } 913 }
914 } 914 }
915 915
916 memcpy(skbp, header->addr1, 6); /* destination address */ 916 memcpy(skbp, header->addr1, 6); /* destination address */
917 if (le16_to_cpu(header->frame_control) & IEEE80211_FCTL_FROMDS) 917 if (le16_to_cpu(header->frame_control) & IEEE80211_FCTL_FROMDS)
918 memcpy(&skbp[6], header->addr3, 6); 918 memcpy(&skbp[6], header->addr3, 6);
919 else 919 else
920 memcpy(&skbp[6], header->addr2, 6); /* source address */ 920 memcpy(&skbp[6], header->addr2, 6); /* source address */
921 921
922 skb->protocol = eth_type_trans(skb, priv->dev); 922 skb->protocol = eth_type_trans(skb, priv->dev);
923 skb->ip_summed = CHECKSUM_NONE; 923 skb->ip_summed = CHECKSUM_NONE;
924 netif_rx(skb); 924 netif_rx(skb);
925 priv->dev->stats.rx_bytes += 12 + msdu_size; 925 priv->dev->stats.rx_bytes += 12 + msdu_size;
926 priv->dev->stats.rx_packets++; 926 priv->dev->stats.rx_packets++;
927 } 927 }
928 928
929 /* Test to see if the packet in card memory at packet_loc has a valid CRC 929 /* Test to see if the packet in card memory at packet_loc has a valid CRC
930 It doesn't matter that this is slow: it is only used to proble the first few 930 It doesn't matter that this is slow: it is only used to proble the first few
931 packets. */ 931 packets. */
932 static int probe_crc(struct atmel_private *priv, u16 packet_loc, u16 msdu_size) 932 static int probe_crc(struct atmel_private *priv, u16 packet_loc, u16 msdu_size)
933 { 933 {
934 int i = msdu_size - 4; 934 int i = msdu_size - 4;
935 u32 netcrc, crc = 0xffffffff; 935 u32 netcrc, crc = 0xffffffff;
936 936
937 if (msdu_size < 4) 937 if (msdu_size < 4)
938 return 0; 938 return 0;
939 939
940 atmel_copy_to_host(priv->dev, (void *)&netcrc, packet_loc + i, 4); 940 atmel_copy_to_host(priv->dev, (void *)&netcrc, packet_loc + i, 4);
941 941
942 atmel_writeAR(priv->dev, packet_loc); 942 atmel_writeAR(priv->dev, packet_loc);
943 while (i--) { 943 while (i--) {
944 u8 octet = atmel_read8(priv->dev, DR); 944 u8 octet = atmel_read8(priv->dev, DR);
945 crc = crc32_le(crc, &octet, 1); 945 crc = crc32_le(crc, &octet, 1);
946 } 946 }
947 947
948 return (crc ^ 0xffffffff) == netcrc; 948 return (crc ^ 0xffffffff) == netcrc;
949 } 949 }
950 950
951 static void frag_rx_path(struct atmel_private *priv, 951 static void frag_rx_path(struct atmel_private *priv,
952 struct ieee80211_hdr *header, 952 struct ieee80211_hdr *header,
953 u16 msdu_size, u16 rx_packet_loc, u32 crc, u16 seq_no, 953 u16 msdu_size, u16 rx_packet_loc, u32 crc, u16 seq_no,
954 u8 frag_no, int more_frags) 954 u8 frag_no, int more_frags)
955 { 955 {
956 u8 mac4[6]; 956 u8 mac4[6];
957 u8 source[6]; 957 u8 source[6];
958 struct sk_buff *skb; 958 struct sk_buff *skb;
959 959
960 if (le16_to_cpu(header->frame_control) & IEEE80211_FCTL_FROMDS) 960 if (le16_to_cpu(header->frame_control) & IEEE80211_FCTL_FROMDS)
961 memcpy(source, header->addr3, 6); 961 memcpy(source, header->addr3, 6);
962 else 962 else
963 memcpy(source, header->addr2, 6); 963 memcpy(source, header->addr2, 6);
964 964
965 rx_packet_loc += 24; /* skip header */ 965 rx_packet_loc += 24; /* skip header */
966 966
967 if (priv->do_rx_crc) 967 if (priv->do_rx_crc)
968 msdu_size -= 4; 968 msdu_size -= 4;
969 969
970 if (frag_no == 0) { /* first fragment */ 970 if (frag_no == 0) { /* first fragment */
971 atmel_copy_to_host(priv->dev, mac4, rx_packet_loc, 6); 971 atmel_copy_to_host(priv->dev, mac4, rx_packet_loc, 6);
972 msdu_size -= 6; 972 msdu_size -= 6;
973 rx_packet_loc += 6; 973 rx_packet_loc += 6;
974 974
975 if (priv->do_rx_crc) 975 if (priv->do_rx_crc)
976 crc = crc32_le(crc, mac4, 6); 976 crc = crc32_le(crc, mac4, 6);
977 977
978 priv->frag_seq = seq_no; 978 priv->frag_seq = seq_no;
979 priv->frag_no = 1; 979 priv->frag_no = 1;
980 priv->frag_len = msdu_size; 980 priv->frag_len = msdu_size;
981 memcpy(priv->frag_source, source, 6); 981 memcpy(priv->frag_source, source, 6);
982 memcpy(&priv->rx_buf[6], source, 6); 982 memcpy(&priv->rx_buf[6], source, 6);
983 memcpy(priv->rx_buf, header->addr1, 6); 983 memcpy(priv->rx_buf, header->addr1, 6);
984 984
985 atmel_copy_to_host(priv->dev, &priv->rx_buf[12], rx_packet_loc, msdu_size); 985 atmel_copy_to_host(priv->dev, &priv->rx_buf[12], rx_packet_loc, msdu_size);
986 986
987 if (priv->do_rx_crc) { 987 if (priv->do_rx_crc) {
988 u32 netcrc; 988 u32 netcrc;
989 crc = crc32_le(crc, &priv->rx_buf[12], msdu_size); 989 crc = crc32_le(crc, &priv->rx_buf[12], msdu_size);
990 atmel_copy_to_host(priv->dev, (void *)&netcrc, rx_packet_loc + msdu_size, 4); 990 atmel_copy_to_host(priv->dev, (void *)&netcrc, rx_packet_loc + msdu_size, 4);
991 if ((crc ^ 0xffffffff) != netcrc) { 991 if ((crc ^ 0xffffffff) != netcrc) {
992 priv->dev->stats.rx_crc_errors++; 992 priv->dev->stats.rx_crc_errors++;
993 memset(priv->frag_source, 0xff, 6); 993 memset(priv->frag_source, 0xff, 6);
994 } 994 }
995 } 995 }
996 996
997 } else if (priv->frag_no == frag_no && 997 } else if (priv->frag_no == frag_no &&
998 priv->frag_seq == seq_no && 998 priv->frag_seq == seq_no &&
999 memcmp(priv->frag_source, source, 6) == 0) { 999 memcmp(priv->frag_source, source, 6) == 0) {
1000 1000
1001 atmel_copy_to_host(priv->dev, &priv->rx_buf[12 + priv->frag_len], 1001 atmel_copy_to_host(priv->dev, &priv->rx_buf[12 + priv->frag_len],
1002 rx_packet_loc, msdu_size); 1002 rx_packet_loc, msdu_size);
1003 if (priv->do_rx_crc) { 1003 if (priv->do_rx_crc) {
1004 u32 netcrc; 1004 u32 netcrc;
1005 crc = crc32_le(crc, 1005 crc = crc32_le(crc,
1006 &priv->rx_buf[12 + priv->frag_len], 1006 &priv->rx_buf[12 + priv->frag_len],
1007 msdu_size); 1007 msdu_size);
1008 atmel_copy_to_host(priv->dev, (void *)&netcrc, rx_packet_loc + msdu_size, 4); 1008 atmel_copy_to_host(priv->dev, (void *)&netcrc, rx_packet_loc + msdu_size, 4);
1009 if ((crc ^ 0xffffffff) != netcrc) { 1009 if ((crc ^ 0xffffffff) != netcrc) {
1010 priv->dev->stats.rx_crc_errors++; 1010 priv->dev->stats.rx_crc_errors++;
1011 memset(priv->frag_source, 0xff, 6); 1011 memset(priv->frag_source, 0xff, 6);
1012 more_frags = 1; /* don't send broken assembly */ 1012 more_frags = 1; /* don't send broken assembly */
1013 } 1013 }
1014 } 1014 }
1015 1015
1016 priv->frag_len += msdu_size; 1016 priv->frag_len += msdu_size;
1017 priv->frag_no++; 1017 priv->frag_no++;
1018 1018
1019 if (!more_frags) { /* last one */ 1019 if (!more_frags) { /* last one */
1020 memset(priv->frag_source, 0xff, 6); 1020 memset(priv->frag_source, 0xff, 6);
1021 if (!(skb = dev_alloc_skb(priv->frag_len + 14))) { 1021 if (!(skb = dev_alloc_skb(priv->frag_len + 14))) {
1022 priv->dev->stats.rx_dropped++; 1022 priv->dev->stats.rx_dropped++;
1023 } else { 1023 } else {
1024 skb_reserve(skb, 2); 1024 skb_reserve(skb, 2);
1025 memcpy(skb_put(skb, priv->frag_len + 12), 1025 memcpy(skb_put(skb, priv->frag_len + 12),
1026 priv->rx_buf, 1026 priv->rx_buf,
1027 priv->frag_len + 12); 1027 priv->frag_len + 12);
1028 skb->protocol = eth_type_trans(skb, priv->dev); 1028 skb->protocol = eth_type_trans(skb, priv->dev);
1029 skb->ip_summed = CHECKSUM_NONE; 1029 skb->ip_summed = CHECKSUM_NONE;
1030 netif_rx(skb); 1030 netif_rx(skb);
1031 priv->dev->stats.rx_bytes += priv->frag_len + 12; 1031 priv->dev->stats.rx_bytes += priv->frag_len + 12;
1032 priv->dev->stats.rx_packets++; 1032 priv->dev->stats.rx_packets++;
1033 } 1033 }
1034 } 1034 }
1035 } else 1035 } else
1036 priv->wstats.discard.fragment++; 1036 priv->wstats.discard.fragment++;
1037 } 1037 }
1038 1038
1039 static void rx_done_irq(struct atmel_private *priv) 1039 static void rx_done_irq(struct atmel_private *priv)
1040 { 1040 {
1041 int i; 1041 int i;
1042 struct ieee80211_hdr header; 1042 struct ieee80211_hdr header;
1043 1043
1044 for (i = 0; 1044 for (i = 0;
1045 atmel_rmem8(priv, atmel_rx(priv, RX_DESC_FLAGS_OFFSET, priv->rx_desc_head)) == RX_DESC_FLAG_VALID && 1045 atmel_rmem8(priv, atmel_rx(priv, RX_DESC_FLAGS_OFFSET, priv->rx_desc_head)) == RX_DESC_FLAG_VALID &&
1046 i < priv->host_info.rx_desc_count; 1046 i < priv->host_info.rx_desc_count;
1047 i++) { 1047 i++) {
1048 1048
1049 u16 msdu_size, rx_packet_loc, frame_ctl, seq_control; 1049 u16 msdu_size, rx_packet_loc, frame_ctl, seq_control;
1050 u8 status = atmel_rmem8(priv, atmel_rx(priv, RX_DESC_STATUS_OFFSET, priv->rx_desc_head)); 1050 u8 status = atmel_rmem8(priv, atmel_rx(priv, RX_DESC_STATUS_OFFSET, priv->rx_desc_head));
1051 u32 crc = 0xffffffff; 1051 u32 crc = 0xffffffff;
1052 1052
1053 if (status != RX_STATUS_SUCCESS) { 1053 if (status != RX_STATUS_SUCCESS) {
1054 if (status == 0xc1) /* determined by experiment */ 1054 if (status == 0xc1) /* determined by experiment */
1055 priv->wstats.discard.nwid++; 1055 priv->wstats.discard.nwid++;
1056 else 1056 else
1057 priv->dev->stats.rx_errors++; 1057 priv->dev->stats.rx_errors++;
1058 goto next; 1058 goto next;
1059 } 1059 }
1060 1060
1061 msdu_size = atmel_rmem16(priv, atmel_rx(priv, RX_DESC_MSDU_SIZE_OFFSET, priv->rx_desc_head)); 1061 msdu_size = atmel_rmem16(priv, atmel_rx(priv, RX_DESC_MSDU_SIZE_OFFSET, priv->rx_desc_head));
1062 rx_packet_loc = atmel_rmem16(priv, atmel_rx(priv, RX_DESC_MSDU_POS_OFFSET, priv->rx_desc_head)); 1062 rx_packet_loc = atmel_rmem16(priv, atmel_rx(priv, RX_DESC_MSDU_POS_OFFSET, priv->rx_desc_head));
1063 1063
1064 if (msdu_size < 30) { 1064 if (msdu_size < 30) {
1065 priv->dev->stats.rx_errors++; 1065 priv->dev->stats.rx_errors++;
1066 goto next; 1066 goto next;
1067 } 1067 }
1068 1068
1069 /* Get header as far as end of seq_ctrl */ 1069 /* Get header as far as end of seq_ctrl */
1070 atmel_copy_to_host(priv->dev, (char *)&header, rx_packet_loc, 24); 1070 atmel_copy_to_host(priv->dev, (char *)&header, rx_packet_loc, 24);
1071 frame_ctl = le16_to_cpu(header.frame_control); 1071 frame_ctl = le16_to_cpu(header.frame_control);
1072 seq_control = le16_to_cpu(header.seq_ctrl); 1072 seq_control = le16_to_cpu(header.seq_ctrl);
1073 1073
1074 /* probe for CRC use here if needed once five packets have 1074 /* probe for CRC use here if needed once five packets have
1075 arrived with the same crc status, we assume we know what's 1075 arrived with the same crc status, we assume we know what's
1076 happening and stop probing */ 1076 happening and stop probing */
1077 if (priv->probe_crc) { 1077 if (priv->probe_crc) {
1078 if (!priv->wep_is_on || !(frame_ctl & IEEE80211_FCTL_PROTECTED)) { 1078 if (!priv->wep_is_on || !(frame_ctl & IEEE80211_FCTL_PROTECTED)) {
1079 priv->do_rx_crc = probe_crc(priv, rx_packet_loc, msdu_size); 1079 priv->do_rx_crc = probe_crc(priv, rx_packet_loc, msdu_size);
1080 } else { 1080 } else {
1081 priv->do_rx_crc = probe_crc(priv, rx_packet_loc + 24, msdu_size - 24); 1081 priv->do_rx_crc = probe_crc(priv, rx_packet_loc + 24, msdu_size - 24);
1082 } 1082 }
1083 if (priv->do_rx_crc) { 1083 if (priv->do_rx_crc) {
1084 if (priv->crc_ok_cnt++ > 5) 1084 if (priv->crc_ok_cnt++ > 5)
1085 priv->probe_crc = 0; 1085 priv->probe_crc = 0;
1086 } else { 1086 } else {
1087 if (priv->crc_ko_cnt++ > 5) 1087 if (priv->crc_ko_cnt++ > 5)
1088 priv->probe_crc = 0; 1088 priv->probe_crc = 0;
1089 } 1089 }
1090 } 1090 }
1091 1091
1092 /* don't CRC header when WEP in use */ 1092 /* don't CRC header when WEP in use */
1093 if (priv->do_rx_crc && (!priv->wep_is_on || !(frame_ctl & IEEE80211_FCTL_PROTECTED))) { 1093 if (priv->do_rx_crc && (!priv->wep_is_on || !(frame_ctl & IEEE80211_FCTL_PROTECTED))) {
1094 crc = crc32_le(0xffffffff, (unsigned char *)&header, 24); 1094 crc = crc32_le(0xffffffff, (unsigned char *)&header, 24);
1095 } 1095 }
1096 msdu_size -= 24; /* header */ 1096 msdu_size -= 24; /* header */
1097 1097
1098 if ((frame_ctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) { 1098 if ((frame_ctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) {
1099 int more_fragments = frame_ctl & IEEE80211_FCTL_MOREFRAGS; 1099 int more_fragments = frame_ctl & IEEE80211_FCTL_MOREFRAGS;
1100 u8 packet_fragment_no = seq_control & IEEE80211_SCTL_FRAG; 1100 u8 packet_fragment_no = seq_control & IEEE80211_SCTL_FRAG;
1101 u16 packet_sequence_no = (seq_control & IEEE80211_SCTL_SEQ) >> 4; 1101 u16 packet_sequence_no = (seq_control & IEEE80211_SCTL_SEQ) >> 4;
1102 1102
1103 if (!more_fragments && packet_fragment_no == 0) { 1103 if (!more_fragments && packet_fragment_no == 0) {
1104 fast_rx_path(priv, &header, msdu_size, rx_packet_loc, crc); 1104 fast_rx_path(priv, &header, msdu_size, rx_packet_loc, crc);
1105 } else { 1105 } else {
1106 frag_rx_path(priv, &header, msdu_size, rx_packet_loc, crc, 1106 frag_rx_path(priv, &header, msdu_size, rx_packet_loc, crc,
1107 packet_sequence_no, packet_fragment_no, more_fragments); 1107 packet_sequence_no, packet_fragment_no, more_fragments);
1108 } 1108 }
1109 } 1109 }
1110 1110
1111 if ((frame_ctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) { 1111 if ((frame_ctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) {
1112 /* copy rest of packet into buffer */ 1112 /* copy rest of packet into buffer */
1113 atmel_copy_to_host(priv->dev, (unsigned char *)&priv->rx_buf, rx_packet_loc + 24, msdu_size); 1113 atmel_copy_to_host(priv->dev, (unsigned char *)&priv->rx_buf, rx_packet_loc + 24, msdu_size);
1114 1114
1115 /* we use the same buffer for frag reassembly and control packets */ 1115 /* we use the same buffer for frag reassembly and control packets */
1116 memset(priv->frag_source, 0xff, 6); 1116 memset(priv->frag_source, 0xff, 6);
1117 1117
1118 if (priv->do_rx_crc) { 1118 if (priv->do_rx_crc) {
1119 /* last 4 octets is crc */ 1119 /* last 4 octets is crc */
1120 msdu_size -= 4; 1120 msdu_size -= 4;
1121 crc = crc32_le(crc, (unsigned char *)&priv->rx_buf, msdu_size); 1121 crc = crc32_le(crc, (unsigned char *)&priv->rx_buf, msdu_size);
1122 if ((crc ^ 0xffffffff) != (*((u32 *)&priv->rx_buf[msdu_size]))) { 1122 if ((crc ^ 0xffffffff) != (*((u32 *)&priv->rx_buf[msdu_size]))) {
1123 priv->dev->stats.rx_crc_errors++; 1123 priv->dev->stats.rx_crc_errors++;
1124 goto next; 1124 goto next;
1125 } 1125 }
1126 } 1126 }
1127 1127
1128 atmel_management_frame(priv, &header, msdu_size, 1128 atmel_management_frame(priv, &header, msdu_size,
1129 atmel_rmem8(priv, atmel_rx(priv, RX_DESC_RSSI_OFFSET, priv->rx_desc_head))); 1129 atmel_rmem8(priv, atmel_rx(priv, RX_DESC_RSSI_OFFSET, priv->rx_desc_head)));
1130 } 1130 }
1131 1131
1132 next: 1132 next:
1133 /* release descriptor */ 1133 /* release descriptor */
1134 atmel_wmem8(priv, atmel_rx(priv, RX_DESC_FLAGS_OFFSET, priv->rx_desc_head), RX_DESC_FLAG_CONSUMED); 1134 atmel_wmem8(priv, atmel_rx(priv, RX_DESC_FLAGS_OFFSET, priv->rx_desc_head), RX_DESC_FLAG_CONSUMED);
1135 1135
1136 if (priv->rx_desc_head < (priv->host_info.rx_desc_count - 1)) 1136 if (priv->rx_desc_head < (priv->host_info.rx_desc_count - 1))
1137 priv->rx_desc_head++; 1137 priv->rx_desc_head++;
1138 else 1138 else
1139 priv->rx_desc_head = 0; 1139 priv->rx_desc_head = 0;
1140 } 1140 }
1141 } 1141 }
1142 1142
1143 static irqreturn_t service_interrupt(int irq, void *dev_id) 1143 static irqreturn_t service_interrupt(int irq, void *dev_id)
1144 { 1144 {
1145 struct net_device *dev = (struct net_device *) dev_id; 1145 struct net_device *dev = (struct net_device *) dev_id;
1146 struct atmel_private *priv = netdev_priv(dev); 1146 struct atmel_private *priv = netdev_priv(dev);
1147 u8 isr; 1147 u8 isr;
1148 int i = -1; 1148 int i = -1;
1149 static u8 irq_order[] = { 1149 static u8 irq_order[] = {
1150 ISR_OUT_OF_RANGE, 1150 ISR_OUT_OF_RANGE,
1151 ISR_RxCOMPLETE, 1151 ISR_RxCOMPLETE,
1152 ISR_TxCOMPLETE, 1152 ISR_TxCOMPLETE,
1153 ISR_RxFRAMELOST, 1153 ISR_RxFRAMELOST,
1154 ISR_FATAL_ERROR, 1154 ISR_FATAL_ERROR,
1155 ISR_COMMAND_COMPLETE, 1155 ISR_COMMAND_COMPLETE,
1156 ISR_IBSS_MERGE, 1156 ISR_IBSS_MERGE,
1157 ISR_GENERIC_IRQ 1157 ISR_GENERIC_IRQ
1158 }; 1158 };
1159 1159
1160 if (priv->card && priv->present_callback && 1160 if (priv->card && priv->present_callback &&
1161 !(*priv->present_callback)(priv->card)) 1161 !(*priv->present_callback)(priv->card))
1162 return IRQ_HANDLED; 1162 return IRQ_HANDLED;
1163 1163
1164 /* In this state upper-level code assumes it can mess with 1164 /* In this state upper-level code assumes it can mess with
1165 the card unhampered by interrupts which may change register state. 1165 the card unhampered by interrupts which may change register state.
1166 Note that even though the card shouldn't generate interrupts 1166 Note that even though the card shouldn't generate interrupts
1167 the inturrupt line may be shared. This allows card setup 1167 the inturrupt line may be shared. This allows card setup
1168 to go on without disabling interrupts for a long time. */ 1168 to go on without disabling interrupts for a long time. */
1169 if (priv->station_state == STATION_STATE_DOWN) 1169 if (priv->station_state == STATION_STATE_DOWN)
1170 return IRQ_NONE; 1170 return IRQ_NONE;
1171 1171
1172 atmel_clear_gcr(dev, GCR_ENINT); /* disable interrupts */ 1172 atmel_clear_gcr(dev, GCR_ENINT); /* disable interrupts */
1173 1173
1174 while (1) { 1174 while (1) {
1175 if (!atmel_lock_mac(priv)) { 1175 if (!atmel_lock_mac(priv)) {
1176 /* failed to contact card */ 1176 /* failed to contact card */
1177 printk(KERN_ALERT "%s: failed to contact MAC.\n", dev->name); 1177 printk(KERN_ALERT "%s: failed to contact MAC.\n", dev->name);
1178 return IRQ_HANDLED; 1178 return IRQ_HANDLED;
1179 } 1179 }
1180 1180
1181 isr = atmel_rmem8(priv, atmel_hi(priv, IFACE_INT_STATUS_OFFSET)); 1181 isr = atmel_rmem8(priv, atmel_hi(priv, IFACE_INT_STATUS_OFFSET));
1182 atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 0); 1182 atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 0);
1183 1183
1184 if (!isr) { 1184 if (!isr) {
1185 atmel_set_gcr(dev, GCR_ENINT); /* enable interrupts */ 1185 atmel_set_gcr(dev, GCR_ENINT); /* enable interrupts */
1186 return i == -1 ? IRQ_NONE : IRQ_HANDLED; 1186 return i == -1 ? IRQ_NONE : IRQ_HANDLED;
1187 } 1187 }
1188 1188
1189 atmel_set_gcr(dev, GCR_ACKINT); /* acknowledge interrupt */ 1189 atmel_set_gcr(dev, GCR_ACKINT); /* acknowledge interrupt */
1190 1190
1191 for (i = 0; i < ARRAY_SIZE(irq_order); i++) 1191 for (i = 0; i < ARRAY_SIZE(irq_order); i++)
1192 if (isr & irq_order[i]) 1192 if (isr & irq_order[i])
1193 break; 1193 break;
1194 1194
1195 if (!atmel_lock_mac(priv)) { 1195 if (!atmel_lock_mac(priv)) {
1196 /* failed to contact card */ 1196 /* failed to contact card */
1197 printk(KERN_ALERT "%s: failed to contact MAC.\n", dev->name); 1197 printk(KERN_ALERT "%s: failed to contact MAC.\n", dev->name);
1198 return IRQ_HANDLED; 1198 return IRQ_HANDLED;
1199 } 1199 }
1200 1200
1201 isr = atmel_rmem8(priv, atmel_hi(priv, IFACE_INT_STATUS_OFFSET)); 1201 isr = atmel_rmem8(priv, atmel_hi(priv, IFACE_INT_STATUS_OFFSET));
1202 isr ^= irq_order[i]; 1202 isr ^= irq_order[i];
1203 atmel_wmem8(priv, atmel_hi(priv, IFACE_INT_STATUS_OFFSET), isr); 1203 atmel_wmem8(priv, atmel_hi(priv, IFACE_INT_STATUS_OFFSET), isr);
1204 atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 0); 1204 atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 0);
1205 1205
1206 switch (irq_order[i]) { 1206 switch (irq_order[i]) {
1207 1207
1208 case ISR_OUT_OF_RANGE: 1208 case ISR_OUT_OF_RANGE:
1209 if (priv->operating_mode == IW_MODE_INFRA && 1209 if (priv->operating_mode == IW_MODE_INFRA &&
1210 priv->station_state == STATION_STATE_READY) { 1210 priv->station_state == STATION_STATE_READY) {
1211 priv->station_is_associated = 0; 1211 priv->station_is_associated = 0;
1212 atmel_scan(priv, 1); 1212 atmel_scan(priv, 1);
1213 } 1213 }
1214 break; 1214 break;
1215 1215
1216 case ISR_RxFRAMELOST: 1216 case ISR_RxFRAMELOST:
1217 priv->wstats.discard.misc++; 1217 priv->wstats.discard.misc++;
1218 /* fall through */ 1218 /* fall through */
1219 case ISR_RxCOMPLETE: 1219 case ISR_RxCOMPLETE:
1220 rx_done_irq(priv); 1220 rx_done_irq(priv);
1221 break; 1221 break;
1222 1222
1223 case ISR_TxCOMPLETE: 1223 case ISR_TxCOMPLETE:
1224 tx_done_irq(priv); 1224 tx_done_irq(priv);
1225 break; 1225 break;
1226 1226
1227 case ISR_FATAL_ERROR: 1227 case ISR_FATAL_ERROR:
1228 printk(KERN_ALERT "%s: *** FATAL error interrupt ***\n", dev->name); 1228 printk(KERN_ALERT "%s: *** FATAL error interrupt ***\n", dev->name);
1229 atmel_enter_state(priv, STATION_STATE_MGMT_ERROR); 1229 atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
1230 break; 1230 break;
1231 1231
1232 case ISR_COMMAND_COMPLETE: 1232 case ISR_COMMAND_COMPLETE:
1233 atmel_command_irq(priv); 1233 atmel_command_irq(priv);
1234 break; 1234 break;
1235 1235
1236 case ISR_IBSS_MERGE: 1236 case ISR_IBSS_MERGE:
1237 atmel_get_mib(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_CUR_BSSID_POS, 1237 atmel_get_mib(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_CUR_BSSID_POS,
1238 priv->CurrentBSSID, 6); 1238 priv->CurrentBSSID, 6);
1239 /* The WPA stuff cares about the current AP address */ 1239 /* The WPA stuff cares about the current AP address */
1240 if (priv->use_wpa) 1240 if (priv->use_wpa)
1241 build_wpa_mib(priv); 1241 build_wpa_mib(priv);
1242 break; 1242 break;
1243 case ISR_GENERIC_IRQ: 1243 case ISR_GENERIC_IRQ:
1244 printk(KERN_INFO "%s: Generic_irq received.\n", dev->name); 1244 printk(KERN_INFO "%s: Generic_irq received.\n", dev->name);
1245 break; 1245 break;
1246 } 1246 }
1247 } 1247 }
1248 } 1248 }
1249 1249
1250 static struct iw_statistics *atmel_get_wireless_stats(struct net_device *dev) 1250 static struct iw_statistics *atmel_get_wireless_stats(struct net_device *dev)
1251 { 1251 {
1252 struct atmel_private *priv = netdev_priv(dev); 1252 struct atmel_private *priv = netdev_priv(dev);
1253 1253
1254 /* update the link quality here in case we are seeing no beacons 1254 /* update the link quality here in case we are seeing no beacons
1255 at all to drive the process */ 1255 at all to drive the process */
1256 atmel_smooth_qual(priv); 1256 atmel_smooth_qual(priv);
1257 1257
1258 priv->wstats.status = priv->station_state; 1258 priv->wstats.status = priv->station_state;
1259 1259
1260 if (priv->operating_mode == IW_MODE_INFRA) { 1260 if (priv->operating_mode == IW_MODE_INFRA) {
1261 if (priv->station_state != STATION_STATE_READY) { 1261 if (priv->station_state != STATION_STATE_READY) {
1262 priv->wstats.qual.qual = 0; 1262 priv->wstats.qual.qual = 0;
1263 priv->wstats.qual.level = 0; 1263 priv->wstats.qual.level = 0;
1264 priv->wstats.qual.updated = (IW_QUAL_QUAL_INVALID 1264 priv->wstats.qual.updated = (IW_QUAL_QUAL_INVALID
1265 | IW_QUAL_LEVEL_INVALID); 1265 | IW_QUAL_LEVEL_INVALID);
1266 } 1266 }
1267 priv->wstats.qual.noise = 0; 1267 priv->wstats.qual.noise = 0;
1268 priv->wstats.qual.updated |= IW_QUAL_NOISE_INVALID; 1268 priv->wstats.qual.updated |= IW_QUAL_NOISE_INVALID;
1269 } else { 1269 } else {
1270 /* Quality levels cannot be determined in ad-hoc mode, 1270 /* Quality levels cannot be determined in ad-hoc mode,
1271 because we can 'hear' more that one remote station. */ 1271 because we can 'hear' more that one remote station. */
1272 priv->wstats.qual.qual = 0; 1272 priv->wstats.qual.qual = 0;
1273 priv->wstats.qual.level = 0; 1273 priv->wstats.qual.level = 0;
1274 priv->wstats.qual.noise = 0; 1274 priv->wstats.qual.noise = 0;
1275 priv->wstats.qual.updated = IW_QUAL_QUAL_INVALID 1275 priv->wstats.qual.updated = IW_QUAL_QUAL_INVALID
1276 | IW_QUAL_LEVEL_INVALID 1276 | IW_QUAL_LEVEL_INVALID
1277 | IW_QUAL_NOISE_INVALID; 1277 | IW_QUAL_NOISE_INVALID;
1278 priv->wstats.miss.beacon = 0; 1278 priv->wstats.miss.beacon = 0;
1279 } 1279 }
1280 1280
1281 return &priv->wstats; 1281 return &priv->wstats;
1282 } 1282 }
1283 1283
1284 static int atmel_change_mtu(struct net_device *dev, int new_mtu) 1284 static int atmel_change_mtu(struct net_device *dev, int new_mtu)
1285 { 1285 {
1286 if ((new_mtu < 68) || (new_mtu > 2312)) 1286 if ((new_mtu < 68) || (new_mtu > 2312))
1287 return -EINVAL; 1287 return -EINVAL;
1288 dev->mtu = new_mtu; 1288 dev->mtu = new_mtu;
1289 return 0; 1289 return 0;
1290 } 1290 }
1291 1291
1292 static int atmel_set_mac_address(struct net_device *dev, void *p) 1292 static int atmel_set_mac_address(struct net_device *dev, void *p)
1293 { 1293 {
1294 struct sockaddr *addr = p; 1294 struct sockaddr *addr = p;
1295 1295
1296 memcpy (dev->dev_addr, addr->sa_data, dev->addr_len); 1296 memcpy (dev->dev_addr, addr->sa_data, dev->addr_len);
1297 return atmel_open(dev); 1297 return atmel_open(dev);
1298 } 1298 }
1299 1299
1300 EXPORT_SYMBOL(atmel_open); 1300 EXPORT_SYMBOL(atmel_open);
1301 1301
1302 int atmel_open(struct net_device *dev) 1302 int atmel_open(struct net_device *dev)
1303 { 1303 {
1304 struct atmel_private *priv = netdev_priv(dev); 1304 struct atmel_private *priv = netdev_priv(dev);
1305 int i, channel, err; 1305 int i, channel, err;
1306 1306
1307 /* any scheduled timer is no longer needed and might screw things up.. */ 1307 /* any scheduled timer is no longer needed and might screw things up.. */
1308 del_timer_sync(&priv->management_timer); 1308 del_timer_sync(&priv->management_timer);
1309 1309
1310 /* Interrupts will not touch the card once in this state... */ 1310 /* Interrupts will not touch the card once in this state... */
1311 priv->station_state = STATION_STATE_DOWN; 1311 priv->station_state = STATION_STATE_DOWN;
1312 1312
1313 if (priv->new_SSID_size) { 1313 if (priv->new_SSID_size) {
1314 memcpy(priv->SSID, priv->new_SSID, priv->new_SSID_size); 1314 memcpy(priv->SSID, priv->new_SSID, priv->new_SSID_size);
1315 priv->SSID_size = priv->new_SSID_size; 1315 priv->SSID_size = priv->new_SSID_size;
1316 priv->new_SSID_size = 0; 1316 priv->new_SSID_size = 0;
1317 } 1317 }
1318 priv->BSS_list_entries = 0; 1318 priv->BSS_list_entries = 0;
1319 1319
1320 priv->AuthenticationRequestRetryCnt = 0; 1320 priv->AuthenticationRequestRetryCnt = 0;
1321 priv->AssociationRequestRetryCnt = 0; 1321 priv->AssociationRequestRetryCnt = 0;
1322 priv->ReAssociationRequestRetryCnt = 0; 1322 priv->ReAssociationRequestRetryCnt = 0;
1323 priv->CurrentAuthentTransactionSeqNum = 0x0001; 1323 priv->CurrentAuthentTransactionSeqNum = 0x0001;
1324 priv->ExpectedAuthentTransactionSeqNum = 0x0002; 1324 priv->ExpectedAuthentTransactionSeqNum = 0x0002;
1325 1325
1326 priv->site_survey_state = SITE_SURVEY_IDLE; 1326 priv->site_survey_state = SITE_SURVEY_IDLE;
1327 priv->station_is_associated = 0; 1327 priv->station_is_associated = 0;
1328 1328
1329 err = reset_atmel_card(dev); 1329 err = reset_atmel_card(dev);
1330 if (err) 1330 if (err)
1331 return err; 1331 return err;
1332 1332
1333 if (priv->config_reg_domain) { 1333 if (priv->config_reg_domain) {
1334 priv->reg_domain = priv->config_reg_domain; 1334 priv->reg_domain = priv->config_reg_domain;
1335 atmel_set_mib8(priv, Phy_Mib_Type, PHY_MIB_REG_DOMAIN_POS, priv->reg_domain); 1335 atmel_set_mib8(priv, Phy_Mib_Type, PHY_MIB_REG_DOMAIN_POS, priv->reg_domain);
1336 } else { 1336 } else {
1337 priv->reg_domain = atmel_get_mib8(priv, Phy_Mib_Type, PHY_MIB_REG_DOMAIN_POS); 1337 priv->reg_domain = atmel_get_mib8(priv, Phy_Mib_Type, PHY_MIB_REG_DOMAIN_POS);
1338 for (i = 0; i < ARRAY_SIZE(channel_table); i++) 1338 for (i = 0; i < ARRAY_SIZE(channel_table); i++)
1339 if (priv->reg_domain == channel_table[i].reg_domain) 1339 if (priv->reg_domain == channel_table[i].reg_domain)
1340 break; 1340 break;
1341 if (i == ARRAY_SIZE(channel_table)) { 1341 if (i == ARRAY_SIZE(channel_table)) {
1342 priv->reg_domain = REG_DOMAIN_MKK1; 1342 priv->reg_domain = REG_DOMAIN_MKK1;
1343 printk(KERN_ALERT "%s: failed to get regulatory domain: assuming MKK1.\n", dev->name); 1343 printk(KERN_ALERT "%s: failed to get regulatory domain: assuming MKK1.\n", dev->name);
1344 } 1344 }
1345 } 1345 }
1346 1346
1347 if ((channel = atmel_validate_channel(priv, priv->channel))) 1347 if ((channel = atmel_validate_channel(priv, priv->channel)))
1348 priv->channel = channel; 1348 priv->channel = channel;
1349 1349
1350 /* this moves station_state on.... */ 1350 /* this moves station_state on.... */
1351 atmel_scan(priv, 1); 1351 atmel_scan(priv, 1);
1352 1352
1353 atmel_set_gcr(priv->dev, GCR_ENINT); /* enable interrupts */ 1353 atmel_set_gcr(priv->dev, GCR_ENINT); /* enable interrupts */
1354 return 0; 1354 return 0;
1355 } 1355 }
1356 1356
1357 static int atmel_close(struct net_device *dev) 1357 static int atmel_close(struct net_device *dev)
1358 { 1358 {
1359 struct atmel_private *priv = netdev_priv(dev); 1359 struct atmel_private *priv = netdev_priv(dev);
1360 1360
1361 /* Send event to userspace that we are disassociating */ 1361 /* Send event to userspace that we are disassociating */
1362 if (priv->station_state == STATION_STATE_READY) { 1362 if (priv->station_state == STATION_STATE_READY) {
1363 union iwreq_data wrqu; 1363 union iwreq_data wrqu;
1364 1364
1365 wrqu.data.length = 0; 1365 wrqu.data.length = 0;
1366 wrqu.data.flags = 0; 1366 wrqu.data.flags = 0;
1367 wrqu.ap_addr.sa_family = ARPHRD_ETHER; 1367 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
1368 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN); 1368 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
1369 wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL); 1369 wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
1370 } 1370 }
1371 1371
1372 atmel_enter_state(priv, STATION_STATE_DOWN); 1372 atmel_enter_state(priv, STATION_STATE_DOWN);
1373 1373
1374 if (priv->bus_type == BUS_TYPE_PCCARD) 1374 if (priv->bus_type == BUS_TYPE_PCCARD)
1375 atmel_write16(dev, GCR, 0x0060); 1375 atmel_write16(dev, GCR, 0x0060);
1376 atmel_write16(dev, GCR, 0x0040); 1376 atmel_write16(dev, GCR, 0x0040);
1377 return 0; 1377 return 0;
1378 } 1378 }
1379 1379
1380 static int atmel_validate_channel(struct atmel_private *priv, int channel) 1380 static int atmel_validate_channel(struct atmel_private *priv, int channel)
1381 { 1381 {
1382 /* check that channel is OK, if so return zero, 1382 /* check that channel is OK, if so return zero,
1383 else return suitable default channel */ 1383 else return suitable default channel */
1384 int i; 1384 int i;
1385 1385
1386 for (i = 0; i < ARRAY_SIZE(channel_table); i++) 1386 for (i = 0; i < ARRAY_SIZE(channel_table); i++)
1387 if (priv->reg_domain == channel_table[i].reg_domain) { 1387 if (priv->reg_domain == channel_table[i].reg_domain) {
1388 if (channel >= channel_table[i].min && 1388 if (channel >= channel_table[i].min &&
1389 channel <= channel_table[i].max) 1389 channel <= channel_table[i].max)
1390 return 0; 1390 return 0;
1391 else 1391 else
1392 return channel_table[i].min; 1392 return channel_table[i].min;
1393 } 1393 }
1394 return 0; 1394 return 0;
1395 } 1395 }
1396 1396
1397 static int atmel_proc_output (char *buf, struct atmel_private *priv) 1397 static int atmel_proc_output (char *buf, struct atmel_private *priv)
1398 { 1398 {
1399 int i; 1399 int i;
1400 char *p = buf; 1400 char *p = buf;
1401 char *s, *r, *c; 1401 char *s, *r, *c;
1402 1402
1403 p += sprintf(p, "Driver version:\t\t%d.%d\n", 1403 p += sprintf(p, "Driver version:\t\t%d.%d\n",
1404 DRIVER_MAJOR, DRIVER_MINOR); 1404 DRIVER_MAJOR, DRIVER_MINOR);
1405 1405
1406 if (priv->station_state != STATION_STATE_DOWN) { 1406 if (priv->station_state != STATION_STATE_DOWN) {
1407 p += sprintf(p, "Firmware version:\t%d.%d build %d\n" 1407 p += sprintf(p, "Firmware version:\t%d.%d build %d\n"
1408 "Firmware location:\t", 1408 "Firmware location:\t",
1409 priv->host_info.major_version, 1409 priv->host_info.major_version,
1410 priv->host_info.minor_version, 1410 priv->host_info.minor_version,
1411 priv->host_info.build_version); 1411 priv->host_info.build_version);
1412 1412
1413 if (priv->card_type != CARD_TYPE_EEPROM) 1413 if (priv->card_type != CARD_TYPE_EEPROM)
1414 p += sprintf(p, "on card\n"); 1414 p += sprintf(p, "on card\n");
1415 else if (priv->firmware) 1415 else if (priv->firmware)
1416 p += sprintf(p, "%s loaded by host\n", 1416 p += sprintf(p, "%s loaded by host\n",
1417 priv->firmware_id); 1417 priv->firmware_id);
1418 else 1418 else
1419 p += sprintf(p, "%s loaded by hotplug\n", 1419 p += sprintf(p, "%s loaded by hotplug\n",
1420 priv->firmware_id); 1420 priv->firmware_id);
1421 1421
1422 switch (priv->card_type) { 1422 switch (priv->card_type) {
1423 case CARD_TYPE_PARALLEL_FLASH: 1423 case CARD_TYPE_PARALLEL_FLASH:
1424 c = "Parallel flash"; 1424 c = "Parallel flash";
1425 break; 1425 break;
1426 case CARD_TYPE_SPI_FLASH: 1426 case CARD_TYPE_SPI_FLASH:
1427 c = "SPI flash\n"; 1427 c = "SPI flash\n";
1428 break; 1428 break;
1429 case CARD_TYPE_EEPROM: 1429 case CARD_TYPE_EEPROM:
1430 c = "EEPROM"; 1430 c = "EEPROM";
1431 break; 1431 break;
1432 default: 1432 default:
1433 c = "<unknown>"; 1433 c = "<unknown>";
1434 } 1434 }
1435 1435
1436 r = "<unknown>"; 1436 r = "<unknown>";
1437 for (i = 0; i < ARRAY_SIZE(channel_table); i++) 1437 for (i = 0; i < ARRAY_SIZE(channel_table); i++)
1438 if (priv->reg_domain == channel_table[i].reg_domain) 1438 if (priv->reg_domain == channel_table[i].reg_domain)
1439 r = channel_table[i].name; 1439 r = channel_table[i].name;
1440 1440
1441 p += sprintf(p, "MAC memory type:\t%s\n", c); 1441 p += sprintf(p, "MAC memory type:\t%s\n", c);
1442 p += sprintf(p, "Regulatory domain:\t%s\n", r); 1442 p += sprintf(p, "Regulatory domain:\t%s\n", r);
1443 p += sprintf(p, "Host CRC checking:\t%s\n", 1443 p += sprintf(p, "Host CRC checking:\t%s\n",
1444 priv->do_rx_crc ? "On" : "Off"); 1444 priv->do_rx_crc ? "On" : "Off");
1445 p += sprintf(p, "WPA-capable firmware:\t%s\n", 1445 p += sprintf(p, "WPA-capable firmware:\t%s\n",
1446 priv->use_wpa ? "Yes" : "No"); 1446 priv->use_wpa ? "Yes" : "No");
1447 } 1447 }
1448 1448
1449 switch (priv->station_state) { 1449 switch (priv->station_state) {
1450 case STATION_STATE_SCANNING: 1450 case STATION_STATE_SCANNING:
1451 s = "Scanning"; 1451 s = "Scanning";
1452 break; 1452 break;
1453 case STATION_STATE_JOINNING: 1453 case STATION_STATE_JOINNING:
1454 s = "Joining"; 1454 s = "Joining";
1455 break; 1455 break;
1456 case STATION_STATE_AUTHENTICATING: 1456 case STATION_STATE_AUTHENTICATING:
1457 s = "Authenticating"; 1457 s = "Authenticating";
1458 break; 1458 break;
1459 case STATION_STATE_ASSOCIATING: 1459 case STATION_STATE_ASSOCIATING:
1460 s = "Associating"; 1460 s = "Associating";
1461 break; 1461 break;
1462 case STATION_STATE_READY: 1462 case STATION_STATE_READY:
1463 s = "Ready"; 1463 s = "Ready";
1464 break; 1464 break;
1465 case STATION_STATE_REASSOCIATING: 1465 case STATION_STATE_REASSOCIATING:
1466 s = "Reassociating"; 1466 s = "Reassociating";
1467 break; 1467 break;
1468 case STATION_STATE_MGMT_ERROR: 1468 case STATION_STATE_MGMT_ERROR:
1469 s = "Management error"; 1469 s = "Management error";
1470 break; 1470 break;
1471 case STATION_STATE_DOWN: 1471 case STATION_STATE_DOWN:
1472 s = "Down"; 1472 s = "Down";
1473 break; 1473 break;
1474 default: 1474 default:
1475 s = "<unknown>"; 1475 s = "<unknown>";
1476 } 1476 }
1477 1477
1478 p += sprintf(p, "Current state:\t\t%s\n", s); 1478 p += sprintf(p, "Current state:\t\t%s\n", s);
1479 return p - buf; 1479 return p - buf;
1480 } 1480 }
1481 1481
1482 static int atmel_read_proc(char *page, char **start, off_t off, 1482 static int atmel_read_proc(char *page, char **start, off_t off,
1483 int count, int *eof, void *data) 1483 int count, int *eof, void *data)
1484 { 1484 {
1485 struct atmel_private *priv = data; 1485 struct atmel_private *priv = data;
1486 int len = atmel_proc_output (page, priv); 1486 int len = atmel_proc_output (page, priv);
1487 if (len <= off+count) 1487 if (len <= off+count)
1488 *eof = 1; 1488 *eof = 1;
1489 *start = page + off; 1489 *start = page + off;
1490 len -= off; 1490 len -= off;
1491 if (len > count) 1491 if (len > count)
1492 len = count; 1492 len = count;
1493 if (len < 0) 1493 if (len < 0)
1494 len = 0; 1494 len = 0;
1495 return len; 1495 return len;
1496 } 1496 }
1497 1497
1498 static const struct net_device_ops atmel_netdev_ops = { 1498 static const struct net_device_ops atmel_netdev_ops = {
1499 .ndo_open = atmel_open, 1499 .ndo_open = atmel_open,
1500 .ndo_stop = atmel_close, 1500 .ndo_stop = atmel_close,
1501 .ndo_change_mtu = atmel_change_mtu, 1501 .ndo_change_mtu = atmel_change_mtu,
1502 .ndo_set_mac_address = atmel_set_mac_address, 1502 .ndo_set_mac_address = atmel_set_mac_address,
1503 .ndo_start_xmit = start_tx, 1503 .ndo_start_xmit = start_tx,
1504 .ndo_do_ioctl = atmel_ioctl, 1504 .ndo_do_ioctl = atmel_ioctl,
1505 .ndo_validate_addr = eth_validate_addr, 1505 .ndo_validate_addr = eth_validate_addr,
1506 }; 1506 };
1507 1507
1508 struct net_device *init_atmel_card(unsigned short irq, unsigned long port, 1508 struct net_device *init_atmel_card(unsigned short irq, unsigned long port,
1509 const AtmelFWType fw_type, 1509 const AtmelFWType fw_type,
1510 struct device *sys_dev, 1510 struct device *sys_dev,
1511 int (*card_present)(void *), void *card) 1511 int (*card_present)(void *), void *card)
1512 { 1512 {
1513 struct proc_dir_entry *ent; 1513 struct proc_dir_entry *ent;
1514 struct net_device *dev; 1514 struct net_device *dev;
1515 struct atmel_private *priv; 1515 struct atmel_private *priv;
1516 int rc; 1516 int rc;
1517 1517
1518 /* Create the network device object. */ 1518 /* Create the network device object. */
1519 dev = alloc_etherdev(sizeof(*priv)); 1519 dev = alloc_etherdev(sizeof(*priv));
1520 if (!dev) { 1520 if (!dev) {
1521 printk(KERN_ERR "atmel: Couldn't alloc_etherdev\n"); 1521 printk(KERN_ERR "atmel: Couldn't alloc_etherdev\n");
1522 return NULL; 1522 return NULL;
1523 } 1523 }
1524 if (dev_alloc_name(dev, dev->name) < 0) { 1524 if (dev_alloc_name(dev, dev->name) < 0) {
1525 printk(KERN_ERR "atmel: Couldn't get name!\n"); 1525 printk(KERN_ERR "atmel: Couldn't get name!\n");
1526 goto err_out_free; 1526 goto err_out_free;
1527 } 1527 }
1528 1528
1529 priv = netdev_priv(dev); 1529 priv = netdev_priv(dev);
1530 priv->dev = dev; 1530 priv->dev = dev;
1531 priv->sys_dev = sys_dev; 1531 priv->sys_dev = sys_dev;
1532 priv->present_callback = card_present; 1532 priv->present_callback = card_present;
1533 priv->card = card; 1533 priv->card = card;
1534 priv->firmware = NULL; 1534 priv->firmware = NULL;
1535 priv->firmware_id[0] = '\0'; 1535 priv->firmware_id[0] = '\0';
1536 priv->firmware_type = fw_type; 1536 priv->firmware_type = fw_type;
1537 if (firmware) /* module parameter */ 1537 if (firmware) /* module parameter */
1538 strcpy(priv->firmware_id, firmware); 1538 strcpy(priv->firmware_id, firmware);
1539 priv->bus_type = card_present ? BUS_TYPE_PCCARD : BUS_TYPE_PCI; 1539 priv->bus_type = card_present ? BUS_TYPE_PCCARD : BUS_TYPE_PCI;
1540 priv->station_state = STATION_STATE_DOWN; 1540 priv->station_state = STATION_STATE_DOWN;
1541 priv->do_rx_crc = 0; 1541 priv->do_rx_crc = 0;
1542 /* For PCMCIA cards, some chips need CRC, some don't 1542 /* For PCMCIA cards, some chips need CRC, some don't
1543 so we have to probe. */ 1543 so we have to probe. */
1544 if (priv->bus_type == BUS_TYPE_PCCARD) { 1544 if (priv->bus_type == BUS_TYPE_PCCARD) {
1545 priv->probe_crc = 1; 1545 priv->probe_crc = 1;
1546 priv->crc_ok_cnt = priv->crc_ko_cnt = 0; 1546 priv->crc_ok_cnt = priv->crc_ko_cnt = 0;
1547 } else 1547 } else
1548 priv->probe_crc = 0; 1548 priv->probe_crc = 0;
1549 priv->last_qual = jiffies; 1549 priv->last_qual = jiffies;
1550 priv->last_beacon_timestamp = 0; 1550 priv->last_beacon_timestamp = 0;
1551 memset(priv->frag_source, 0xff, sizeof(priv->frag_source)); 1551 memset(priv->frag_source, 0xff, sizeof(priv->frag_source));
1552 memset(priv->BSSID, 0, 6); 1552 memset(priv->BSSID, 0, 6);
1553 priv->CurrentBSSID[0] = 0xFF; /* Initialize to something invalid.... */ 1553 priv->CurrentBSSID[0] = 0xFF; /* Initialize to something invalid.... */
1554 priv->station_was_associated = 0; 1554 priv->station_was_associated = 0;
1555 1555
1556 priv->last_survey = jiffies; 1556 priv->last_survey = jiffies;
1557 priv->preamble = LONG_PREAMBLE; 1557 priv->preamble = LONG_PREAMBLE;
1558 priv->operating_mode = IW_MODE_INFRA; 1558 priv->operating_mode = IW_MODE_INFRA;
1559 priv->connect_to_any_BSS = 0; 1559 priv->connect_to_any_BSS = 0;
1560 priv->config_reg_domain = 0; 1560 priv->config_reg_domain = 0;
1561 priv->reg_domain = 0; 1561 priv->reg_domain = 0;
1562 priv->tx_rate = 3; 1562 priv->tx_rate = 3;
1563 priv->auto_tx_rate = 1; 1563 priv->auto_tx_rate = 1;
1564 priv->channel = 4; 1564 priv->channel = 4;
1565 priv->power_mode = 0; 1565 priv->power_mode = 0;
1566 priv->SSID[0] = '\0'; 1566 priv->SSID[0] = '\0';
1567 priv->SSID_size = 0; 1567 priv->SSID_size = 0;
1568 priv->new_SSID_size = 0; 1568 priv->new_SSID_size = 0;
1569 priv->frag_threshold = 2346; 1569 priv->frag_threshold = 2346;
1570 priv->rts_threshold = 2347; 1570 priv->rts_threshold = 2347;
1571 priv->short_retry = 7; 1571 priv->short_retry = 7;
1572 priv->long_retry = 4; 1572 priv->long_retry = 4;
1573 1573
1574 priv->wep_is_on = 0; 1574 priv->wep_is_on = 0;
1575 priv->default_key = 0; 1575 priv->default_key = 0;
1576 priv->encryption_level = 0; 1576 priv->encryption_level = 0;
1577 priv->exclude_unencrypted = 0; 1577 priv->exclude_unencrypted = 0;
1578 priv->group_cipher_suite = priv->pairwise_cipher_suite = CIPHER_SUITE_NONE; 1578 priv->group_cipher_suite = priv->pairwise_cipher_suite = CIPHER_SUITE_NONE;
1579 priv->use_wpa = 0; 1579 priv->use_wpa = 0;
1580 memset(priv->wep_keys, 0, sizeof(priv->wep_keys)); 1580 memset(priv->wep_keys, 0, sizeof(priv->wep_keys));
1581 memset(priv->wep_key_len, 0, sizeof(priv->wep_key_len)); 1581 memset(priv->wep_key_len, 0, sizeof(priv->wep_key_len));
1582 1582
1583 priv->default_beacon_period = priv->beacon_period = 100; 1583 priv->default_beacon_period = priv->beacon_period = 100;
1584 priv->listen_interval = 1; 1584 priv->listen_interval = 1;
1585 1585
1586 init_timer(&priv->management_timer); 1586 init_timer(&priv->management_timer);
1587 spin_lock_init(&priv->irqlock); 1587 spin_lock_init(&priv->irqlock);
1588 spin_lock_init(&priv->timerlock); 1588 spin_lock_init(&priv->timerlock);
1589 priv->management_timer.function = atmel_management_timer; 1589 priv->management_timer.function = atmel_management_timer;
1590 priv->management_timer.data = (unsigned long) dev; 1590 priv->management_timer.data = (unsigned long) dev;
1591 1591
1592 dev->netdev_ops = &atmel_netdev_ops; 1592 dev->netdev_ops = &atmel_netdev_ops;
1593 dev->wireless_handlers = &atmel_handler_def; 1593 dev->wireless_handlers = &atmel_handler_def;
1594 dev->irq = irq; 1594 dev->irq = irq;
1595 dev->base_addr = port; 1595 dev->base_addr = port;
1596 1596
1597 SET_NETDEV_DEV(dev, sys_dev); 1597 SET_NETDEV_DEV(dev, sys_dev);
1598 1598
1599 if ((rc = request_irq(dev->irq, service_interrupt, IRQF_SHARED, dev->name, dev))) { 1599 if ((rc = request_irq(dev->irq, service_interrupt, IRQF_SHARED, dev->name, dev))) {
1600 printk(KERN_ERR "%s: register interrupt %d failed, rc %d\n", dev->name, irq, rc); 1600 printk(KERN_ERR "%s: register interrupt %d failed, rc %d\n", dev->name, irq, rc);
1601 goto err_out_free; 1601 goto err_out_free;
1602 } 1602 }
1603 1603
1604 if (!request_region(dev->base_addr, 32, 1604 if (!request_region(dev->base_addr, 32,
1605 priv->bus_type == BUS_TYPE_PCCARD ? "atmel_cs" : "atmel_pci")) { 1605 priv->bus_type == BUS_TYPE_PCCARD ? "atmel_cs" : "atmel_pci")) {
1606 goto err_out_irq; 1606 goto err_out_irq;
1607 } 1607 }
1608 1608
1609 if (register_netdev(dev)) 1609 if (register_netdev(dev))
1610 goto err_out_res; 1610 goto err_out_res;
1611 1611
1612 if (!probe_atmel_card(dev)) { 1612 if (!probe_atmel_card(dev)) {
1613 unregister_netdev(dev); 1613 unregister_netdev(dev);
1614 goto err_out_res; 1614 goto err_out_res;
1615 } 1615 }
1616 1616
1617 netif_carrier_off(dev); 1617 netif_carrier_off(dev);
1618 1618
1619 ent = create_proc_read_entry ("driver/atmel", 0, NULL, atmel_read_proc, priv); 1619 ent = create_proc_read_entry ("driver/atmel", 0, NULL, atmel_read_proc, priv);
1620 if (!ent) 1620 if (!ent)
1621 printk(KERN_WARNING "atmel: unable to create /proc entry.\n"); 1621 printk(KERN_WARNING "atmel: unable to create /proc entry.\n");
1622 1622
1623 printk(KERN_INFO "%s: Atmel at76c50x. Version %d.%d. MAC %pM\n", 1623 printk(KERN_INFO "%s: Atmel at76c50x. Version %d.%d. MAC %pM\n",
1624 dev->name, DRIVER_MAJOR, DRIVER_MINOR, dev->dev_addr); 1624 dev->name, DRIVER_MAJOR, DRIVER_MINOR, dev->dev_addr);
1625 1625
1626 return dev; 1626 return dev;
1627 1627
1628 err_out_res: 1628 err_out_res:
1629 release_region(dev->base_addr, 32); 1629 release_region(dev->base_addr, 32);
1630 err_out_irq: 1630 err_out_irq:
1631 free_irq(dev->irq, dev); 1631 free_irq(dev->irq, dev);
1632 err_out_free: 1632 err_out_free:
1633 free_netdev(dev); 1633 free_netdev(dev);
1634 return NULL; 1634 return NULL;
1635 } 1635 }
1636 1636
1637 EXPORT_SYMBOL(init_atmel_card); 1637 EXPORT_SYMBOL(init_atmel_card);
1638 1638
1639 void stop_atmel_card(struct net_device *dev) 1639 void stop_atmel_card(struct net_device *dev)
1640 { 1640 {
1641 struct atmel_private *priv = netdev_priv(dev); 1641 struct atmel_private *priv = netdev_priv(dev);
1642 1642
1643 /* put a brick on it... */ 1643 /* put a brick on it... */
1644 if (priv->bus_type == BUS_TYPE_PCCARD) 1644 if (priv->bus_type == BUS_TYPE_PCCARD)
1645 atmel_write16(dev, GCR, 0x0060); 1645 atmel_write16(dev, GCR, 0x0060);
1646 atmel_write16(dev, GCR, 0x0040); 1646 atmel_write16(dev, GCR, 0x0040);
1647 1647
1648 del_timer_sync(&priv->management_timer); 1648 del_timer_sync(&priv->management_timer);
1649 unregister_netdev(dev); 1649 unregister_netdev(dev);
1650 remove_proc_entry("driver/atmel", NULL); 1650 remove_proc_entry("driver/atmel", NULL);
1651 free_irq(dev->irq, dev); 1651 free_irq(dev->irq, dev);
1652 kfree(priv->firmware); 1652 kfree(priv->firmware);
1653 release_region(dev->base_addr, 32); 1653 release_region(dev->base_addr, 32);
1654 free_netdev(dev); 1654 free_netdev(dev);
1655 } 1655 }
1656 1656
1657 EXPORT_SYMBOL(stop_atmel_card); 1657 EXPORT_SYMBOL(stop_atmel_card);
1658 1658
1659 static int atmel_set_essid(struct net_device *dev, 1659 static int atmel_set_essid(struct net_device *dev,
1660 struct iw_request_info *info, 1660 struct iw_request_info *info,
1661 struct iw_point *dwrq, 1661 struct iw_point *dwrq,
1662 char *extra) 1662 char *extra)
1663 { 1663 {
1664 struct atmel_private *priv = netdev_priv(dev); 1664 struct atmel_private *priv = netdev_priv(dev);
1665 1665
1666 /* Check if we asked for `any' */ 1666 /* Check if we asked for `any' */
1667 if (dwrq->flags == 0) { 1667 if (dwrq->flags == 0) {
1668 priv->connect_to_any_BSS = 1; 1668 priv->connect_to_any_BSS = 1;
1669 } else { 1669 } else {
1670 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1; 1670 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
1671 1671
1672 priv->connect_to_any_BSS = 0; 1672 priv->connect_to_any_BSS = 0;
1673 1673
1674 /* Check the size of the string */ 1674 /* Check the size of the string */
1675 if (dwrq->length > MAX_SSID_LENGTH) 1675 if (dwrq->length > MAX_SSID_LENGTH)
1676 return -E2BIG; 1676 return -E2BIG;
1677 if (index != 0) 1677 if (index != 0)
1678 return -EINVAL; 1678 return -EINVAL;
1679 1679
1680 memcpy(priv->new_SSID, extra, dwrq->length); 1680 memcpy(priv->new_SSID, extra, dwrq->length);
1681 priv->new_SSID_size = dwrq->length; 1681 priv->new_SSID_size = dwrq->length;
1682 } 1682 }
1683 1683
1684 return -EINPROGRESS; 1684 return -EINPROGRESS;
1685 } 1685 }
1686 1686
1687 static int atmel_get_essid(struct net_device *dev, 1687 static int atmel_get_essid(struct net_device *dev,
1688 struct iw_request_info *info, 1688 struct iw_request_info *info,
1689 struct iw_point *dwrq, 1689 struct iw_point *dwrq,
1690 char *extra) 1690 char *extra)
1691 { 1691 {
1692 struct atmel_private *priv = netdev_priv(dev); 1692 struct atmel_private *priv = netdev_priv(dev);
1693 1693
1694 /* Get the current SSID */ 1694 /* Get the current SSID */
1695 if (priv->new_SSID_size != 0) { 1695 if (priv->new_SSID_size != 0) {
1696 memcpy(extra, priv->new_SSID, priv->new_SSID_size); 1696 memcpy(extra, priv->new_SSID, priv->new_SSID_size);
1697 dwrq->length = priv->new_SSID_size; 1697 dwrq->length = priv->new_SSID_size;
1698 } else { 1698 } else {
1699 memcpy(extra, priv->SSID, priv->SSID_size); 1699 memcpy(extra, priv->SSID, priv->SSID_size);
1700 dwrq->length = priv->SSID_size; 1700 dwrq->length = priv->SSID_size;
1701 } 1701 }
1702 1702
1703 dwrq->flags = !priv->connect_to_any_BSS; /* active */ 1703 dwrq->flags = !priv->connect_to_any_BSS; /* active */
1704 1704
1705 return 0; 1705 return 0;
1706 } 1706 }
1707 1707
1708 static int atmel_get_wap(struct net_device *dev, 1708 static int atmel_get_wap(struct net_device *dev,
1709 struct iw_request_info *info, 1709 struct iw_request_info *info,
1710 struct sockaddr *awrq, 1710 struct sockaddr *awrq,
1711 char *extra) 1711 char *extra)
1712 { 1712 {
1713 struct atmel_private *priv = netdev_priv(dev); 1713 struct atmel_private *priv = netdev_priv(dev);
1714 memcpy(awrq->sa_data, priv->CurrentBSSID, 6); 1714 memcpy(awrq->sa_data, priv->CurrentBSSID, 6);
1715 awrq->sa_family = ARPHRD_ETHER; 1715 awrq->sa_family = ARPHRD_ETHER;
1716 1716
1717 return 0; 1717 return 0;
1718 } 1718 }
1719 1719
1720 static int atmel_set_encode(struct net_device *dev, 1720 static int atmel_set_encode(struct net_device *dev,
1721 struct iw_request_info *info, 1721 struct iw_request_info *info,
1722 struct iw_point *dwrq, 1722 struct iw_point *dwrq,
1723 char *extra) 1723 char *extra)
1724 { 1724 {
1725 struct atmel_private *priv = netdev_priv(dev); 1725 struct atmel_private *priv = netdev_priv(dev);
1726 1726
1727 /* Basic checking: do we have a key to set ? 1727 /* Basic checking: do we have a key to set ?
1728 * Note : with the new API, it's impossible to get a NULL pointer. 1728 * Note : with the new API, it's impossible to get a NULL pointer.
1729 * Therefore, we need to check a key size == 0 instead. 1729 * Therefore, we need to check a key size == 0 instead.
1730 * New version of iwconfig properly set the IW_ENCODE_NOKEY flag 1730 * New version of iwconfig properly set the IW_ENCODE_NOKEY flag
1731 * when no key is present (only change flags), but older versions 1731 * when no key is present (only change flags), but older versions
1732 * don't do it. - Jean II */ 1732 * don't do it. - Jean II */
1733 if (dwrq->length > 0) { 1733 if (dwrq->length > 0) {
1734 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1; 1734 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
1735 int current_index = priv->default_key; 1735 int current_index = priv->default_key;
1736 /* Check the size of the key */ 1736 /* Check the size of the key */
1737 if (dwrq->length > 13) { 1737 if (dwrq->length > 13) {
1738 return -EINVAL; 1738 return -EINVAL;
1739 } 1739 }
1740 /* Check the index (none -> use current) */ 1740 /* Check the index (none -> use current) */
1741 if (index < 0 || index >= 4) 1741 if (index < 0 || index >= 4)
1742 index = current_index; 1742 index = current_index;
1743 else 1743 else
1744 priv->default_key = index; 1744 priv->default_key = index;
1745 /* Set the length */ 1745 /* Set the length */
1746 if (dwrq->length > 5) 1746 if (dwrq->length > 5)
1747 priv->wep_key_len[index] = 13; 1747 priv->wep_key_len[index] = 13;
1748 else 1748 else
1749 if (dwrq->length > 0) 1749 if (dwrq->length > 0)
1750 priv->wep_key_len[index] = 5; 1750 priv->wep_key_len[index] = 5;
1751 else 1751 else
1752 /* Disable the key */ 1752 /* Disable the key */
1753 priv->wep_key_len[index] = 0; 1753 priv->wep_key_len[index] = 0;
1754 /* Check if the key is not marked as invalid */ 1754 /* Check if the key is not marked as invalid */
1755 if (!(dwrq->flags & IW_ENCODE_NOKEY)) { 1755 if (!(dwrq->flags & IW_ENCODE_NOKEY)) {
1756 /* Cleanup */ 1756 /* Cleanup */
1757 memset(priv->wep_keys[index], 0, 13); 1757 memset(priv->wep_keys[index], 0, 13);
1758 /* Copy the key in the driver */ 1758 /* Copy the key in the driver */
1759 memcpy(priv->wep_keys[index], extra, dwrq->length); 1759 memcpy(priv->wep_keys[index], extra, dwrq->length);
1760 } 1760 }
1761 /* WE specify that if a valid key is set, encryption 1761 /* WE specify that if a valid key is set, encryption
1762 * should be enabled (user may turn it off later) 1762 * should be enabled (user may turn it off later)
1763 * This is also how "iwconfig ethX key on" works */ 1763 * This is also how "iwconfig ethX key on" works */
1764 if (index == current_index && 1764 if (index == current_index &&
1765 priv->wep_key_len[index] > 0) { 1765 priv->wep_key_len[index] > 0) {
1766 priv->wep_is_on = 1; 1766 priv->wep_is_on = 1;
1767 priv->exclude_unencrypted = 1; 1767 priv->exclude_unencrypted = 1;
1768 if (priv->wep_key_len[index] > 5) { 1768 if (priv->wep_key_len[index] > 5) {
1769 priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_128; 1769 priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_128;
1770 priv->encryption_level = 2; 1770 priv->encryption_level = 2;
1771 } else { 1771 } else {
1772 priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_64; 1772 priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_64;
1773 priv->encryption_level = 1; 1773 priv->encryption_level = 1;
1774 } 1774 }
1775 } 1775 }
1776 } else { 1776 } else {
1777 /* Do we want to just set the transmit key index ? */ 1777 /* Do we want to just set the transmit key index ? */
1778 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1; 1778 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
1779 if (index >= 0 && index < 4) { 1779 if (index >= 0 && index < 4) {
1780 priv->default_key = index; 1780 priv->default_key = index;
1781 } else 1781 } else
1782 /* Don't complain if only change the mode */ 1782 /* Don't complain if only change the mode */
1783 if (!(dwrq->flags & IW_ENCODE_MODE)) 1783 if (!(dwrq->flags & IW_ENCODE_MODE))
1784 return -EINVAL; 1784 return -EINVAL;
1785 } 1785 }
1786 /* Read the flags */ 1786 /* Read the flags */
1787 if (dwrq->flags & IW_ENCODE_DISABLED) { 1787 if (dwrq->flags & IW_ENCODE_DISABLED) {
1788 priv->wep_is_on = 0; 1788 priv->wep_is_on = 0;
1789 priv->encryption_level = 0; 1789 priv->encryption_level = 0;
1790 priv->pairwise_cipher_suite = CIPHER_SUITE_NONE; 1790 priv->pairwise_cipher_suite = CIPHER_SUITE_NONE;
1791 } else { 1791 } else {
1792 priv->wep_is_on = 1; 1792 priv->wep_is_on = 1;
1793 if (priv->wep_key_len[priv->default_key] > 5) { 1793 if (priv->wep_key_len[priv->default_key] > 5) {
1794 priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_128; 1794 priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_128;
1795 priv->encryption_level = 2; 1795 priv->encryption_level = 2;
1796 } else { 1796 } else {
1797 priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_64; 1797 priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_64;
1798 priv->encryption_level = 1; 1798 priv->encryption_level = 1;
1799 } 1799 }
1800 } 1800 }
1801 if (dwrq->flags & IW_ENCODE_RESTRICTED) 1801 if (dwrq->flags & IW_ENCODE_RESTRICTED)
1802 priv->exclude_unencrypted = 1; 1802 priv->exclude_unencrypted = 1;
1803 if (dwrq->flags & IW_ENCODE_OPEN) 1803 if (dwrq->flags & IW_ENCODE_OPEN)
1804 priv->exclude_unencrypted = 0; 1804 priv->exclude_unencrypted = 0;
1805 1805
1806 return -EINPROGRESS; /* Call commit handler */ 1806 return -EINPROGRESS; /* Call commit handler */
1807 } 1807 }
1808 1808
1809 static int atmel_get_encode(struct net_device *dev, 1809 static int atmel_get_encode(struct net_device *dev,
1810 struct iw_request_info *info, 1810 struct iw_request_info *info,
1811 struct iw_point *dwrq, 1811 struct iw_point *dwrq,
1812 char *extra) 1812 char *extra)
1813 { 1813 {
1814 struct atmel_private *priv = netdev_priv(dev); 1814 struct atmel_private *priv = netdev_priv(dev);
1815 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1; 1815 int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
1816 1816
1817 if (!priv->wep_is_on) 1817 if (!priv->wep_is_on)
1818 dwrq->flags = IW_ENCODE_DISABLED; 1818 dwrq->flags = IW_ENCODE_DISABLED;
1819 else { 1819 else {
1820 if (priv->exclude_unencrypted) 1820 if (priv->exclude_unencrypted)
1821 dwrq->flags = IW_ENCODE_RESTRICTED; 1821 dwrq->flags = IW_ENCODE_RESTRICTED;
1822 else 1822 else
1823 dwrq->flags = IW_ENCODE_OPEN; 1823 dwrq->flags = IW_ENCODE_OPEN;
1824 } 1824 }
1825 /* Which key do we want ? -1 -> tx index */ 1825 /* Which key do we want ? -1 -> tx index */
1826 if (index < 0 || index >= 4) 1826 if (index < 0 || index >= 4)
1827 index = priv->default_key; 1827 index = priv->default_key;
1828 dwrq->flags |= index + 1; 1828 dwrq->flags |= index + 1;
1829 /* Copy the key to the user buffer */ 1829 /* Copy the key to the user buffer */
1830 dwrq->length = priv->wep_key_len[index]; 1830 dwrq->length = priv->wep_key_len[index];
1831 if (dwrq->length > 16) { 1831 if (dwrq->length > 16) {
1832 dwrq->length = 0; 1832 dwrq->length = 0;
1833 } else { 1833 } else {
1834 memset(extra, 0, 16); 1834 memset(extra, 0, 16);
1835 memcpy(extra, priv->wep_keys[index], dwrq->length); 1835 memcpy(extra, priv->wep_keys[index], dwrq->length);
1836 } 1836 }
1837 1837
1838 return 0; 1838 return 0;
1839 } 1839 }
1840 1840
1841 static int atmel_set_encodeext(struct net_device *dev, 1841 static int atmel_set_encodeext(struct net_device *dev,
1842 struct iw_request_info *info, 1842 struct iw_request_info *info,
1843 union iwreq_data *wrqu, 1843 union iwreq_data *wrqu,
1844 char *extra) 1844 char *extra)
1845 { 1845 {
1846 struct atmel_private *priv = netdev_priv(dev); 1846 struct atmel_private *priv = netdev_priv(dev);
1847 struct iw_point *encoding = &wrqu->encoding; 1847 struct iw_point *encoding = &wrqu->encoding;
1848 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; 1848 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
1849 int idx, key_len, alg = ext->alg, set_key = 1; 1849 int idx, key_len, alg = ext->alg, set_key = 1;
1850 1850
1851 /* Determine and validate the key index */ 1851 /* Determine and validate the key index */
1852 idx = encoding->flags & IW_ENCODE_INDEX; 1852 idx = encoding->flags & IW_ENCODE_INDEX;
1853 if (idx) { 1853 if (idx) {
1854 if (idx < 1 || idx > 4) 1854 if (idx < 1 || idx > 4)
1855 return -EINVAL; 1855 return -EINVAL;
1856 idx--; 1856 idx--;
1857 } else 1857 } else
1858 idx = priv->default_key; 1858 idx = priv->default_key;
1859 1859
1860 if (encoding->flags & IW_ENCODE_DISABLED) 1860 if (encoding->flags & IW_ENCODE_DISABLED)
1861 alg = IW_ENCODE_ALG_NONE; 1861 alg = IW_ENCODE_ALG_NONE;
1862 1862
1863 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { 1863 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
1864 priv->default_key = idx; 1864 priv->default_key = idx;
1865 set_key = ext->key_len > 0 ? 1 : 0; 1865 set_key = ext->key_len > 0 ? 1 : 0;
1866 } 1866 }
1867 1867
1868 if (set_key) { 1868 if (set_key) {
1869 /* Set the requested key first */ 1869 /* Set the requested key first */
1870 switch (alg) { 1870 switch (alg) {
1871 case IW_ENCODE_ALG_NONE: 1871 case IW_ENCODE_ALG_NONE:
1872 priv->wep_is_on = 0; 1872 priv->wep_is_on = 0;
1873 priv->encryption_level = 0; 1873 priv->encryption_level = 0;
1874 priv->pairwise_cipher_suite = CIPHER_SUITE_NONE; 1874 priv->pairwise_cipher_suite = CIPHER_SUITE_NONE;
1875 break; 1875 break;
1876 case IW_ENCODE_ALG_WEP: 1876 case IW_ENCODE_ALG_WEP:
1877 if (ext->key_len > 5) { 1877 if (ext->key_len > 5) {
1878 priv->wep_key_len[idx] = 13; 1878 priv->wep_key_len[idx] = 13;
1879 priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_128; 1879 priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_128;
1880 priv->encryption_level = 2; 1880 priv->encryption_level = 2;
1881 } else if (ext->key_len > 0) { 1881 } else if (ext->key_len > 0) {
1882 priv->wep_key_len[idx] = 5; 1882 priv->wep_key_len[idx] = 5;
1883 priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_64; 1883 priv->pairwise_cipher_suite = CIPHER_SUITE_WEP_64;
1884 priv->encryption_level = 1; 1884 priv->encryption_level = 1;
1885 } else { 1885 } else {
1886 return -EINVAL; 1886 return -EINVAL;
1887 } 1887 }
1888 priv->wep_is_on = 1; 1888 priv->wep_is_on = 1;
1889 memset(priv->wep_keys[idx], 0, 13); 1889 memset(priv->wep_keys[idx], 0, 13);
1890 key_len = min ((int)ext->key_len, priv->wep_key_len[idx]); 1890 key_len = min ((int)ext->key_len, priv->wep_key_len[idx]);
1891 memcpy(priv->wep_keys[idx], ext->key, key_len); 1891 memcpy(priv->wep_keys[idx], ext->key, key_len);
1892 break; 1892 break;
1893 default: 1893 default:
1894 return -EINVAL; 1894 return -EINVAL;
1895 } 1895 }
1896 } 1896 }
1897 1897
1898 return -EINPROGRESS; 1898 return -EINPROGRESS;
1899 } 1899 }
1900 1900
1901 static int atmel_get_encodeext(struct net_device *dev, 1901 static int atmel_get_encodeext(struct net_device *dev,
1902 struct iw_request_info *info, 1902 struct iw_request_info *info,
1903 union iwreq_data *wrqu, 1903 union iwreq_data *wrqu,
1904 char *extra) 1904 char *extra)
1905 { 1905 {
1906 struct atmel_private *priv = netdev_priv(dev); 1906 struct atmel_private *priv = netdev_priv(dev);
1907 struct iw_point *encoding = &wrqu->encoding; 1907 struct iw_point *encoding = &wrqu->encoding;
1908 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; 1908 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
1909 int idx, max_key_len; 1909 int idx, max_key_len;
1910 1910
1911 max_key_len = encoding->length - sizeof(*ext); 1911 max_key_len = encoding->length - sizeof(*ext);
1912 if (max_key_len < 0) 1912 if (max_key_len < 0)
1913 return -EINVAL; 1913 return -EINVAL;
1914 1914
1915 idx = encoding->flags & IW_ENCODE_INDEX; 1915 idx = encoding->flags & IW_ENCODE_INDEX;
1916 if (idx) { 1916 if (idx) {
1917 if (idx < 1 || idx > 4) 1917 if (idx < 1 || idx > 4)
1918 return -EINVAL; 1918 return -EINVAL;
1919 idx--; 1919 idx--;
1920 } else 1920 } else
1921 idx = priv->default_key; 1921 idx = priv->default_key;
1922 1922
1923 encoding->flags = idx + 1; 1923 encoding->flags = idx + 1;
1924 memset(ext, 0, sizeof(*ext)); 1924 memset(ext, 0, sizeof(*ext));
1925 1925
1926 if (!priv->wep_is_on) { 1926 if (!priv->wep_is_on) {
1927 ext->alg = IW_ENCODE_ALG_NONE; 1927 ext->alg = IW_ENCODE_ALG_NONE;
1928 ext->key_len = 0; 1928 ext->key_len = 0;
1929 encoding->flags |= IW_ENCODE_DISABLED; 1929 encoding->flags |= IW_ENCODE_DISABLED;
1930 } else { 1930 } else {
1931 if (priv->encryption_level > 0) 1931 if (priv->encryption_level > 0)
1932 ext->alg = IW_ENCODE_ALG_WEP; 1932 ext->alg = IW_ENCODE_ALG_WEP;
1933 else 1933 else
1934 return -EINVAL; 1934 return -EINVAL;
1935 1935
1936 ext->key_len = priv->wep_key_len[idx]; 1936 ext->key_len = priv->wep_key_len[idx];
1937 memcpy(ext->key, priv->wep_keys[idx], ext->key_len); 1937 memcpy(ext->key, priv->wep_keys[idx], ext->key_len);
1938 encoding->flags |= IW_ENCODE_ENABLED; 1938 encoding->flags |= IW_ENCODE_ENABLED;
1939 } 1939 }
1940 1940
1941 return 0; 1941 return 0;
1942 } 1942 }
1943 1943
1944 static int atmel_set_auth(struct net_device *dev, 1944 static int atmel_set_auth(struct net_device *dev,
1945 struct iw_request_info *info, 1945 struct iw_request_info *info,
1946 union iwreq_data *wrqu, char *extra) 1946 union iwreq_data *wrqu, char *extra)
1947 { 1947 {
1948 struct atmel_private *priv = netdev_priv(dev); 1948 struct atmel_private *priv = netdev_priv(dev);
1949 struct iw_param *param = &wrqu->param; 1949 struct iw_param *param = &wrqu->param;
1950 1950
1951 switch (param->flags & IW_AUTH_INDEX) { 1951 switch (param->flags & IW_AUTH_INDEX) {
1952 case IW_AUTH_WPA_VERSION: 1952 case IW_AUTH_WPA_VERSION:
1953 case IW_AUTH_CIPHER_PAIRWISE: 1953 case IW_AUTH_CIPHER_PAIRWISE:
1954 case IW_AUTH_CIPHER_GROUP: 1954 case IW_AUTH_CIPHER_GROUP:
1955 case IW_AUTH_KEY_MGMT: 1955 case IW_AUTH_KEY_MGMT:
1956 case IW_AUTH_RX_UNENCRYPTED_EAPOL: 1956 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1957 case IW_AUTH_PRIVACY_INVOKED: 1957 case IW_AUTH_PRIVACY_INVOKED:
1958 /* 1958 /*
1959 * atmel does not use these parameters 1959 * atmel does not use these parameters
1960 */ 1960 */
1961 break; 1961 break;
1962 1962
1963 case IW_AUTH_DROP_UNENCRYPTED: 1963 case IW_AUTH_DROP_UNENCRYPTED:
1964 priv->exclude_unencrypted = param->value ? 1 : 0; 1964 priv->exclude_unencrypted = param->value ? 1 : 0;
1965 break; 1965 break;
1966 1966
1967 case IW_AUTH_80211_AUTH_ALG: { 1967 case IW_AUTH_80211_AUTH_ALG: {
1968 if (param->value & IW_AUTH_ALG_SHARED_KEY) { 1968 if (param->value & IW_AUTH_ALG_SHARED_KEY) {
1969 priv->exclude_unencrypted = 1; 1969 priv->exclude_unencrypted = 1;
1970 } else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM) { 1970 } else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM) {
1971 priv->exclude_unencrypted = 0; 1971 priv->exclude_unencrypted = 0;
1972 } else 1972 } else
1973 return -EINVAL; 1973 return -EINVAL;
1974 break; 1974 break;
1975 } 1975 }
1976 1976
1977 case IW_AUTH_WPA_ENABLED: 1977 case IW_AUTH_WPA_ENABLED:
1978 /* Silently accept disable of WPA */ 1978 /* Silently accept disable of WPA */
1979 if (param->value > 0) 1979 if (param->value > 0)
1980 return -EOPNOTSUPP; 1980 return -EOPNOTSUPP;
1981 break; 1981 break;
1982 1982
1983 default: 1983 default:
1984 return -EOPNOTSUPP; 1984 return -EOPNOTSUPP;
1985 } 1985 }
1986 return -EINPROGRESS; 1986 return -EINPROGRESS;
1987 } 1987 }
1988 1988
1989 static int atmel_get_auth(struct net_device *dev, 1989 static int atmel_get_auth(struct net_device *dev,
1990 struct iw_request_info *info, 1990 struct iw_request_info *info,
1991 union iwreq_data *wrqu, char *extra) 1991 union iwreq_data *wrqu, char *extra)
1992 { 1992 {
1993 struct atmel_private *priv = netdev_priv(dev); 1993 struct atmel_private *priv = netdev_priv(dev);
1994 struct iw_param *param = &wrqu->param; 1994 struct iw_param *param = &wrqu->param;
1995 1995
1996 switch (param->flags & IW_AUTH_INDEX) { 1996 switch (param->flags & IW_AUTH_INDEX) {
1997 case IW_AUTH_DROP_UNENCRYPTED: 1997 case IW_AUTH_DROP_UNENCRYPTED:
1998 param->value = priv->exclude_unencrypted; 1998 param->value = priv->exclude_unencrypted;
1999 break; 1999 break;
2000 2000
2001 case IW_AUTH_80211_AUTH_ALG: 2001 case IW_AUTH_80211_AUTH_ALG:
2002 if (priv->exclude_unencrypted == 1) 2002 if (priv->exclude_unencrypted == 1)
2003 param->value = IW_AUTH_ALG_SHARED_KEY; 2003 param->value = IW_AUTH_ALG_SHARED_KEY;
2004 else 2004 else
2005 param->value = IW_AUTH_ALG_OPEN_SYSTEM; 2005 param->value = IW_AUTH_ALG_OPEN_SYSTEM;
2006 break; 2006 break;
2007 2007
2008 case IW_AUTH_WPA_ENABLED: 2008 case IW_AUTH_WPA_ENABLED:
2009 param->value = 0; 2009 param->value = 0;
2010 break; 2010 break;
2011 2011
2012 default: 2012 default:
2013 return -EOPNOTSUPP; 2013 return -EOPNOTSUPP;
2014 } 2014 }
2015 return 0; 2015 return 0;
2016 } 2016 }
2017 2017
2018 2018
2019 static int atmel_get_name(struct net_device *dev, 2019 static int atmel_get_name(struct net_device *dev,
2020 struct iw_request_info *info, 2020 struct iw_request_info *info,
2021 char *cwrq, 2021 char *cwrq,
2022 char *extra) 2022 char *extra)
2023 { 2023 {
2024 strcpy(cwrq, "IEEE 802.11-DS"); 2024 strcpy(cwrq, "IEEE 802.11-DS");
2025 return 0; 2025 return 0;
2026 } 2026 }
2027 2027
2028 static int atmel_set_rate(struct net_device *dev, 2028 static int atmel_set_rate(struct net_device *dev,
2029 struct iw_request_info *info, 2029 struct iw_request_info *info,
2030 struct iw_param *vwrq, 2030 struct iw_param *vwrq,
2031 char *extra) 2031 char *extra)
2032 { 2032 {
2033 struct atmel_private *priv = netdev_priv(dev); 2033 struct atmel_private *priv = netdev_priv(dev);
2034 2034
2035 if (vwrq->fixed == 0) { 2035 if (vwrq->fixed == 0) {
2036 priv->tx_rate = 3; 2036 priv->tx_rate = 3;
2037 priv->auto_tx_rate = 1; 2037 priv->auto_tx_rate = 1;
2038 } else { 2038 } else {
2039 priv->auto_tx_rate = 0; 2039 priv->auto_tx_rate = 0;
2040 2040
2041 /* Which type of value ? */ 2041 /* Which type of value ? */
2042 if ((vwrq->value < 4) && (vwrq->value >= 0)) { 2042 if ((vwrq->value < 4) && (vwrq->value >= 0)) {
2043 /* Setting by rate index */ 2043 /* Setting by rate index */
2044 priv->tx_rate = vwrq->value; 2044 priv->tx_rate = vwrq->value;
2045 } else { 2045 } else {
2046 /* Setting by frequency value */ 2046 /* Setting by frequency value */
2047 switch (vwrq->value) { 2047 switch (vwrq->value) {
2048 case 1000000: 2048 case 1000000:
2049 priv->tx_rate = 0; 2049 priv->tx_rate = 0;
2050 break; 2050 break;
2051 case 2000000: 2051 case 2000000:
2052 priv->tx_rate = 1; 2052 priv->tx_rate = 1;
2053 break; 2053 break;
2054 case 5500000: 2054 case 5500000:
2055 priv->tx_rate = 2; 2055 priv->tx_rate = 2;
2056 break; 2056 break;
2057 case 11000000: 2057 case 11000000:
2058 priv->tx_rate = 3; 2058 priv->tx_rate = 3;
2059 break; 2059 break;
2060 default: 2060 default:
2061 return -EINVAL; 2061 return -EINVAL;
2062 } 2062 }
2063 } 2063 }
2064 } 2064 }
2065 2065
2066 return -EINPROGRESS; 2066 return -EINPROGRESS;
2067 } 2067 }
2068 2068
2069 static int atmel_set_mode(struct net_device *dev, 2069 static int atmel_set_mode(struct net_device *dev,
2070 struct iw_request_info *info, 2070 struct iw_request_info *info,
2071 __u32 *uwrq, 2071 __u32 *uwrq,
2072 char *extra) 2072 char *extra)
2073 { 2073 {
2074 struct atmel_private *priv = netdev_priv(dev); 2074 struct atmel_private *priv = netdev_priv(dev);
2075 2075
2076 if (*uwrq != IW_MODE_ADHOC && *uwrq != IW_MODE_INFRA) 2076 if (*uwrq != IW_MODE_ADHOC && *uwrq != IW_MODE_INFRA)
2077 return -EINVAL; 2077 return -EINVAL;
2078 2078
2079 priv->operating_mode = *uwrq; 2079 priv->operating_mode = *uwrq;
2080 return -EINPROGRESS; 2080 return -EINPROGRESS;
2081 } 2081 }
2082 2082
2083 static int atmel_get_mode(struct net_device *dev, 2083 static int atmel_get_mode(struct net_device *dev,
2084 struct iw_request_info *info, 2084 struct iw_request_info *info,
2085 __u32 *uwrq, 2085 __u32 *uwrq,
2086 char *extra) 2086 char *extra)
2087 { 2087 {
2088 struct atmel_private *priv = netdev_priv(dev); 2088 struct atmel_private *priv = netdev_priv(dev);
2089 2089
2090 *uwrq = priv->operating_mode; 2090 *uwrq = priv->operating_mode;
2091 return 0; 2091 return 0;
2092 } 2092 }
2093 2093
2094 static int atmel_get_rate(struct net_device *dev, 2094 static int atmel_get_rate(struct net_device *dev,
2095 struct iw_request_info *info, 2095 struct iw_request_info *info,
2096 struct iw_param *vwrq, 2096 struct iw_param *vwrq,
2097 char *extra) 2097 char *extra)
2098 { 2098 {
2099 struct atmel_private *priv = netdev_priv(dev); 2099 struct atmel_private *priv = netdev_priv(dev);
2100 2100
2101 if (priv->auto_tx_rate) { 2101 if (priv->auto_tx_rate) {
2102 vwrq->fixed = 0; 2102 vwrq->fixed = 0;
2103 vwrq->value = 11000000; 2103 vwrq->value = 11000000;
2104 } else { 2104 } else {
2105 vwrq->fixed = 1; 2105 vwrq->fixed = 1;
2106 switch (priv->tx_rate) { 2106 switch (priv->tx_rate) {
2107 case 0: 2107 case 0:
2108 vwrq->value = 1000000; 2108 vwrq->value = 1000000;
2109 break; 2109 break;
2110 case 1: 2110 case 1:
2111 vwrq->value = 2000000; 2111 vwrq->value = 2000000;
2112 break; 2112 break;
2113 case 2: 2113 case 2:
2114 vwrq->value = 5500000; 2114 vwrq->value = 5500000;
2115 break; 2115 break;
2116 case 3: 2116 case 3:
2117 vwrq->value = 11000000; 2117 vwrq->value = 11000000;
2118 break; 2118 break;
2119 } 2119 }
2120 } 2120 }
2121 return 0; 2121 return 0;
2122 } 2122 }
2123 2123
2124 static int atmel_set_power(struct net_device *dev, 2124 static int atmel_set_power(struct net_device *dev,
2125 struct iw_request_info *info, 2125 struct iw_request_info *info,
2126 struct iw_param *vwrq, 2126 struct iw_param *vwrq,
2127 char *extra) 2127 char *extra)
2128 { 2128 {
2129 struct atmel_private *priv = netdev_priv(dev); 2129 struct atmel_private *priv = netdev_priv(dev);
2130 priv->power_mode = vwrq->disabled ? 0 : 1; 2130 priv->power_mode = vwrq->disabled ? 0 : 1;
2131 return -EINPROGRESS; 2131 return -EINPROGRESS;
2132 } 2132 }
2133 2133
2134 static int atmel_get_power(struct net_device *dev, 2134 static int atmel_get_power(struct net_device *dev,
2135 struct iw_request_info *info, 2135 struct iw_request_info *info,
2136 struct iw_param *vwrq, 2136 struct iw_param *vwrq,
2137 char *extra) 2137 char *extra)
2138 { 2138 {
2139 struct atmel_private *priv = netdev_priv(dev); 2139 struct atmel_private *priv = netdev_priv(dev);
2140 vwrq->disabled = priv->power_mode ? 0 : 1; 2140 vwrq->disabled = priv->power_mode ? 0 : 1;
2141 vwrq->flags = IW_POWER_ON; 2141 vwrq->flags = IW_POWER_ON;
2142 return 0; 2142 return 0;
2143 } 2143 }
2144 2144
2145 static int atmel_set_retry(struct net_device *dev, 2145 static int atmel_set_retry(struct net_device *dev,
2146 struct iw_request_info *info, 2146 struct iw_request_info *info,
2147 struct iw_param *vwrq, 2147 struct iw_param *vwrq,
2148 char *extra) 2148 char *extra)
2149 { 2149 {
2150 struct atmel_private *priv = netdev_priv(dev); 2150 struct atmel_private *priv = netdev_priv(dev);
2151 2151
2152 if (!vwrq->disabled && (vwrq->flags & IW_RETRY_LIMIT)) { 2152 if (!vwrq->disabled && (vwrq->flags & IW_RETRY_LIMIT)) {
2153 if (vwrq->flags & IW_RETRY_LONG) 2153 if (vwrq->flags & IW_RETRY_LONG)
2154 priv->long_retry = vwrq->value; 2154 priv->long_retry = vwrq->value;
2155 else if (vwrq->flags & IW_RETRY_SHORT) 2155 else if (vwrq->flags & IW_RETRY_SHORT)
2156 priv->short_retry = vwrq->value; 2156 priv->short_retry = vwrq->value;
2157 else { 2157 else {
2158 /* No modifier : set both */ 2158 /* No modifier : set both */
2159 priv->long_retry = vwrq->value; 2159 priv->long_retry = vwrq->value;
2160 priv->short_retry = vwrq->value; 2160 priv->short_retry = vwrq->value;
2161 } 2161 }
2162 return -EINPROGRESS; 2162 return -EINPROGRESS;
2163 } 2163 }
2164 2164
2165 return -EINVAL; 2165 return -EINVAL;
2166 } 2166 }
2167 2167
2168 static int atmel_get_retry(struct net_device *dev, 2168 static int atmel_get_retry(struct net_device *dev,
2169 struct iw_request_info *info, 2169 struct iw_request_info *info,
2170 struct iw_param *vwrq, 2170 struct iw_param *vwrq,
2171 char *extra) 2171 char *extra)
2172 { 2172 {
2173 struct atmel_private *priv = netdev_priv(dev); 2173 struct atmel_private *priv = netdev_priv(dev);
2174 2174
2175 vwrq->disabled = 0; /* Can't be disabled */ 2175 vwrq->disabled = 0; /* Can't be disabled */
2176 2176
2177 /* Note : by default, display the short retry number */ 2177 /* Note : by default, display the short retry number */
2178 if (vwrq->flags & IW_RETRY_LONG) { 2178 if (vwrq->flags & IW_RETRY_LONG) {
2179 vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG; 2179 vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
2180 vwrq->value = priv->long_retry; 2180 vwrq->value = priv->long_retry;
2181 } else { 2181 } else {
2182 vwrq->flags = IW_RETRY_LIMIT; 2182 vwrq->flags = IW_RETRY_LIMIT;
2183 vwrq->value = priv->short_retry; 2183 vwrq->value = priv->short_retry;
2184 if (priv->long_retry != priv->short_retry) 2184 if (priv->long_retry != priv->short_retry)
2185 vwrq->flags |= IW_RETRY_SHORT; 2185 vwrq->flags |= IW_RETRY_SHORT;
2186 } 2186 }
2187 2187
2188 return 0; 2188 return 0;
2189 } 2189 }
2190 2190
2191 static int atmel_set_rts(struct net_device *dev, 2191 static int atmel_set_rts(struct net_device *dev,
2192 struct iw_request_info *info, 2192 struct iw_request_info *info,
2193 struct iw_param *vwrq, 2193 struct iw_param *vwrq,
2194 char *extra) 2194 char *extra)
2195 { 2195 {
2196 struct atmel_private *priv = netdev_priv(dev); 2196 struct atmel_private *priv = netdev_priv(dev);
2197 int rthr = vwrq->value; 2197 int rthr = vwrq->value;
2198 2198
2199 if (vwrq->disabled) 2199 if (vwrq->disabled)
2200 rthr = 2347; 2200 rthr = 2347;
2201 if ((rthr < 0) || (rthr > 2347)) { 2201 if ((rthr < 0) || (rthr > 2347)) {
2202 return -EINVAL; 2202 return -EINVAL;
2203 } 2203 }
2204 priv->rts_threshold = rthr; 2204 priv->rts_threshold = rthr;
2205 2205
2206 return -EINPROGRESS; /* Call commit handler */ 2206 return -EINPROGRESS; /* Call commit handler */
2207 } 2207 }
2208 2208
2209 static int atmel_get_rts(struct net_device *dev, 2209 static int atmel_get_rts(struct net_device *dev,
2210 struct iw_request_info *info, 2210 struct iw_request_info *info,
2211 struct iw_param *vwrq, 2211 struct iw_param *vwrq,
2212 char *extra) 2212 char *extra)
2213 { 2213 {
2214 struct atmel_private *priv = netdev_priv(dev); 2214 struct atmel_private *priv = netdev_priv(dev);
2215 2215
2216 vwrq->value = priv->rts_threshold; 2216 vwrq->value = priv->rts_threshold;
2217 vwrq->disabled = (vwrq->value >= 2347); 2217 vwrq->disabled = (vwrq->value >= 2347);
2218 vwrq->fixed = 1; 2218 vwrq->fixed = 1;
2219 2219
2220 return 0; 2220 return 0;
2221 } 2221 }
2222 2222
2223 static int atmel_set_frag(struct net_device *dev, 2223 static int atmel_set_frag(struct net_device *dev,
2224 struct iw_request_info *info, 2224 struct iw_request_info *info,
2225 struct iw_param *vwrq, 2225 struct iw_param *vwrq,
2226 char *extra) 2226 char *extra)
2227 { 2227 {
2228 struct atmel_private *priv = netdev_priv(dev); 2228 struct atmel_private *priv = netdev_priv(dev);
2229 int fthr = vwrq->value; 2229 int fthr = vwrq->value;
2230 2230
2231 if (vwrq->disabled) 2231 if (vwrq->disabled)
2232 fthr = 2346; 2232 fthr = 2346;
2233 if ((fthr < 256) || (fthr > 2346)) { 2233 if ((fthr < 256) || (fthr > 2346)) {
2234 return -EINVAL; 2234 return -EINVAL;
2235 } 2235 }
2236 fthr &= ~0x1; /* Get an even value - is it really needed ??? */ 2236 fthr &= ~0x1; /* Get an even value - is it really needed ??? */
2237 priv->frag_threshold = fthr; 2237 priv->frag_threshold = fthr;
2238 2238
2239 return -EINPROGRESS; /* Call commit handler */ 2239 return -EINPROGRESS; /* Call commit handler */
2240 } 2240 }
2241 2241
2242 static int atmel_get_frag(struct net_device *dev, 2242 static int atmel_get_frag(struct net_device *dev,
2243 struct iw_request_info *info, 2243 struct iw_request_info *info,
2244 struct iw_param *vwrq, 2244 struct iw_param *vwrq,
2245 char *extra) 2245 char *extra)
2246 { 2246 {
2247 struct atmel_private *priv = netdev_priv(dev); 2247 struct atmel_private *priv = netdev_priv(dev);
2248 2248
2249 vwrq->value = priv->frag_threshold; 2249 vwrq->value = priv->frag_threshold;
2250 vwrq->disabled = (vwrq->value >= 2346); 2250 vwrq->disabled = (vwrq->value >= 2346);
2251 vwrq->fixed = 1; 2251 vwrq->fixed = 1;
2252 2252
2253 return 0; 2253 return 0;
2254 } 2254 }
2255 2255
2256 static int atmel_set_freq(struct net_device *dev, 2256 static int atmel_set_freq(struct net_device *dev,
2257 struct iw_request_info *info, 2257 struct iw_request_info *info,
2258 struct iw_freq *fwrq, 2258 struct iw_freq *fwrq,
2259 char *extra) 2259 char *extra)
2260 { 2260 {
2261 struct atmel_private *priv = netdev_priv(dev); 2261 struct atmel_private *priv = netdev_priv(dev);
2262 int rc = -EINPROGRESS; /* Call commit handler */ 2262 int rc = -EINPROGRESS; /* Call commit handler */
2263 2263
2264 /* If setting by frequency, convert to a channel */ 2264 /* If setting by frequency, convert to a channel */
2265 if (fwrq->e == 1) { 2265 if (fwrq->e == 1) {
2266 int f = fwrq->m / 100000; 2266 int f = fwrq->m / 100000;
2267 2267
2268 /* Hack to fall through... */ 2268 /* Hack to fall through... */
2269 fwrq->e = 0; 2269 fwrq->e = 0;
2270 fwrq->m = ieee80211_freq_to_dsss_chan(f); 2270 fwrq->m = ieee80211_freq_to_dsss_chan(f);
2271 } 2271 }
2272 /* Setting by channel number */ 2272 /* Setting by channel number */
2273 if ((fwrq->m > 1000) || (fwrq->e > 0)) 2273 if ((fwrq->m > 1000) || (fwrq->e > 0))
2274 rc = -EOPNOTSUPP; 2274 rc = -EOPNOTSUPP;
2275 else { 2275 else {
2276 int channel = fwrq->m; 2276 int channel = fwrq->m;
2277 if (atmel_validate_channel(priv, channel) == 0) { 2277 if (atmel_validate_channel(priv, channel) == 0) {
2278 priv->channel = channel; 2278 priv->channel = channel;
2279 } else { 2279 } else {
2280 rc = -EINVAL; 2280 rc = -EINVAL;
2281 } 2281 }
2282 } 2282 }
2283 return rc; 2283 return rc;
2284 } 2284 }
2285 2285
2286 static int atmel_get_freq(struct net_device *dev, 2286 static int atmel_get_freq(struct net_device *dev,
2287 struct iw_request_info *info, 2287 struct iw_request_info *info,
2288 struct iw_freq *fwrq, 2288 struct iw_freq *fwrq,
2289 char *extra) 2289 char *extra)
2290 { 2290 {
2291 struct atmel_private *priv = netdev_priv(dev); 2291 struct atmel_private *priv = netdev_priv(dev);
2292 2292
2293 fwrq->m = priv->channel; 2293 fwrq->m = priv->channel;
2294 fwrq->e = 0; 2294 fwrq->e = 0;
2295 return 0; 2295 return 0;
2296 } 2296 }
2297 2297
2298 static int atmel_set_scan(struct net_device *dev, 2298 static int atmel_set_scan(struct net_device *dev,
2299 struct iw_request_info *info, 2299 struct iw_request_info *info,
2300 struct iw_point *dwrq, 2300 struct iw_point *dwrq,
2301 char *extra) 2301 char *extra)
2302 { 2302 {
2303 struct atmel_private *priv = netdev_priv(dev); 2303 struct atmel_private *priv = netdev_priv(dev);
2304 unsigned long flags; 2304 unsigned long flags;
2305 2305
2306 /* Note : you may have realised that, as this is a SET operation, 2306 /* Note : you may have realised that, as this is a SET operation,
2307 * this is privileged and therefore a normal user can't 2307 * this is privileged and therefore a normal user can't
2308 * perform scanning. 2308 * perform scanning.
2309 * This is not an error, while the device perform scanning, 2309 * This is not an error, while the device perform scanning,
2310 * traffic doesn't flow, so it's a perfect DoS... 2310 * traffic doesn't flow, so it's a perfect DoS...
2311 * Jean II */ 2311 * Jean II */
2312 2312
2313 if (priv->station_state == STATION_STATE_DOWN) 2313 if (priv->station_state == STATION_STATE_DOWN)
2314 return -EAGAIN; 2314 return -EAGAIN;
2315 2315
2316 /* Timeout old surveys. */ 2316 /* Timeout old surveys. */
2317 if (time_after(jiffies, priv->last_survey + 20 * HZ)) 2317 if (time_after(jiffies, priv->last_survey + 20 * HZ))
2318 priv->site_survey_state = SITE_SURVEY_IDLE; 2318 priv->site_survey_state = SITE_SURVEY_IDLE;
2319 priv->last_survey = jiffies; 2319 priv->last_survey = jiffies;
2320 2320
2321 /* Initiate a scan command */ 2321 /* Initiate a scan command */
2322 if (priv->site_survey_state == SITE_SURVEY_IN_PROGRESS) 2322 if (priv->site_survey_state == SITE_SURVEY_IN_PROGRESS)
2323 return -EBUSY; 2323 return -EBUSY;
2324 2324
2325 del_timer_sync(&priv->management_timer); 2325 del_timer_sync(&priv->management_timer);
2326 spin_lock_irqsave(&priv->irqlock, flags); 2326 spin_lock_irqsave(&priv->irqlock, flags);
2327 2327
2328 priv->site_survey_state = SITE_SURVEY_IN_PROGRESS; 2328 priv->site_survey_state = SITE_SURVEY_IN_PROGRESS;
2329 priv->fast_scan = 0; 2329 priv->fast_scan = 0;
2330 atmel_scan(priv, 0); 2330 atmel_scan(priv, 0);
2331 spin_unlock_irqrestore(&priv->irqlock, flags); 2331 spin_unlock_irqrestore(&priv->irqlock, flags);
2332 2332
2333 return 0; 2333 return 0;
2334 } 2334 }
2335 2335
2336 static int atmel_get_scan(struct net_device *dev, 2336 static int atmel_get_scan(struct net_device *dev,
2337 struct iw_request_info *info, 2337 struct iw_request_info *info,
2338 struct iw_point *dwrq, 2338 struct iw_point *dwrq,
2339 char *extra) 2339 char *extra)
2340 { 2340 {
2341 struct atmel_private *priv = netdev_priv(dev); 2341 struct atmel_private *priv = netdev_priv(dev);
2342 int i; 2342 int i;
2343 char *current_ev = extra; 2343 char *current_ev = extra;
2344 struct iw_event iwe; 2344 struct iw_event iwe;
2345 2345
2346 if (priv->site_survey_state != SITE_SURVEY_COMPLETED) 2346 if (priv->site_survey_state != SITE_SURVEY_COMPLETED)
2347 return -EAGAIN; 2347 return -EAGAIN;
2348 2348
2349 for (i = 0; i < priv->BSS_list_entries; i++) { 2349 for (i = 0; i < priv->BSS_list_entries; i++) {
2350 iwe.cmd = SIOCGIWAP; 2350 iwe.cmd = SIOCGIWAP;
2351 iwe.u.ap_addr.sa_family = ARPHRD_ETHER; 2351 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
2352 memcpy(iwe.u.ap_addr.sa_data, priv->BSSinfo[i].BSSID, 6); 2352 memcpy(iwe.u.ap_addr.sa_data, priv->BSSinfo[i].BSSID, 6);
2353 current_ev = iwe_stream_add_event(info, current_ev, 2353 current_ev = iwe_stream_add_event(info, current_ev,
2354 extra + IW_SCAN_MAX_DATA, 2354 extra + IW_SCAN_MAX_DATA,
2355 &iwe, IW_EV_ADDR_LEN); 2355 &iwe, IW_EV_ADDR_LEN);
2356 2356
2357 iwe.u.data.length = priv->BSSinfo[i].SSIDsize; 2357 iwe.u.data.length = priv->BSSinfo[i].SSIDsize;
2358 if (iwe.u.data.length > 32) 2358 if (iwe.u.data.length > 32)
2359 iwe.u.data.length = 32; 2359 iwe.u.data.length = 32;
2360 iwe.cmd = SIOCGIWESSID; 2360 iwe.cmd = SIOCGIWESSID;
2361 iwe.u.data.flags = 1; 2361 iwe.u.data.flags = 1;
2362 current_ev = iwe_stream_add_point(info, current_ev, 2362 current_ev = iwe_stream_add_point(info, current_ev,
2363 extra + IW_SCAN_MAX_DATA, 2363 extra + IW_SCAN_MAX_DATA,
2364 &iwe, priv->BSSinfo[i].SSID); 2364 &iwe, priv->BSSinfo[i].SSID);
2365 2365
2366 iwe.cmd = SIOCGIWMODE; 2366 iwe.cmd = SIOCGIWMODE;
2367 iwe.u.mode = priv->BSSinfo[i].BSStype; 2367 iwe.u.mode = priv->BSSinfo[i].BSStype;
2368 current_ev = iwe_stream_add_event(info, current_ev, 2368 current_ev = iwe_stream_add_event(info, current_ev,
2369 extra + IW_SCAN_MAX_DATA, 2369 extra + IW_SCAN_MAX_DATA,
2370 &iwe, IW_EV_UINT_LEN); 2370 &iwe, IW_EV_UINT_LEN);
2371 2371
2372 iwe.cmd = SIOCGIWFREQ; 2372 iwe.cmd = SIOCGIWFREQ;
2373 iwe.u.freq.m = priv->BSSinfo[i].channel; 2373 iwe.u.freq.m = priv->BSSinfo[i].channel;
2374 iwe.u.freq.e = 0; 2374 iwe.u.freq.e = 0;
2375 current_ev = iwe_stream_add_event(info, current_ev, 2375 current_ev = iwe_stream_add_event(info, current_ev,
2376 extra + IW_SCAN_MAX_DATA, 2376 extra + IW_SCAN_MAX_DATA,
2377 &iwe, IW_EV_FREQ_LEN); 2377 &iwe, IW_EV_FREQ_LEN);
2378 2378
2379 /* Add quality statistics */ 2379 /* Add quality statistics */
2380 iwe.cmd = IWEVQUAL; 2380 iwe.cmd = IWEVQUAL;
2381 iwe.u.qual.level = priv->BSSinfo[i].RSSI; 2381 iwe.u.qual.level = priv->BSSinfo[i].RSSI;
2382 iwe.u.qual.qual = iwe.u.qual.level; 2382 iwe.u.qual.qual = iwe.u.qual.level;
2383 /* iwe.u.qual.noise = SOMETHING */ 2383 /* iwe.u.qual.noise = SOMETHING */
2384 current_ev = iwe_stream_add_event(info, current_ev, 2384 current_ev = iwe_stream_add_event(info, current_ev,
2385 extra + IW_SCAN_MAX_DATA, 2385 extra + IW_SCAN_MAX_DATA,
2386 &iwe, IW_EV_QUAL_LEN); 2386 &iwe, IW_EV_QUAL_LEN);
2387 2387
2388 2388
2389 iwe.cmd = SIOCGIWENCODE; 2389 iwe.cmd = SIOCGIWENCODE;
2390 if (priv->BSSinfo[i].UsingWEP) 2390 if (priv->BSSinfo[i].UsingWEP)
2391 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; 2391 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
2392 else 2392 else
2393 iwe.u.data.flags = IW_ENCODE_DISABLED; 2393 iwe.u.data.flags = IW_ENCODE_DISABLED;
2394 iwe.u.data.length = 0; 2394 iwe.u.data.length = 0;
2395 current_ev = iwe_stream_add_point(info, current_ev, 2395 current_ev = iwe_stream_add_point(info, current_ev,
2396 extra + IW_SCAN_MAX_DATA, 2396 extra + IW_SCAN_MAX_DATA,
2397 &iwe, NULL); 2397 &iwe, NULL);
2398 } 2398 }
2399 2399
2400 /* Length of data */ 2400 /* Length of data */
2401 dwrq->length = (current_ev - extra); 2401 dwrq->length = (current_ev - extra);
2402 dwrq->flags = 0; 2402 dwrq->flags = 0;
2403 2403
2404 return 0; 2404 return 0;
2405 } 2405 }
2406 2406
2407 static int atmel_get_range(struct net_device *dev, 2407 static int atmel_get_range(struct net_device *dev,
2408 struct iw_request_info *info, 2408 struct iw_request_info *info,
2409 struct iw_point *dwrq, 2409 struct iw_point *dwrq,
2410 char *extra) 2410 char *extra)
2411 { 2411 {
2412 struct atmel_private *priv = netdev_priv(dev); 2412 struct atmel_private *priv = netdev_priv(dev);
2413 struct iw_range *range = (struct iw_range *) extra; 2413 struct iw_range *range = (struct iw_range *) extra;
2414 int k, i, j; 2414 int k, i, j;
2415 2415
2416 dwrq->length = sizeof(struct iw_range); 2416 dwrq->length = sizeof(struct iw_range);
2417 memset(range, 0, sizeof(struct iw_range)); 2417 memset(range, 0, sizeof(struct iw_range));
2418 range->min_nwid = 0x0000; 2418 range->min_nwid = 0x0000;
2419 range->max_nwid = 0x0000; 2419 range->max_nwid = 0x0000;
2420 range->num_channels = 0; 2420 range->num_channels = 0;
2421 for (j = 0; j < ARRAY_SIZE(channel_table); j++) 2421 for (j = 0; j < ARRAY_SIZE(channel_table); j++)
2422 if (priv->reg_domain == channel_table[j].reg_domain) { 2422 if (priv->reg_domain == channel_table[j].reg_domain) {
2423 range->num_channels = channel_table[j].max - channel_table[j].min + 1; 2423 range->num_channels = channel_table[j].max - channel_table[j].min + 1;
2424 break; 2424 break;
2425 } 2425 }
2426 if (range->num_channels != 0) { 2426 if (range->num_channels != 0) {
2427 for (k = 0, i = channel_table[j].min; i <= channel_table[j].max; i++) { 2427 for (k = 0, i = channel_table[j].min; i <= channel_table[j].max; i++) {
2428 range->freq[k].i = i; /* List index */ 2428 range->freq[k].i = i; /* List index */
2429 2429
2430 /* Values in MHz -> * 10^5 * 10 */ 2430 /* Values in MHz -> * 10^5 * 10 */
2431 range->freq[k].m = (ieee80211_dsss_chan_to_freq(i) * 2431 range->freq[k].m = (ieee80211_dsss_chan_to_freq(i) *
2432 100000); 2432 100000);
2433 range->freq[k++].e = 1; 2433 range->freq[k++].e = 1;
2434 } 2434 }
2435 range->num_frequency = k; 2435 range->num_frequency = k;
2436 } 2436 }
2437 2437
2438 range->max_qual.qual = 100; 2438 range->max_qual.qual = 100;
2439 range->max_qual.level = 100; 2439 range->max_qual.level = 100;
2440 range->max_qual.noise = 0; 2440 range->max_qual.noise = 0;
2441 range->max_qual.updated = IW_QUAL_NOISE_INVALID; 2441 range->max_qual.updated = IW_QUAL_NOISE_INVALID;
2442 2442
2443 range->avg_qual.qual = 50; 2443 range->avg_qual.qual = 50;
2444 range->avg_qual.level = 50; 2444 range->avg_qual.level = 50;
2445 range->avg_qual.noise = 0; 2445 range->avg_qual.noise = 0;
2446 range->avg_qual.updated = IW_QUAL_NOISE_INVALID; 2446 range->avg_qual.updated = IW_QUAL_NOISE_INVALID;
2447 2447
2448 range->sensitivity = 0; 2448 range->sensitivity = 0;
2449 2449
2450 range->bitrate[0] = 1000000; 2450 range->bitrate[0] = 1000000;
2451 range->bitrate[1] = 2000000; 2451 range->bitrate[1] = 2000000;
2452 range->bitrate[2] = 5500000; 2452 range->bitrate[2] = 5500000;
2453 range->bitrate[3] = 11000000; 2453 range->bitrate[3] = 11000000;
2454 range->num_bitrates = 4; 2454 range->num_bitrates = 4;
2455 2455
2456 range->min_rts = 0; 2456 range->min_rts = 0;
2457 range->max_rts = 2347; 2457 range->max_rts = 2347;
2458 range->min_frag = 256; 2458 range->min_frag = 256;
2459 range->max_frag = 2346; 2459 range->max_frag = 2346;
2460 2460
2461 range->encoding_size[0] = 5; 2461 range->encoding_size[0] = 5;
2462 range->encoding_size[1] = 13; 2462 range->encoding_size[1] = 13;
2463 range->num_encoding_sizes = 2; 2463 range->num_encoding_sizes = 2;
2464 range->max_encoding_tokens = 4; 2464 range->max_encoding_tokens = 4;
2465 2465
2466 range->pmp_flags = IW_POWER_ON; 2466 range->pmp_flags = IW_POWER_ON;
2467 range->pmt_flags = IW_POWER_ON; 2467 range->pmt_flags = IW_POWER_ON;
2468 range->pm_capa = 0; 2468 range->pm_capa = 0;
2469 2469
2470 range->we_version_source = WIRELESS_EXT; 2470 range->we_version_source = WIRELESS_EXT;
2471 range->we_version_compiled = WIRELESS_EXT; 2471 range->we_version_compiled = WIRELESS_EXT;
2472 range->retry_capa = IW_RETRY_LIMIT ; 2472 range->retry_capa = IW_RETRY_LIMIT ;
2473 range->retry_flags = IW_RETRY_LIMIT; 2473 range->retry_flags = IW_RETRY_LIMIT;
2474 range->r_time_flags = 0; 2474 range->r_time_flags = 0;
2475 range->min_retry = 1; 2475 range->min_retry = 1;
2476 range->max_retry = 65535; 2476 range->max_retry = 65535;
2477 2477
2478 return 0; 2478 return 0;
2479 } 2479 }
2480 2480
2481 static int atmel_set_wap(struct net_device *dev, 2481 static int atmel_set_wap(struct net_device *dev,
2482 struct iw_request_info *info, 2482 struct iw_request_info *info,
2483 struct sockaddr *awrq, 2483 struct sockaddr *awrq,
2484 char *extra) 2484 char *extra)
2485 { 2485 {
2486 struct atmel_private *priv = netdev_priv(dev); 2486 struct atmel_private *priv = netdev_priv(dev);
2487 int i; 2487 int i;
2488 static const u8 any[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; 2488 static const u8 any[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
2489 static const u8 off[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 2489 static const u8 off[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
2490 unsigned long flags; 2490 unsigned long flags;
2491 2491
2492 if (awrq->sa_family != ARPHRD_ETHER) 2492 if (awrq->sa_family != ARPHRD_ETHER)
2493 return -EINVAL; 2493 return -EINVAL;
2494 2494
2495 if (!memcmp(any, awrq->sa_data, 6) || 2495 if (!memcmp(any, awrq->sa_data, 6) ||
2496 !memcmp(off, awrq->sa_data, 6)) { 2496 !memcmp(off, awrq->sa_data, 6)) {
2497 del_timer_sync(&priv->management_timer); 2497 del_timer_sync(&priv->management_timer);
2498 spin_lock_irqsave(&priv->irqlock, flags); 2498 spin_lock_irqsave(&priv->irqlock, flags);
2499 atmel_scan(priv, 1); 2499 atmel_scan(priv, 1);
2500 spin_unlock_irqrestore(&priv->irqlock, flags); 2500 spin_unlock_irqrestore(&priv->irqlock, flags);
2501 return 0; 2501 return 0;
2502 } 2502 }
2503 2503
2504 for (i = 0; i < priv->BSS_list_entries; i++) { 2504 for (i = 0; i < priv->BSS_list_entries; i++) {
2505 if (memcmp(priv->BSSinfo[i].BSSID, awrq->sa_data, 6) == 0) { 2505 if (memcmp(priv->BSSinfo[i].BSSID, awrq->sa_data, 6) == 0) {
2506 if (!priv->wep_is_on && priv->BSSinfo[i].UsingWEP) { 2506 if (!priv->wep_is_on && priv->BSSinfo[i].UsingWEP) {
2507 return -EINVAL; 2507 return -EINVAL;
2508 } else if (priv->wep_is_on && !priv->BSSinfo[i].UsingWEP) { 2508 } else if (priv->wep_is_on && !priv->BSSinfo[i].UsingWEP) {
2509 return -EINVAL; 2509 return -EINVAL;
2510 } else { 2510 } else {
2511 del_timer_sync(&priv->management_timer); 2511 del_timer_sync(&priv->management_timer);
2512 spin_lock_irqsave(&priv->irqlock, flags); 2512 spin_lock_irqsave(&priv->irqlock, flags);
2513 atmel_join_bss(priv, i); 2513 atmel_join_bss(priv, i);
2514 spin_unlock_irqrestore(&priv->irqlock, flags); 2514 spin_unlock_irqrestore(&priv->irqlock, flags);
2515 return 0; 2515 return 0;
2516 } 2516 }
2517 } 2517 }
2518 } 2518 }
2519 2519
2520 return -EINVAL; 2520 return -EINVAL;
2521 } 2521 }
2522 2522
2523 static int atmel_config_commit(struct net_device *dev, 2523 static int atmel_config_commit(struct net_device *dev,
2524 struct iw_request_info *info, /* NULL */ 2524 struct iw_request_info *info, /* NULL */
2525 void *zwrq, /* NULL */ 2525 void *zwrq, /* NULL */
2526 char *extra) /* NULL */ 2526 char *extra) /* NULL */
2527 { 2527 {
2528 return atmel_open(dev); 2528 return atmel_open(dev);
2529 } 2529 }
2530 2530
2531 static const iw_handler atmel_handler[] = 2531 static const iw_handler atmel_handler[] =
2532 { 2532 {
2533 (iw_handler) atmel_config_commit, /* SIOCSIWCOMMIT */ 2533 (iw_handler) atmel_config_commit, /* SIOCSIWCOMMIT */
2534 (iw_handler) atmel_get_name, /* SIOCGIWNAME */ 2534 (iw_handler) atmel_get_name, /* SIOCGIWNAME */
2535 (iw_handler) NULL, /* SIOCSIWNWID */ 2535 (iw_handler) NULL, /* SIOCSIWNWID */
2536 (iw_handler) NULL, /* SIOCGIWNWID */ 2536 (iw_handler) NULL, /* SIOCGIWNWID */
2537 (iw_handler) atmel_set_freq, /* SIOCSIWFREQ */ 2537 (iw_handler) atmel_set_freq, /* SIOCSIWFREQ */
2538 (iw_handler) atmel_get_freq, /* SIOCGIWFREQ */ 2538 (iw_handler) atmel_get_freq, /* SIOCGIWFREQ */
2539 (iw_handler) atmel_set_mode, /* SIOCSIWMODE */ 2539 (iw_handler) atmel_set_mode, /* SIOCSIWMODE */
2540 (iw_handler) atmel_get_mode, /* SIOCGIWMODE */ 2540 (iw_handler) atmel_get_mode, /* SIOCGIWMODE */
2541 (iw_handler) NULL, /* SIOCSIWSENS */ 2541 (iw_handler) NULL, /* SIOCSIWSENS */
2542 (iw_handler) NULL, /* SIOCGIWSENS */ 2542 (iw_handler) NULL, /* SIOCGIWSENS */
2543 (iw_handler) NULL, /* SIOCSIWRANGE */ 2543 (iw_handler) NULL, /* SIOCSIWRANGE */
2544 (iw_handler) atmel_get_range, /* SIOCGIWRANGE */ 2544 (iw_handler) atmel_get_range, /* SIOCGIWRANGE */
2545 (iw_handler) NULL, /* SIOCSIWPRIV */ 2545 (iw_handler) NULL, /* SIOCSIWPRIV */
2546 (iw_handler) NULL, /* SIOCGIWPRIV */ 2546 (iw_handler) NULL, /* SIOCGIWPRIV */
2547 (iw_handler) NULL, /* SIOCSIWSTATS */ 2547 (iw_handler) NULL, /* SIOCSIWSTATS */
2548 (iw_handler) NULL, /* SIOCGIWSTATS */ 2548 (iw_handler) NULL, /* SIOCGIWSTATS */
2549 (iw_handler) NULL, /* SIOCSIWSPY */ 2549 (iw_handler) NULL, /* SIOCSIWSPY */
2550 (iw_handler) NULL, /* SIOCGIWSPY */ 2550 (iw_handler) NULL, /* SIOCGIWSPY */
2551 (iw_handler) NULL, /* -- hole -- */ 2551 (iw_handler) NULL, /* -- hole -- */
2552 (iw_handler) NULL, /* -- hole -- */ 2552 (iw_handler) NULL, /* -- hole -- */
2553 (iw_handler) atmel_set_wap, /* SIOCSIWAP */ 2553 (iw_handler) atmel_set_wap, /* SIOCSIWAP */
2554 (iw_handler) atmel_get_wap, /* SIOCGIWAP */ 2554 (iw_handler) atmel_get_wap, /* SIOCGIWAP */
2555 (iw_handler) NULL, /* -- hole -- */ 2555 (iw_handler) NULL, /* -- hole -- */
2556 (iw_handler) NULL, /* SIOCGIWAPLIST */ 2556 (iw_handler) NULL, /* SIOCGIWAPLIST */
2557 (iw_handler) atmel_set_scan, /* SIOCSIWSCAN */ 2557 (iw_handler) atmel_set_scan, /* SIOCSIWSCAN */
2558 (iw_handler) atmel_get_scan, /* SIOCGIWSCAN */ 2558 (iw_handler) atmel_get_scan, /* SIOCGIWSCAN */
2559 (iw_handler) atmel_set_essid, /* SIOCSIWESSID */ 2559 (iw_handler) atmel_set_essid, /* SIOCSIWESSID */
2560 (iw_handler) atmel_get_essid, /* SIOCGIWESSID */ 2560 (iw_handler) atmel_get_essid, /* SIOCGIWESSID */
2561 (iw_handler) NULL, /* SIOCSIWNICKN */ 2561 (iw_handler) NULL, /* SIOCSIWNICKN */
2562 (iw_handler) NULL, /* SIOCGIWNICKN */ 2562 (iw_handler) NULL, /* SIOCGIWNICKN */
2563 (iw_handler) NULL, /* -- hole -- */ 2563 (iw_handler) NULL, /* -- hole -- */
2564 (iw_handler) NULL, /* -- hole -- */ 2564 (iw_handler) NULL, /* -- hole -- */
2565 (iw_handler) atmel_set_rate, /* SIOCSIWRATE */ 2565 (iw_handler) atmel_set_rate, /* SIOCSIWRATE */
2566 (iw_handler) atmel_get_rate, /* SIOCGIWRATE */ 2566 (iw_handler) atmel_get_rate, /* SIOCGIWRATE */
2567 (iw_handler) atmel_set_rts, /* SIOCSIWRTS */ 2567 (iw_handler) atmel_set_rts, /* SIOCSIWRTS */
2568 (iw_handler) atmel_get_rts, /* SIOCGIWRTS */ 2568 (iw_handler) atmel_get_rts, /* SIOCGIWRTS */
2569 (iw_handler) atmel_set_frag, /* SIOCSIWFRAG */ 2569 (iw_handler) atmel_set_frag, /* SIOCSIWFRAG */
2570 (iw_handler) atmel_get_frag, /* SIOCGIWFRAG */ 2570 (iw_handler) atmel_get_frag, /* SIOCGIWFRAG */
2571 (iw_handler) NULL, /* SIOCSIWTXPOW */ 2571 (iw_handler) NULL, /* SIOCSIWTXPOW */
2572 (iw_handler) NULL, /* SIOCGIWTXPOW */ 2572 (iw_handler) NULL, /* SIOCGIWTXPOW */
2573 (iw_handler) atmel_set_retry, /* SIOCSIWRETRY */ 2573 (iw_handler) atmel_set_retry, /* SIOCSIWRETRY */
2574 (iw_handler) atmel_get_retry, /* SIOCGIWRETRY */ 2574 (iw_handler) atmel_get_retry, /* SIOCGIWRETRY */
2575 (iw_handler) atmel_set_encode, /* SIOCSIWENCODE */ 2575 (iw_handler) atmel_set_encode, /* SIOCSIWENCODE */
2576 (iw_handler) atmel_get_encode, /* SIOCGIWENCODE */ 2576 (iw_handler) atmel_get_encode, /* SIOCGIWENCODE */
2577 (iw_handler) atmel_set_power, /* SIOCSIWPOWER */ 2577 (iw_handler) atmel_set_power, /* SIOCSIWPOWER */
2578 (iw_handler) atmel_get_power, /* SIOCGIWPOWER */ 2578 (iw_handler) atmel_get_power, /* SIOCGIWPOWER */
2579 (iw_handler) NULL, /* -- hole -- */ 2579 (iw_handler) NULL, /* -- hole -- */
2580 (iw_handler) NULL, /* -- hole -- */ 2580 (iw_handler) NULL, /* -- hole -- */
2581 (iw_handler) NULL, /* SIOCSIWGENIE */ 2581 (iw_handler) NULL, /* SIOCSIWGENIE */
2582 (iw_handler) NULL, /* SIOCGIWGENIE */ 2582 (iw_handler) NULL, /* SIOCGIWGENIE */
2583 (iw_handler) atmel_set_auth, /* SIOCSIWAUTH */ 2583 (iw_handler) atmel_set_auth, /* SIOCSIWAUTH */
2584 (iw_handler) atmel_get_auth, /* SIOCGIWAUTH */ 2584 (iw_handler) atmel_get_auth, /* SIOCGIWAUTH */
2585 (iw_handler) atmel_set_encodeext, /* SIOCSIWENCODEEXT */ 2585 (iw_handler) atmel_set_encodeext, /* SIOCSIWENCODEEXT */
2586 (iw_handler) atmel_get_encodeext, /* SIOCGIWENCODEEXT */ 2586 (iw_handler) atmel_get_encodeext, /* SIOCGIWENCODEEXT */
2587 (iw_handler) NULL, /* SIOCSIWPMKSA */ 2587 (iw_handler) NULL, /* SIOCSIWPMKSA */
2588 }; 2588 };
2589 2589
2590 static const iw_handler atmel_private_handler[] = 2590 static const iw_handler atmel_private_handler[] =
2591 { 2591 {
2592 NULL, /* SIOCIWFIRSTPRIV */ 2592 NULL, /* SIOCIWFIRSTPRIV */
2593 }; 2593 };
2594 2594
2595 typedef struct atmel_priv_ioctl { 2595 typedef struct atmel_priv_ioctl {
2596 char id[32]; 2596 char id[32];
2597 unsigned char __user *data; 2597 unsigned char __user *data;
2598 unsigned short len; 2598 unsigned short len;
2599 } atmel_priv_ioctl; 2599 } atmel_priv_ioctl;
2600 2600
2601 #define ATMELFWL SIOCIWFIRSTPRIV 2601 #define ATMELFWL SIOCIWFIRSTPRIV
2602 #define ATMELIDIFC ATMELFWL + 1 2602 #define ATMELIDIFC ATMELFWL + 1
2603 #define ATMELRD ATMELFWL + 2 2603 #define ATMELRD ATMELFWL + 2
2604 #define ATMELMAGIC 0x51807 2604 #define ATMELMAGIC 0x51807
2605 #define REGDOMAINSZ 20 2605 #define REGDOMAINSZ 20
2606 2606
2607 static const struct iw_priv_args atmel_private_args[] = { 2607 static const struct iw_priv_args atmel_private_args[] = {
2608 { 2608 {
2609 .cmd = ATMELFWL, 2609 .cmd = ATMELFWL,
2610 .set_args = IW_PRIV_TYPE_BYTE 2610 .set_args = IW_PRIV_TYPE_BYTE
2611 | IW_PRIV_SIZE_FIXED 2611 | IW_PRIV_SIZE_FIXED
2612 | sizeof (atmel_priv_ioctl), 2612 | sizeof (atmel_priv_ioctl),
2613 .get_args = IW_PRIV_TYPE_NONE, 2613 .get_args = IW_PRIV_TYPE_NONE,
2614 .name = "atmelfwl" 2614 .name = "atmelfwl"
2615 }, { 2615 }, {
2616 .cmd = ATMELIDIFC, 2616 .cmd = ATMELIDIFC,
2617 .set_args = IW_PRIV_TYPE_NONE, 2617 .set_args = IW_PRIV_TYPE_NONE,
2618 .get_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 2618 .get_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
2619 .name = "atmelidifc" 2619 .name = "atmelidifc"
2620 }, { 2620 }, {
2621 .cmd = ATMELRD, 2621 .cmd = ATMELRD,
2622 .set_args = IW_PRIV_TYPE_CHAR | REGDOMAINSZ, 2622 .set_args = IW_PRIV_TYPE_CHAR | REGDOMAINSZ,
2623 .get_args = IW_PRIV_TYPE_NONE, 2623 .get_args = IW_PRIV_TYPE_NONE,
2624 .name = "regdomain" 2624 .name = "regdomain"
2625 }, 2625 },
2626 }; 2626 };
2627 2627
2628 static const struct iw_handler_def atmel_handler_def = { 2628 static const struct iw_handler_def atmel_handler_def = {
2629 .num_standard = ARRAY_SIZE(atmel_handler), 2629 .num_standard = ARRAY_SIZE(atmel_handler),
2630 .num_private = ARRAY_SIZE(atmel_private_handler), 2630 .num_private = ARRAY_SIZE(atmel_private_handler),
2631 .num_private_args = ARRAY_SIZE(atmel_private_args), 2631 .num_private_args = ARRAY_SIZE(atmel_private_args),
2632 .standard = (iw_handler *) atmel_handler, 2632 .standard = (iw_handler *) atmel_handler,
2633 .private = (iw_handler *) atmel_private_handler, 2633 .private = (iw_handler *) atmel_private_handler,
2634 .private_args = (struct iw_priv_args *) atmel_private_args, 2634 .private_args = (struct iw_priv_args *) atmel_private_args,
2635 .get_wireless_stats = atmel_get_wireless_stats 2635 .get_wireless_stats = atmel_get_wireless_stats
2636 }; 2636 };
2637 2637
2638 static int atmel_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) 2638 static int atmel_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
2639 { 2639 {
2640 int i, rc = 0; 2640 int i, rc = 0;
2641 struct atmel_private *priv = netdev_priv(dev); 2641 struct atmel_private *priv = netdev_priv(dev);
2642 atmel_priv_ioctl com; 2642 atmel_priv_ioctl com;
2643 struct iwreq *wrq = (struct iwreq *) rq; 2643 struct iwreq *wrq = (struct iwreq *) rq;
2644 unsigned char *new_firmware; 2644 unsigned char *new_firmware;
2645 char domain[REGDOMAINSZ + 1]; 2645 char domain[REGDOMAINSZ + 1];
2646 2646
2647 switch (cmd) { 2647 switch (cmd) {
2648 case ATMELIDIFC: 2648 case ATMELIDIFC:
2649 wrq->u.param.value = ATMELMAGIC; 2649 wrq->u.param.value = ATMELMAGIC;
2650 break; 2650 break;
2651 2651
2652 case ATMELFWL: 2652 case ATMELFWL:
2653 if (copy_from_user(&com, rq->ifr_data, sizeof(com))) { 2653 if (copy_from_user(&com, rq->ifr_data, sizeof(com))) {
2654 rc = -EFAULT; 2654 rc = -EFAULT;
2655 break; 2655 break;
2656 } 2656 }
2657 2657
2658 if (!capable(CAP_NET_ADMIN)) { 2658 if (!capable(CAP_NET_ADMIN)) {
2659 rc = -EPERM; 2659 rc = -EPERM;
2660 break; 2660 break;
2661 } 2661 }
2662 2662
2663 if (!(new_firmware = kmalloc(com.len, GFP_KERNEL))) { 2663 if (!(new_firmware = kmalloc(com.len, GFP_KERNEL))) {
2664 rc = -ENOMEM; 2664 rc = -ENOMEM;
2665 break; 2665 break;
2666 } 2666 }
2667 2667
2668 if (copy_from_user(new_firmware, com.data, com.len)) { 2668 if (copy_from_user(new_firmware, com.data, com.len)) {
2669 kfree(new_firmware); 2669 kfree(new_firmware);
2670 rc = -EFAULT; 2670 rc = -EFAULT;
2671 break; 2671 break;
2672 } 2672 }
2673 2673
2674 kfree(priv->firmware); 2674 kfree(priv->firmware);
2675 2675
2676 priv->firmware = new_firmware; 2676 priv->firmware = new_firmware;
2677 priv->firmware_length = com.len; 2677 priv->firmware_length = com.len;
2678 strncpy(priv->firmware_id, com.id, 31); 2678 strncpy(priv->firmware_id, com.id, 31);
2679 priv->firmware_id[31] = '\0'; 2679 priv->firmware_id[31] = '\0';
2680 break; 2680 break;
2681 2681
2682 case ATMELRD: 2682 case ATMELRD:
2683 if (copy_from_user(domain, rq->ifr_data, REGDOMAINSZ)) { 2683 if (copy_from_user(domain, rq->ifr_data, REGDOMAINSZ)) {
2684 rc = -EFAULT; 2684 rc = -EFAULT;
2685 break; 2685 break;
2686 } 2686 }
2687 2687
2688 if (!capable(CAP_NET_ADMIN)) { 2688 if (!capable(CAP_NET_ADMIN)) {
2689 rc = -EPERM; 2689 rc = -EPERM;
2690 break; 2690 break;
2691 } 2691 }
2692 2692
2693 domain[REGDOMAINSZ] = 0; 2693 domain[REGDOMAINSZ] = 0;
2694 rc = -EINVAL; 2694 rc = -EINVAL;
2695 for (i = 0; i < ARRAY_SIZE(channel_table); i++) { 2695 for (i = 0; i < ARRAY_SIZE(channel_table); i++) {
2696 /* strcasecmp doesn't exist in the library */ 2696 /* strcasecmp doesn't exist in the library */
2697 char *a = channel_table[i].name; 2697 char *a = channel_table[i].name;
2698 char *b = domain; 2698 char *b = domain;
2699 while (*a) { 2699 while (*a) {
2700 char c1 = *a++; 2700 char c1 = *a++;
2701 char c2 = *b++; 2701 char c2 = *b++;
2702 if (tolower(c1) != tolower(c2)) 2702 if (tolower(c1) != tolower(c2))
2703 break; 2703 break;
2704 } 2704 }
2705 if (!*a && !*b) { 2705 if (!*a && !*b) {
2706 priv->config_reg_domain = channel_table[i].reg_domain; 2706 priv->config_reg_domain = channel_table[i].reg_domain;
2707 rc = 0; 2707 rc = 0;
2708 } 2708 }
2709 } 2709 }
2710 2710
2711 if (rc == 0 && priv->station_state != STATION_STATE_DOWN) 2711 if (rc == 0 && priv->station_state != STATION_STATE_DOWN)
2712 rc = atmel_open(dev); 2712 rc = atmel_open(dev);
2713 break; 2713 break;
2714 2714
2715 default: 2715 default:
2716 rc = -EOPNOTSUPP; 2716 rc = -EOPNOTSUPP;
2717 } 2717 }
2718 2718
2719 return rc; 2719 return rc;
2720 } 2720 }
2721 2721
2722 struct auth_body { 2722 struct auth_body {
2723 __le16 alg; 2723 __le16 alg;
2724 __le16 trans_seq; 2724 __le16 trans_seq;
2725 __le16 status; 2725 __le16 status;
2726 u8 el_id; 2726 u8 el_id;
2727 u8 chall_text_len; 2727 u8 chall_text_len;
2728 u8 chall_text[253]; 2728 u8 chall_text[253];
2729 }; 2729 };
2730 2730
2731 static void atmel_enter_state(struct atmel_private *priv, int new_state) 2731 static void atmel_enter_state(struct atmel_private *priv, int new_state)
2732 { 2732 {
2733 int old_state = priv->station_state; 2733 int old_state = priv->station_state;
2734 2734
2735 if (new_state == old_state) 2735 if (new_state == old_state)
2736 return; 2736 return;
2737 2737
2738 priv->station_state = new_state; 2738 priv->station_state = new_state;
2739 2739
2740 if (new_state == STATION_STATE_READY) { 2740 if (new_state == STATION_STATE_READY) {
2741 netif_start_queue(priv->dev); 2741 netif_start_queue(priv->dev);
2742 netif_carrier_on(priv->dev); 2742 netif_carrier_on(priv->dev);
2743 } 2743 }
2744 2744
2745 if (old_state == STATION_STATE_READY) { 2745 if (old_state == STATION_STATE_READY) {
2746 netif_carrier_off(priv->dev); 2746 netif_carrier_off(priv->dev);
2747 if (netif_running(priv->dev)) 2747 if (netif_running(priv->dev))
2748 netif_stop_queue(priv->dev); 2748 netif_stop_queue(priv->dev);
2749 priv->last_beacon_timestamp = 0; 2749 priv->last_beacon_timestamp = 0;
2750 } 2750 }
2751 } 2751 }
2752 2752
2753 static void atmel_scan(struct atmel_private *priv, int specific_ssid) 2753 static void atmel_scan(struct atmel_private *priv, int specific_ssid)
2754 { 2754 {
2755 struct { 2755 struct {
2756 u8 BSSID[6]; 2756 u8 BSSID[6];
2757 u8 SSID[MAX_SSID_LENGTH]; 2757 u8 SSID[MAX_SSID_LENGTH];
2758 u8 scan_type; 2758 u8 scan_type;
2759 u8 channel; 2759 u8 channel;
2760 __le16 BSS_type; 2760 __le16 BSS_type;
2761 __le16 min_channel_time; 2761 __le16 min_channel_time;
2762 __le16 max_channel_time; 2762 __le16 max_channel_time;
2763 u8 options; 2763 u8 options;
2764 u8 SSID_size; 2764 u8 SSID_size;
2765 } cmd; 2765 } cmd;
2766 2766
2767 memset(cmd.BSSID, 0xff, 6); 2767 memset(cmd.BSSID, 0xff, 6);
2768 2768
2769 if (priv->fast_scan) { 2769 if (priv->fast_scan) {
2770 cmd.SSID_size = priv->SSID_size; 2770 cmd.SSID_size = priv->SSID_size;
2771 memcpy(cmd.SSID, priv->SSID, priv->SSID_size); 2771 memcpy(cmd.SSID, priv->SSID, priv->SSID_size);
2772 cmd.min_channel_time = cpu_to_le16(10); 2772 cmd.min_channel_time = cpu_to_le16(10);
2773 cmd.max_channel_time = cpu_to_le16(50); 2773 cmd.max_channel_time = cpu_to_le16(50);
2774 } else { 2774 } else {
2775 priv->BSS_list_entries = 0; 2775 priv->BSS_list_entries = 0;
2776 cmd.SSID_size = 0; 2776 cmd.SSID_size = 0;
2777 cmd.min_channel_time = cpu_to_le16(10); 2777 cmd.min_channel_time = cpu_to_le16(10);
2778 cmd.max_channel_time = cpu_to_le16(120); 2778 cmd.max_channel_time = cpu_to_le16(120);
2779 } 2779 }
2780 2780
2781 cmd.options = 0; 2781 cmd.options = 0;
2782 2782
2783 if (!specific_ssid) 2783 if (!specific_ssid)
2784 cmd.options |= SCAN_OPTIONS_SITE_SURVEY; 2784 cmd.options |= SCAN_OPTIONS_SITE_SURVEY;
2785 2785
2786 cmd.channel = (priv->channel & 0x7f); 2786 cmd.channel = (priv->channel & 0x7f);
2787 cmd.scan_type = SCAN_TYPE_ACTIVE; 2787 cmd.scan_type = SCAN_TYPE_ACTIVE;
2788 cmd.BSS_type = cpu_to_le16(priv->operating_mode == IW_MODE_ADHOC ? 2788 cmd.BSS_type = cpu_to_le16(priv->operating_mode == IW_MODE_ADHOC ?
2789 BSS_TYPE_AD_HOC : BSS_TYPE_INFRASTRUCTURE); 2789 BSS_TYPE_AD_HOC : BSS_TYPE_INFRASTRUCTURE);
2790 2790
2791 atmel_send_command(priv, CMD_Scan, &cmd, sizeof(cmd)); 2791 atmel_send_command(priv, CMD_Scan, &cmd, sizeof(cmd));
2792 2792
2793 /* This must come after all hardware access to avoid being messed up 2793 /* This must come after all hardware access to avoid being messed up
2794 by stuff happening in interrupt context after we leave STATE_DOWN */ 2794 by stuff happening in interrupt context after we leave STATE_DOWN */
2795 atmel_enter_state(priv, STATION_STATE_SCANNING); 2795 atmel_enter_state(priv, STATION_STATE_SCANNING);
2796 } 2796 }
2797 2797
2798 static void join(struct atmel_private *priv, int type) 2798 static void join(struct atmel_private *priv, int type)
2799 { 2799 {
2800 struct { 2800 struct {
2801 u8 BSSID[6]; 2801 u8 BSSID[6];
2802 u8 SSID[MAX_SSID_LENGTH]; 2802 u8 SSID[MAX_SSID_LENGTH];
2803 u8 BSS_type; /* this is a short in a scan command - weird */ 2803 u8 BSS_type; /* this is a short in a scan command - weird */
2804 u8 channel; 2804 u8 channel;
2805 __le16 timeout; 2805 __le16 timeout;
2806 u8 SSID_size; 2806 u8 SSID_size;
2807 u8 reserved; 2807 u8 reserved;
2808 } cmd; 2808 } cmd;
2809 2809
2810 cmd.SSID_size = priv->SSID_size; 2810 cmd.SSID_size = priv->SSID_size;
2811 memcpy(cmd.SSID, priv->SSID, priv->SSID_size); 2811 memcpy(cmd.SSID, priv->SSID, priv->SSID_size);
2812 memcpy(cmd.BSSID, priv->CurrentBSSID, 6); 2812 memcpy(cmd.BSSID, priv->CurrentBSSID, 6);
2813 cmd.channel = (priv->channel & 0x7f); 2813 cmd.channel = (priv->channel & 0x7f);
2814 cmd.BSS_type = type; 2814 cmd.BSS_type = type;
2815 cmd.timeout = cpu_to_le16(2000); 2815 cmd.timeout = cpu_to_le16(2000);
2816 2816
2817 atmel_send_command(priv, CMD_Join, &cmd, sizeof(cmd)); 2817 atmel_send_command(priv, CMD_Join, &cmd, sizeof(cmd));
2818 } 2818 }
2819 2819
2820 static void start(struct atmel_private *priv, int type) 2820 static void start(struct atmel_private *priv, int type)
2821 { 2821 {
2822 struct { 2822 struct {
2823 u8 BSSID[6]; 2823 u8 BSSID[6];
2824 u8 SSID[MAX_SSID_LENGTH]; 2824 u8 SSID[MAX_SSID_LENGTH];
2825 u8 BSS_type; 2825 u8 BSS_type;
2826 u8 channel; 2826 u8 channel;
2827 u8 SSID_size; 2827 u8 SSID_size;
2828 u8 reserved[3]; 2828 u8 reserved[3];
2829 } cmd; 2829 } cmd;
2830 2830
2831 cmd.SSID_size = priv->SSID_size; 2831 cmd.SSID_size = priv->SSID_size;
2832 memcpy(cmd.SSID, priv->SSID, priv->SSID_size); 2832 memcpy(cmd.SSID, priv->SSID, priv->SSID_size);
2833 memcpy(cmd.BSSID, priv->BSSID, 6); 2833 memcpy(cmd.BSSID, priv->BSSID, 6);
2834 cmd.BSS_type = type; 2834 cmd.BSS_type = type;
2835 cmd.channel = (priv->channel & 0x7f); 2835 cmd.channel = (priv->channel & 0x7f);
2836 2836
2837 atmel_send_command(priv, CMD_Start, &cmd, sizeof(cmd)); 2837 atmel_send_command(priv, CMD_Start, &cmd, sizeof(cmd));
2838 } 2838 }
2839 2839
2840 static void handle_beacon_probe(struct atmel_private *priv, u16 capability, 2840 static void handle_beacon_probe(struct atmel_private *priv, u16 capability,
2841 u8 channel) 2841 u8 channel)
2842 { 2842 {
2843 int rejoin = 0; 2843 int rejoin = 0;
2844 int new = capability & WLAN_CAPABILITY_SHORT_PREAMBLE ? 2844 int new = capability & WLAN_CAPABILITY_SHORT_PREAMBLE ?
2845 SHORT_PREAMBLE : LONG_PREAMBLE; 2845 SHORT_PREAMBLE : LONG_PREAMBLE;
2846 2846
2847 if (priv->preamble != new) { 2847 if (priv->preamble != new) {
2848 priv->preamble = new; 2848 priv->preamble = new;
2849 rejoin = 1; 2849 rejoin = 1;
2850 atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_PREAMBLE_TYPE, new); 2850 atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_PREAMBLE_TYPE, new);
2851 } 2851 }
2852 2852
2853 if (priv->channel != channel) { 2853 if (priv->channel != channel) {
2854 priv->channel = channel; 2854 priv->channel = channel;
2855 rejoin = 1; 2855 rejoin = 1;
2856 atmel_set_mib8(priv, Phy_Mib_Type, PHY_MIB_CHANNEL_POS, channel); 2856 atmel_set_mib8(priv, Phy_Mib_Type, PHY_MIB_CHANNEL_POS, channel);
2857 } 2857 }
2858 2858
2859 if (rejoin) { 2859 if (rejoin) {
2860 priv->station_is_associated = 0; 2860 priv->station_is_associated = 0;
2861 atmel_enter_state(priv, STATION_STATE_JOINNING); 2861 atmel_enter_state(priv, STATION_STATE_JOINNING);
2862 2862
2863 if (priv->operating_mode == IW_MODE_INFRA) 2863 if (priv->operating_mode == IW_MODE_INFRA)
2864 join(priv, BSS_TYPE_INFRASTRUCTURE); 2864 join(priv, BSS_TYPE_INFRASTRUCTURE);
2865 else 2865 else
2866 join(priv, BSS_TYPE_AD_HOC); 2866 join(priv, BSS_TYPE_AD_HOC);
2867 } 2867 }
2868 } 2868 }
2869 2869
2870 static void send_authentication_request(struct atmel_private *priv, u16 system, 2870 static void send_authentication_request(struct atmel_private *priv, u16 system,
2871 u8 *challenge, int challenge_len) 2871 u8 *challenge, int challenge_len)
2872 { 2872 {
2873 struct ieee80211_hdr header; 2873 struct ieee80211_hdr header;
2874 struct auth_body auth; 2874 struct auth_body auth;
2875 2875
2876 header.frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH); 2876 header.frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH);
2877 header.duration_id = cpu_to_le16(0x8000); 2877 header.duration_id = cpu_to_le16(0x8000);
2878 header.seq_ctrl = 0; 2878 header.seq_ctrl = 0;
2879 memcpy(header.addr1, priv->CurrentBSSID, 6); 2879 memcpy(header.addr1, priv->CurrentBSSID, 6);
2880 memcpy(header.addr2, priv->dev->dev_addr, 6); 2880 memcpy(header.addr2, priv->dev->dev_addr, 6);
2881 memcpy(header.addr3, priv->CurrentBSSID, 6); 2881 memcpy(header.addr3, priv->CurrentBSSID, 6);
2882 2882
2883 if (priv->wep_is_on && priv->CurrentAuthentTransactionSeqNum != 1) 2883 if (priv->wep_is_on && priv->CurrentAuthentTransactionSeqNum != 1)
2884 /* no WEP for authentication frames with TrSeqNo 1 */ 2884 /* no WEP for authentication frames with TrSeqNo 1 */
2885 header.frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); 2885 header.frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
2886 2886
2887 auth.alg = cpu_to_le16(system); 2887 auth.alg = cpu_to_le16(system);
2888 2888
2889 auth.status = 0; 2889 auth.status = 0;
2890 auth.trans_seq = cpu_to_le16(priv->CurrentAuthentTransactionSeqNum); 2890 auth.trans_seq = cpu_to_le16(priv->CurrentAuthentTransactionSeqNum);
2891 priv->ExpectedAuthentTransactionSeqNum = priv->CurrentAuthentTransactionSeqNum+1; 2891 priv->ExpectedAuthentTransactionSeqNum = priv->CurrentAuthentTransactionSeqNum+1;
2892 priv->CurrentAuthentTransactionSeqNum += 2; 2892 priv->CurrentAuthentTransactionSeqNum += 2;
2893 2893
2894 if (challenge_len != 0) { 2894 if (challenge_len != 0) {
2895 auth.el_id = 16; /* challenge_text */ 2895 auth.el_id = 16; /* challenge_text */
2896 auth.chall_text_len = challenge_len; 2896 auth.chall_text_len = challenge_len;
2897 memcpy(auth.chall_text, challenge, challenge_len); 2897 memcpy(auth.chall_text, challenge, challenge_len);
2898 atmel_transmit_management_frame(priv, &header, (u8 *)&auth, 8 + challenge_len); 2898 atmel_transmit_management_frame(priv, &header, (u8 *)&auth, 8 + challenge_len);
2899 } else { 2899 } else {
2900 atmel_transmit_management_frame(priv, &header, (u8 *)&auth, 6); 2900 atmel_transmit_management_frame(priv, &header, (u8 *)&auth, 6);
2901 } 2901 }
2902 } 2902 }
2903 2903
2904 static void send_association_request(struct atmel_private *priv, int is_reassoc) 2904 static void send_association_request(struct atmel_private *priv, int is_reassoc)
2905 { 2905 {
2906 u8 *ssid_el_p; 2906 u8 *ssid_el_p;
2907 int bodysize; 2907 int bodysize;
2908 struct ieee80211_hdr header; 2908 struct ieee80211_hdr header;
2909 struct ass_req_format { 2909 struct ass_req_format {
2910 __le16 capability; 2910 __le16 capability;
2911 __le16 listen_interval; 2911 __le16 listen_interval;
2912 u8 ap[6]; /* nothing after here directly accessible */ 2912 u8 ap[6]; /* nothing after here directly accessible */
2913 u8 ssid_el_id; 2913 u8 ssid_el_id;
2914 u8 ssid_len; 2914 u8 ssid_len;
2915 u8 ssid[MAX_SSID_LENGTH]; 2915 u8 ssid[MAX_SSID_LENGTH];
2916 u8 sup_rates_el_id; 2916 u8 sup_rates_el_id;
2917 u8 sup_rates_len; 2917 u8 sup_rates_len;
2918 u8 rates[4]; 2918 u8 rates[4];
2919 } body; 2919 } body;
2920 2920
2921 header.frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 2921 header.frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
2922 (is_reassoc ? IEEE80211_STYPE_REASSOC_REQ : IEEE80211_STYPE_ASSOC_REQ)); 2922 (is_reassoc ? IEEE80211_STYPE_REASSOC_REQ : IEEE80211_STYPE_ASSOC_REQ));
2923 header.duration_id = cpu_to_le16(0x8000); 2923 header.duration_id = cpu_to_le16(0x8000);
2924 header.seq_ctrl = 0; 2924 header.seq_ctrl = 0;
2925 2925
2926 memcpy(header.addr1, priv->CurrentBSSID, 6); 2926 memcpy(header.addr1, priv->CurrentBSSID, 6);
2927 memcpy(header.addr2, priv->dev->dev_addr, 6); 2927 memcpy(header.addr2, priv->dev->dev_addr, 6);
2928 memcpy(header.addr3, priv->CurrentBSSID, 6); 2928 memcpy(header.addr3, priv->CurrentBSSID, 6);
2929 2929
2930 body.capability = cpu_to_le16(WLAN_CAPABILITY_ESS); 2930 body.capability = cpu_to_le16(WLAN_CAPABILITY_ESS);
2931 if (priv->wep_is_on) 2931 if (priv->wep_is_on)
2932 body.capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY); 2932 body.capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
2933 if (priv->preamble == SHORT_PREAMBLE) 2933 if (priv->preamble == SHORT_PREAMBLE)
2934 body.capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE); 2934 body.capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE);
2935 2935
2936 body.listen_interval = cpu_to_le16(priv->listen_interval * priv->beacon_period); 2936 body.listen_interval = cpu_to_le16(priv->listen_interval * priv->beacon_period);
2937 2937
2938 /* current AP address - only in reassoc frame */ 2938 /* current AP address - only in reassoc frame */
2939 if (is_reassoc) { 2939 if (is_reassoc) {
2940 memcpy(body.ap, priv->CurrentBSSID, 6); 2940 memcpy(body.ap, priv->CurrentBSSID, 6);
2941 ssid_el_p = (u8 *)&body.ssid_el_id; 2941 ssid_el_p = (u8 *)&body.ssid_el_id;
2942 bodysize = 18 + priv->SSID_size; 2942 bodysize = 18 + priv->SSID_size;
2943 } else { 2943 } else {
2944 ssid_el_p = (u8 *)&body.ap[0]; 2944 ssid_el_p = (u8 *)&body.ap[0];
2945 bodysize = 12 + priv->SSID_size; 2945 bodysize = 12 + priv->SSID_size;
2946 } 2946 }
2947 2947
2948 ssid_el_p[0] = WLAN_EID_SSID; 2948 ssid_el_p[0] = WLAN_EID_SSID;
2949 ssid_el_p[1] = priv->SSID_size; 2949 ssid_el_p[1] = priv->SSID_size;
2950 memcpy(ssid_el_p + 2, priv->SSID, priv->SSID_size); 2950 memcpy(ssid_el_p + 2, priv->SSID, priv->SSID_size);
2951 ssid_el_p[2 + priv->SSID_size] = WLAN_EID_SUPP_RATES; 2951 ssid_el_p[2 + priv->SSID_size] = WLAN_EID_SUPP_RATES;
2952 ssid_el_p[3 + priv->SSID_size] = 4; /* len of suported rates */ 2952 ssid_el_p[3 + priv->SSID_size] = 4; /* len of suported rates */
2953 memcpy(ssid_el_p + 4 + priv->SSID_size, atmel_basic_rates, 4); 2953 memcpy(ssid_el_p + 4 + priv->SSID_size, atmel_basic_rates, 4);
2954 2954
2955 atmel_transmit_management_frame(priv, &header, (void *)&body, bodysize); 2955 atmel_transmit_management_frame(priv, &header, (void *)&body, bodysize);
2956 } 2956 }
2957 2957
2958 static int is_frame_from_current_bss(struct atmel_private *priv, 2958 static int is_frame_from_current_bss(struct atmel_private *priv,
2959 struct ieee80211_hdr *header) 2959 struct ieee80211_hdr *header)
2960 { 2960 {
2961 if (le16_to_cpu(header->frame_control) & IEEE80211_FCTL_FROMDS) 2961 if (le16_to_cpu(header->frame_control) & IEEE80211_FCTL_FROMDS)
2962 return memcmp(header->addr3, priv->CurrentBSSID, 6) == 0; 2962 return memcmp(header->addr3, priv->CurrentBSSID, 6) == 0;
2963 else 2963 else
2964 return memcmp(header->addr2, priv->CurrentBSSID, 6) == 0; 2964 return memcmp(header->addr2, priv->CurrentBSSID, 6) == 0;
2965 } 2965 }
2966 2966
2967 static int retrieve_bss(struct atmel_private *priv) 2967 static int retrieve_bss(struct atmel_private *priv)
2968 { 2968 {
2969 int i; 2969 int i;
2970 int max_rssi = -128; 2970 int max_rssi = -128;
2971 int max_index = -1; 2971 int max_index = -1;
2972 2972
2973 if (priv->BSS_list_entries == 0) 2973 if (priv->BSS_list_entries == 0)
2974 return -1; 2974 return -1;
2975 2975
2976 if (priv->connect_to_any_BSS) { 2976 if (priv->connect_to_any_BSS) {
2977 /* Select a BSS with the max-RSSI but of the same type and of 2977 /* Select a BSS with the max-RSSI but of the same type and of
2978 the same WEP mode and that it is not marked as 'bad' (i.e. 2978 the same WEP mode and that it is not marked as 'bad' (i.e.
2979 we had previously failed to connect to this BSS with the 2979 we had previously failed to connect to this BSS with the
2980 settings that we currently use) */ 2980 settings that we currently use) */
2981 priv->current_BSS = 0; 2981 priv->current_BSS = 0;
2982 for (i = 0; i < priv->BSS_list_entries; i++) { 2982 for (i = 0; i < priv->BSS_list_entries; i++) {
2983 if (priv->operating_mode == priv->BSSinfo[i].BSStype && 2983 if (priv->operating_mode == priv->BSSinfo[i].BSStype &&
2984 ((!priv->wep_is_on && !priv->BSSinfo[i].UsingWEP) || 2984 ((!priv->wep_is_on && !priv->BSSinfo[i].UsingWEP) ||
2985 (priv->wep_is_on && priv->BSSinfo[i].UsingWEP)) && 2985 (priv->wep_is_on && priv->BSSinfo[i].UsingWEP)) &&
2986 !(priv->BSSinfo[i].channel & 0x80)) { 2986 !(priv->BSSinfo[i].channel & 0x80)) {
2987 max_rssi = priv->BSSinfo[i].RSSI; 2987 max_rssi = priv->BSSinfo[i].RSSI;
2988 priv->current_BSS = max_index = i; 2988 priv->current_BSS = max_index = i;
2989 } 2989 }
2990 } 2990 }
2991 return max_index; 2991 return max_index;
2992 } 2992 }
2993 2993
2994 for (i = 0; i < priv->BSS_list_entries; i++) { 2994 for (i = 0; i < priv->BSS_list_entries; i++) {
2995 if (priv->SSID_size == priv->BSSinfo[i].SSIDsize && 2995 if (priv->SSID_size == priv->BSSinfo[i].SSIDsize &&
2996 memcmp(priv->SSID, priv->BSSinfo[i].SSID, priv->SSID_size) == 0 && 2996 memcmp(priv->SSID, priv->BSSinfo[i].SSID, priv->SSID_size) == 0 &&
2997 priv->operating_mode == priv->BSSinfo[i].BSStype && 2997 priv->operating_mode == priv->BSSinfo[i].BSStype &&
2998 atmel_validate_channel(priv, priv->BSSinfo[i].channel) == 0) { 2998 atmel_validate_channel(priv, priv->BSSinfo[i].channel) == 0) {
2999 if (priv->BSSinfo[i].RSSI >= max_rssi) { 2999 if (priv->BSSinfo[i].RSSI >= max_rssi) {
3000 max_rssi = priv->BSSinfo[i].RSSI; 3000 max_rssi = priv->BSSinfo[i].RSSI;
3001 max_index = i; 3001 max_index = i;
3002 } 3002 }
3003 } 3003 }
3004 } 3004 }
3005 return max_index; 3005 return max_index;
3006 } 3006 }
3007 3007
3008 static void store_bss_info(struct atmel_private *priv, 3008 static void store_bss_info(struct atmel_private *priv,
3009 struct ieee80211_hdr *header, u16 capability, 3009 struct ieee80211_hdr *header, u16 capability,
3010 u16 beacon_period, u8 channel, u8 rssi, u8 ssid_len, 3010 u16 beacon_period, u8 channel, u8 rssi, u8 ssid_len,
3011 u8 *ssid, int is_beacon) 3011 u8 *ssid, int is_beacon)
3012 { 3012 {
3013 u8 *bss = capability & WLAN_CAPABILITY_ESS ? header->addr2 : header->addr3; 3013 u8 *bss = capability & WLAN_CAPABILITY_ESS ? header->addr2 : header->addr3;
3014 int i, index; 3014 int i, index;
3015 3015
3016 for (index = -1, i = 0; i < priv->BSS_list_entries; i++) 3016 for (index = -1, i = 0; i < priv->BSS_list_entries; i++)
3017 if (memcmp(bss, priv->BSSinfo[i].BSSID, 6) == 0) 3017 if (memcmp(bss, priv->BSSinfo[i].BSSID, 6) == 0)
3018 index = i; 3018 index = i;
3019 3019
3020 /* If we process a probe and an entry from this BSS exists 3020 /* If we process a probe and an entry from this BSS exists
3021 we will update the BSS entry with the info from this BSS. 3021 we will update the BSS entry with the info from this BSS.
3022 If we process a beacon we will only update RSSI */ 3022 If we process a beacon we will only update RSSI */
3023 3023
3024 if (index == -1) { 3024 if (index == -1) {
3025 if (priv->BSS_list_entries == MAX_BSS_ENTRIES) 3025 if (priv->BSS_list_entries == MAX_BSS_ENTRIES)
3026 return; 3026 return;
3027 index = priv->BSS_list_entries++; 3027 index = priv->BSS_list_entries++;
3028 memcpy(priv->BSSinfo[index].BSSID, bss, 6); 3028 memcpy(priv->BSSinfo[index].BSSID, bss, 6);
3029 priv->BSSinfo[index].RSSI = rssi; 3029 priv->BSSinfo[index].RSSI = rssi;
3030 } else { 3030 } else {
3031 if (rssi > priv->BSSinfo[index].RSSI) 3031 if (rssi > priv->BSSinfo[index].RSSI)
3032 priv->BSSinfo[index].RSSI = rssi; 3032 priv->BSSinfo[index].RSSI = rssi;
3033 if (is_beacon) 3033 if (is_beacon)
3034 return; 3034 return;
3035 } 3035 }
3036 3036
3037 priv->BSSinfo[index].channel = channel; 3037 priv->BSSinfo[index].channel = channel;
3038 priv->BSSinfo[index].beacon_period = beacon_period; 3038 priv->BSSinfo[index].beacon_period = beacon_period;
3039 priv->BSSinfo[index].UsingWEP = capability & WLAN_CAPABILITY_PRIVACY; 3039 priv->BSSinfo[index].UsingWEP = capability & WLAN_CAPABILITY_PRIVACY;
3040 memcpy(priv->BSSinfo[index].SSID, ssid, ssid_len); 3040 memcpy(priv->BSSinfo[index].SSID, ssid, ssid_len);
3041 priv->BSSinfo[index].SSIDsize = ssid_len; 3041 priv->BSSinfo[index].SSIDsize = ssid_len;
3042 3042
3043 if (capability & WLAN_CAPABILITY_IBSS) 3043 if (capability & WLAN_CAPABILITY_IBSS)
3044 priv->BSSinfo[index].BSStype = IW_MODE_ADHOC; 3044 priv->BSSinfo[index].BSStype = IW_MODE_ADHOC;
3045 else if (capability & WLAN_CAPABILITY_ESS) 3045 else if (capability & WLAN_CAPABILITY_ESS)
3046 priv->BSSinfo[index].BSStype = IW_MODE_INFRA; 3046 priv->BSSinfo[index].BSStype = IW_MODE_INFRA;
3047 3047
3048 priv->BSSinfo[index].preamble = capability & WLAN_CAPABILITY_SHORT_PREAMBLE ? 3048 priv->BSSinfo[index].preamble = capability & WLAN_CAPABILITY_SHORT_PREAMBLE ?
3049 SHORT_PREAMBLE : LONG_PREAMBLE; 3049 SHORT_PREAMBLE : LONG_PREAMBLE;
3050 } 3050 }
3051 3051
3052 static void authenticate(struct atmel_private *priv, u16 frame_len) 3052 static void authenticate(struct atmel_private *priv, u16 frame_len)
3053 { 3053 {
3054 struct auth_body *auth = (struct auth_body *)priv->rx_buf; 3054 struct auth_body *auth = (struct auth_body *)priv->rx_buf;
3055 u16 status = le16_to_cpu(auth->status); 3055 u16 status = le16_to_cpu(auth->status);
3056 u16 trans_seq_no = le16_to_cpu(auth->trans_seq); 3056 u16 trans_seq_no = le16_to_cpu(auth->trans_seq);
3057 u16 system = le16_to_cpu(auth->alg); 3057 u16 system = le16_to_cpu(auth->alg);
3058 3058
3059 if (status == WLAN_STATUS_SUCCESS && !priv->wep_is_on) { 3059 if (status == WLAN_STATUS_SUCCESS && !priv->wep_is_on) {
3060 /* no WEP */ 3060 /* no WEP */
3061 if (priv->station_was_associated) { 3061 if (priv->station_was_associated) {
3062 atmel_enter_state(priv, STATION_STATE_REASSOCIATING); 3062 atmel_enter_state(priv, STATION_STATE_REASSOCIATING);
3063 send_association_request(priv, 1); 3063 send_association_request(priv, 1);
3064 return; 3064 return;
3065 } else { 3065 } else {
3066 atmel_enter_state(priv, STATION_STATE_ASSOCIATING); 3066 atmel_enter_state(priv, STATION_STATE_ASSOCIATING);
3067 send_association_request(priv, 0); 3067 send_association_request(priv, 0);
3068 return; 3068 return;
3069 } 3069 }
3070 } 3070 }
3071 3071
3072 if (status == WLAN_STATUS_SUCCESS && priv->wep_is_on) { 3072 if (status == WLAN_STATUS_SUCCESS && priv->wep_is_on) {
3073 int should_associate = 0; 3073 int should_associate = 0;
3074 /* WEP */ 3074 /* WEP */
3075 if (trans_seq_no != priv->ExpectedAuthentTransactionSeqNum) 3075 if (trans_seq_no != priv->ExpectedAuthentTransactionSeqNum)
3076 return; 3076 return;
3077 3077
3078 if (system == WLAN_AUTH_OPEN) { 3078 if (system == WLAN_AUTH_OPEN) {
3079 if (trans_seq_no == 0x0002) { 3079 if (trans_seq_no == 0x0002) {
3080 should_associate = 1; 3080 should_associate = 1;
3081 } 3081 }
3082 } else if (system == WLAN_AUTH_SHARED_KEY) { 3082 } else if (system == WLAN_AUTH_SHARED_KEY) {
3083 if (trans_seq_no == 0x0002 && 3083 if (trans_seq_no == 0x0002 &&
3084 auth->el_id == WLAN_EID_CHALLENGE) { 3084 auth->el_id == WLAN_EID_CHALLENGE) {
3085 send_authentication_request(priv, system, auth->chall_text, auth->chall_text_len); 3085 send_authentication_request(priv, system, auth->chall_text, auth->chall_text_len);
3086 return; 3086 return;
3087 } else if (trans_seq_no == 0x0004) { 3087 } else if (trans_seq_no == 0x0004) {
3088 should_associate = 1; 3088 should_associate = 1;
3089 } 3089 }
3090 } 3090 }
3091 3091
3092 if (should_associate) { 3092 if (should_associate) {
3093 if (priv->station_was_associated) { 3093 if (priv->station_was_associated) {
3094 atmel_enter_state(priv, STATION_STATE_REASSOCIATING); 3094 atmel_enter_state(priv, STATION_STATE_REASSOCIATING);
3095 send_association_request(priv, 1); 3095 send_association_request(priv, 1);
3096 return; 3096 return;
3097 } else { 3097 } else {
3098 atmel_enter_state(priv, STATION_STATE_ASSOCIATING); 3098 atmel_enter_state(priv, STATION_STATE_ASSOCIATING);
3099 send_association_request(priv, 0); 3099 send_association_request(priv, 0);
3100 return; 3100 return;
3101 } 3101 }
3102 } 3102 }
3103 } 3103 }
3104 3104
3105 if (status == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG) { 3105 if (status == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG) {
3106 /* Flip back and forth between WEP auth modes until the max 3106 /* Flip back and forth between WEP auth modes until the max
3107 * authentication tries has been exceeded. 3107 * authentication tries has been exceeded.
3108 */ 3108 */
3109 if (system == WLAN_AUTH_OPEN) { 3109 if (system == WLAN_AUTH_OPEN) {
3110 priv->CurrentAuthentTransactionSeqNum = 0x001; 3110 priv->CurrentAuthentTransactionSeqNum = 0x001;
3111 priv->exclude_unencrypted = 1; 3111 priv->exclude_unencrypted = 1;
3112 send_authentication_request(priv, WLAN_AUTH_SHARED_KEY, NULL, 0); 3112 send_authentication_request(priv, WLAN_AUTH_SHARED_KEY, NULL, 0);
3113 return; 3113 return;
3114 } else if (system == WLAN_AUTH_SHARED_KEY 3114 } else if (system == WLAN_AUTH_SHARED_KEY
3115 && priv->wep_is_on) { 3115 && priv->wep_is_on) {
3116 priv->CurrentAuthentTransactionSeqNum = 0x001; 3116 priv->CurrentAuthentTransactionSeqNum = 0x001;
3117 priv->exclude_unencrypted = 0; 3117 priv->exclude_unencrypted = 0;
3118 send_authentication_request(priv, WLAN_AUTH_OPEN, NULL, 0); 3118 send_authentication_request(priv, WLAN_AUTH_OPEN, NULL, 0);
3119 return; 3119 return;
3120 } else if (priv->connect_to_any_BSS) { 3120 } else if (priv->connect_to_any_BSS) {
3121 int bss_index; 3121 int bss_index;
3122 3122
3123 priv->BSSinfo[(int)(priv->current_BSS)].channel |= 0x80; 3123 priv->BSSinfo[(int)(priv->current_BSS)].channel |= 0x80;
3124 3124
3125 if ((bss_index = retrieve_bss(priv)) != -1) { 3125 if ((bss_index = retrieve_bss(priv)) != -1) {
3126 atmel_join_bss(priv, bss_index); 3126 atmel_join_bss(priv, bss_index);
3127 return; 3127 return;
3128 } 3128 }
3129 } 3129 }
3130 } 3130 }
3131 3131
3132 priv->AuthenticationRequestRetryCnt = 0; 3132 priv->AuthenticationRequestRetryCnt = 0;
3133 atmel_enter_state(priv, STATION_STATE_MGMT_ERROR); 3133 atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3134 priv->station_is_associated = 0; 3134 priv->station_is_associated = 0;
3135 } 3135 }
3136 3136
3137 static void associate(struct atmel_private *priv, u16 frame_len, u16 subtype) 3137 static void associate(struct atmel_private *priv, u16 frame_len, u16 subtype)
3138 { 3138 {
3139 struct ass_resp_format { 3139 struct ass_resp_format {
3140 __le16 capability; 3140 __le16 capability;
3141 __le16 status; 3141 __le16 status;
3142 __le16 ass_id; 3142 __le16 ass_id;
3143 u8 el_id; 3143 u8 el_id;
3144 u8 length; 3144 u8 length;
3145 u8 rates[4]; 3145 u8 rates[4];
3146 } *ass_resp = (struct ass_resp_format *)priv->rx_buf; 3146 } *ass_resp = (struct ass_resp_format *)priv->rx_buf;
3147 3147
3148 u16 status = le16_to_cpu(ass_resp->status); 3148 u16 status = le16_to_cpu(ass_resp->status);
3149 u16 ass_id = le16_to_cpu(ass_resp->ass_id); 3149 u16 ass_id = le16_to_cpu(ass_resp->ass_id);
3150 u16 rates_len = ass_resp->length > 4 ? 4 : ass_resp->length; 3150 u16 rates_len = ass_resp->length > 4 ? 4 : ass_resp->length;
3151 3151
3152 union iwreq_data wrqu; 3152 union iwreq_data wrqu;
3153 3153
3154 if (frame_len < 8 + rates_len) 3154 if (frame_len < 8 + rates_len)
3155 return; 3155 return;
3156 3156
3157 if (status == WLAN_STATUS_SUCCESS) { 3157 if (status == WLAN_STATUS_SUCCESS) {
3158 if (subtype == IEEE80211_STYPE_ASSOC_RESP) 3158 if (subtype == IEEE80211_STYPE_ASSOC_RESP)
3159 priv->AssociationRequestRetryCnt = 0; 3159 priv->AssociationRequestRetryCnt = 0;
3160 else 3160 else
3161 priv->ReAssociationRequestRetryCnt = 0; 3161 priv->ReAssociationRequestRetryCnt = 0;
3162 3162
3163 atmel_set_mib16(priv, Mac_Mgmt_Mib_Type, 3163 atmel_set_mib16(priv, Mac_Mgmt_Mib_Type,
3164 MAC_MGMT_MIB_STATION_ID_POS, ass_id & 0x3fff); 3164 MAC_MGMT_MIB_STATION_ID_POS, ass_id & 0x3fff);
3165 atmel_set_mib(priv, Phy_Mib_Type, 3165 atmel_set_mib(priv, Phy_Mib_Type,
3166 PHY_MIB_RATE_SET_POS, ass_resp->rates, rates_len); 3166 PHY_MIB_RATE_SET_POS, ass_resp->rates, rates_len);
3167 if (priv->power_mode == 0) { 3167 if (priv->power_mode == 0) {
3168 priv->listen_interval = 1; 3168 priv->listen_interval = 1;
3169 atmel_set_mib8(priv, Mac_Mgmt_Mib_Type, 3169 atmel_set_mib8(priv, Mac_Mgmt_Mib_Type,
3170 MAC_MGMT_MIB_PS_MODE_POS, ACTIVE_MODE); 3170 MAC_MGMT_MIB_PS_MODE_POS, ACTIVE_MODE);
3171 atmel_set_mib16(priv, Mac_Mgmt_Mib_Type, 3171 atmel_set_mib16(priv, Mac_Mgmt_Mib_Type,
3172 MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 1); 3172 MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 1);
3173 } else { 3173 } else {
3174 priv->listen_interval = 2; 3174 priv->listen_interval = 2;
3175 atmel_set_mib8(priv, Mac_Mgmt_Mib_Type, 3175 atmel_set_mib8(priv, Mac_Mgmt_Mib_Type,
3176 MAC_MGMT_MIB_PS_MODE_POS, PS_MODE); 3176 MAC_MGMT_MIB_PS_MODE_POS, PS_MODE);
3177 atmel_set_mib16(priv, Mac_Mgmt_Mib_Type, 3177 atmel_set_mib16(priv, Mac_Mgmt_Mib_Type,
3178 MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 2); 3178 MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 2);
3179 } 3179 }
3180 3180
3181 priv->station_is_associated = 1; 3181 priv->station_is_associated = 1;
3182 priv->station_was_associated = 1; 3182 priv->station_was_associated = 1;
3183 atmel_enter_state(priv, STATION_STATE_READY); 3183 atmel_enter_state(priv, STATION_STATE_READY);
3184 3184
3185 /* Send association event to userspace */ 3185 /* Send association event to userspace */
3186 wrqu.data.length = 0; 3186 wrqu.data.length = 0;
3187 wrqu.data.flags = 0; 3187 wrqu.data.flags = 0;
3188 memcpy(wrqu.ap_addr.sa_data, priv->CurrentBSSID, ETH_ALEN); 3188 memcpy(wrqu.ap_addr.sa_data, priv->CurrentBSSID, ETH_ALEN);
3189 wrqu.ap_addr.sa_family = ARPHRD_ETHER; 3189 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
3190 wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL); 3190 wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
3191 3191
3192 return; 3192 return;
3193 } 3193 }
3194 3194
3195 if (subtype == IEEE80211_STYPE_ASSOC_RESP && 3195 if (subtype == IEEE80211_STYPE_ASSOC_RESP &&
3196 status != WLAN_STATUS_ASSOC_DENIED_RATES && 3196 status != WLAN_STATUS_ASSOC_DENIED_RATES &&
3197 status != WLAN_STATUS_CAPS_UNSUPPORTED && 3197 status != WLAN_STATUS_CAPS_UNSUPPORTED &&
3198 priv->AssociationRequestRetryCnt < MAX_ASSOCIATION_RETRIES) { 3198 priv->AssociationRequestRetryCnt < MAX_ASSOCIATION_RETRIES) {
3199 mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES); 3199 mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3200 priv->AssociationRequestRetryCnt++; 3200 priv->AssociationRequestRetryCnt++;
3201 send_association_request(priv, 0); 3201 send_association_request(priv, 0);
3202 return; 3202 return;
3203 } 3203 }
3204 3204
3205 if (subtype == IEEE80211_STYPE_REASSOC_RESP && 3205 if (subtype == IEEE80211_STYPE_REASSOC_RESP &&
3206 status != WLAN_STATUS_ASSOC_DENIED_RATES && 3206 status != WLAN_STATUS_ASSOC_DENIED_RATES &&
3207 status != WLAN_STATUS_CAPS_UNSUPPORTED && 3207 status != WLAN_STATUS_CAPS_UNSUPPORTED &&
3208 priv->AssociationRequestRetryCnt < MAX_ASSOCIATION_RETRIES) { 3208 priv->AssociationRequestRetryCnt < MAX_ASSOCIATION_RETRIES) {
3209 mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES); 3209 mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3210 priv->ReAssociationRequestRetryCnt++; 3210 priv->ReAssociationRequestRetryCnt++;
3211 send_association_request(priv, 1); 3211 send_association_request(priv, 1);
3212 return; 3212 return;
3213 } 3213 }
3214 3214
3215 atmel_enter_state(priv, STATION_STATE_MGMT_ERROR); 3215 atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3216 priv->station_is_associated = 0; 3216 priv->station_is_associated = 0;
3217 3217
3218 if (priv->connect_to_any_BSS) { 3218 if (priv->connect_to_any_BSS) {
3219 int bss_index; 3219 int bss_index;
3220 priv->BSSinfo[(int)(priv->current_BSS)].channel |= 0x80; 3220 priv->BSSinfo[(int)(priv->current_BSS)].channel |= 0x80;
3221 3221
3222 if ((bss_index = retrieve_bss(priv)) != -1) 3222 if ((bss_index = retrieve_bss(priv)) != -1)
3223 atmel_join_bss(priv, bss_index); 3223 atmel_join_bss(priv, bss_index);
3224 } 3224 }
3225 } 3225 }
3226 3226
3227 static void atmel_join_bss(struct atmel_private *priv, int bss_index) 3227 static void atmel_join_bss(struct atmel_private *priv, int bss_index)
3228 { 3228 {
3229 struct bss_info *bss = &priv->BSSinfo[bss_index]; 3229 struct bss_info *bss = &priv->BSSinfo[bss_index];
3230 3230
3231 memcpy(priv->CurrentBSSID, bss->BSSID, 6); 3231 memcpy(priv->CurrentBSSID, bss->BSSID, 6);
3232 memcpy(priv->SSID, bss->SSID, priv->SSID_size = bss->SSIDsize); 3232 memcpy(priv->SSID, bss->SSID, priv->SSID_size = bss->SSIDsize);
3233 3233
3234 /* The WPA stuff cares about the current AP address */ 3234 /* The WPA stuff cares about the current AP address */
3235 if (priv->use_wpa) 3235 if (priv->use_wpa)
3236 build_wpa_mib(priv); 3236 build_wpa_mib(priv);
3237 3237
3238 /* When switching to AdHoc turn OFF Power Save if needed */ 3238 /* When switching to AdHoc turn OFF Power Save if needed */
3239 3239
3240 if (bss->BSStype == IW_MODE_ADHOC && 3240 if (bss->BSStype == IW_MODE_ADHOC &&
3241 priv->operating_mode != IW_MODE_ADHOC && 3241 priv->operating_mode != IW_MODE_ADHOC &&
3242 priv->power_mode) { 3242 priv->power_mode) {
3243 priv->power_mode = 0; 3243 priv->power_mode = 0;
3244 priv->listen_interval = 1; 3244 priv->listen_interval = 1;
3245 atmel_set_mib8(priv, Mac_Mgmt_Mib_Type, 3245 atmel_set_mib8(priv, Mac_Mgmt_Mib_Type,
3246 MAC_MGMT_MIB_PS_MODE_POS, ACTIVE_MODE); 3246 MAC_MGMT_MIB_PS_MODE_POS, ACTIVE_MODE);
3247 atmel_set_mib16(priv, Mac_Mgmt_Mib_Type, 3247 atmel_set_mib16(priv, Mac_Mgmt_Mib_Type,
3248 MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 1); 3248 MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 1);
3249 } 3249 }
3250 3250
3251 priv->operating_mode = bss->BSStype; 3251 priv->operating_mode = bss->BSStype;
3252 priv->channel = bss->channel & 0x7f; 3252 priv->channel = bss->channel & 0x7f;
3253 priv->beacon_period = bss->beacon_period; 3253 priv->beacon_period = bss->beacon_period;
3254 3254
3255 if (priv->preamble != bss->preamble) { 3255 if (priv->preamble != bss->preamble) {
3256 priv->preamble = bss->preamble; 3256 priv->preamble = bss->preamble;
3257 atmel_set_mib8(priv, Local_Mib_Type, 3257 atmel_set_mib8(priv, Local_Mib_Type,
3258 LOCAL_MIB_PREAMBLE_TYPE, bss->preamble); 3258 LOCAL_MIB_PREAMBLE_TYPE, bss->preamble);
3259 } 3259 }
3260 3260
3261 if (!priv->wep_is_on && bss->UsingWEP) { 3261 if (!priv->wep_is_on && bss->UsingWEP) {
3262 atmel_enter_state(priv, STATION_STATE_MGMT_ERROR); 3262 atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3263 priv->station_is_associated = 0; 3263 priv->station_is_associated = 0;
3264 return; 3264 return;
3265 } 3265 }
3266 3266
3267 if (priv->wep_is_on && !bss->UsingWEP) { 3267 if (priv->wep_is_on && !bss->UsingWEP) {
3268 atmel_enter_state(priv, STATION_STATE_MGMT_ERROR); 3268 atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3269 priv->station_is_associated = 0; 3269 priv->station_is_associated = 0;
3270 return; 3270 return;
3271 } 3271 }
3272 3272
3273 atmel_enter_state(priv, STATION_STATE_JOINNING); 3273 atmel_enter_state(priv, STATION_STATE_JOINNING);
3274 3274
3275 if (priv->operating_mode == IW_MODE_INFRA) 3275 if (priv->operating_mode == IW_MODE_INFRA)
3276 join(priv, BSS_TYPE_INFRASTRUCTURE); 3276 join(priv, BSS_TYPE_INFRASTRUCTURE);
3277 else 3277 else
3278 join(priv, BSS_TYPE_AD_HOC); 3278 join(priv, BSS_TYPE_AD_HOC);
3279 } 3279 }
3280 3280
3281 static void restart_search(struct atmel_private *priv) 3281 static void restart_search(struct atmel_private *priv)
3282 { 3282 {
3283 int bss_index; 3283 int bss_index;
3284 3284
3285 if (!priv->connect_to_any_BSS) { 3285 if (!priv->connect_to_any_BSS) {
3286 atmel_scan(priv, 1); 3286 atmel_scan(priv, 1);
3287 } else { 3287 } else {
3288 priv->BSSinfo[(int)(priv->current_BSS)].channel |= 0x80; 3288 priv->BSSinfo[(int)(priv->current_BSS)].channel |= 0x80;
3289 3289
3290 if ((bss_index = retrieve_bss(priv)) != -1) 3290 if ((bss_index = retrieve_bss(priv)) != -1)
3291 atmel_join_bss(priv, bss_index); 3291 atmel_join_bss(priv, bss_index);
3292 else 3292 else
3293 atmel_scan(priv, 0); 3293 atmel_scan(priv, 0);
3294 } 3294 }
3295 } 3295 }
3296 3296
3297 static void smooth_rssi(struct atmel_private *priv, u8 rssi) 3297 static void smooth_rssi(struct atmel_private *priv, u8 rssi)
3298 { 3298 {
3299 u8 old = priv->wstats.qual.level; 3299 u8 old = priv->wstats.qual.level;
3300 u8 max_rssi = 42; /* 502-rmfd-revd max by experiment, default for now */ 3300 u8 max_rssi = 42; /* 502-rmfd-revd max by experiment, default for now */
3301 3301
3302 switch (priv->firmware_type) { 3302 switch (priv->firmware_type) {
3303 case ATMEL_FW_TYPE_502E: 3303 case ATMEL_FW_TYPE_502E:
3304 max_rssi = 63; /* 502-rmfd-reve max by experiment */ 3304 max_rssi = 63; /* 502-rmfd-reve max by experiment */
3305 break; 3305 break;
3306 default: 3306 default:
3307 break; 3307 break;
3308 } 3308 }
3309 3309
3310 rssi = rssi * 100 / max_rssi; 3310 rssi = rssi * 100 / max_rssi;
3311 if ((rssi + old) % 2) 3311 if ((rssi + old) % 2)
3312 priv->wstats.qual.level = (rssi + old) / 2 + 1; 3312 priv->wstats.qual.level = (rssi + old) / 2 + 1;
3313 else 3313 else
3314 priv->wstats.qual.level = (rssi + old) / 2; 3314 priv->wstats.qual.level = (rssi + old) / 2;
3315 priv->wstats.qual.updated |= IW_QUAL_LEVEL_UPDATED; 3315 priv->wstats.qual.updated |= IW_QUAL_LEVEL_UPDATED;
3316 priv->wstats.qual.updated &= ~IW_QUAL_LEVEL_INVALID; 3316 priv->wstats.qual.updated &= ~IW_QUAL_LEVEL_INVALID;
3317 } 3317 }
3318 3318
3319 static void atmel_smooth_qual(struct atmel_private *priv) 3319 static void atmel_smooth_qual(struct atmel_private *priv)
3320 { 3320 {
3321 unsigned long time_diff = (jiffies - priv->last_qual) / HZ; 3321 unsigned long time_diff = (jiffies - priv->last_qual) / HZ;
3322 while (time_diff--) { 3322 while (time_diff--) {
3323 priv->last_qual += HZ; 3323 priv->last_qual += HZ;
3324 priv->wstats.qual.qual = priv->wstats.qual.qual / 2; 3324 priv->wstats.qual.qual = priv->wstats.qual.qual / 2;
3325 priv->wstats.qual.qual += 3325 priv->wstats.qual.qual +=
3326 priv->beacons_this_sec * priv->beacon_period * (priv->wstats.qual.level + 100) / 4000; 3326 priv->beacons_this_sec * priv->beacon_period * (priv->wstats.qual.level + 100) / 4000;
3327 priv->beacons_this_sec = 0; 3327 priv->beacons_this_sec = 0;
3328 } 3328 }
3329 priv->wstats.qual.updated |= IW_QUAL_QUAL_UPDATED; 3329 priv->wstats.qual.updated |= IW_QUAL_QUAL_UPDATED;
3330 priv->wstats.qual.updated &= ~IW_QUAL_QUAL_INVALID; 3330 priv->wstats.qual.updated &= ~IW_QUAL_QUAL_INVALID;
3331 } 3331 }
3332 3332
3333 /* deals with incoming managment frames. */ 3333 /* deals with incoming management frames. */
3334 static void atmel_management_frame(struct atmel_private *priv, 3334 static void atmel_management_frame(struct atmel_private *priv,
3335 struct ieee80211_hdr *header, 3335 struct ieee80211_hdr *header,
3336 u16 frame_len, u8 rssi) 3336 u16 frame_len, u8 rssi)
3337 { 3337 {
3338 u16 subtype; 3338 u16 subtype;
3339 3339
3340 subtype = le16_to_cpu(header->frame_control) & IEEE80211_FCTL_STYPE; 3340 subtype = le16_to_cpu(header->frame_control) & IEEE80211_FCTL_STYPE;
3341 switch (subtype) { 3341 switch (subtype) {
3342 case IEEE80211_STYPE_BEACON: 3342 case IEEE80211_STYPE_BEACON:
3343 case IEEE80211_STYPE_PROBE_RESP: 3343 case IEEE80211_STYPE_PROBE_RESP:
3344 3344
3345 /* beacon frame has multiple variable-length fields - 3345 /* beacon frame has multiple variable-length fields -
3346 never let an engineer loose with a data structure design. */ 3346 never let an engineer loose with a data structure design. */
3347 { 3347 {
3348 struct beacon_format { 3348 struct beacon_format {
3349 __le64 timestamp; 3349 __le64 timestamp;
3350 __le16 interval; 3350 __le16 interval;
3351 __le16 capability; 3351 __le16 capability;
3352 u8 ssid_el_id; 3352 u8 ssid_el_id;
3353 u8 ssid_length; 3353 u8 ssid_length;
3354 /* ssid here */ 3354 /* ssid here */
3355 u8 rates_el_id; 3355 u8 rates_el_id;
3356 u8 rates_length; 3356 u8 rates_length;
3357 /* rates here */ 3357 /* rates here */
3358 u8 ds_el_id; 3358 u8 ds_el_id;
3359 u8 ds_length; 3359 u8 ds_length;
3360 /* ds here */ 3360 /* ds here */
3361 } *beacon = (struct beacon_format *)priv->rx_buf; 3361 } *beacon = (struct beacon_format *)priv->rx_buf;
3362 3362
3363 u8 channel, rates_length, ssid_length; 3363 u8 channel, rates_length, ssid_length;
3364 u64 timestamp = le64_to_cpu(beacon->timestamp); 3364 u64 timestamp = le64_to_cpu(beacon->timestamp);
3365 u16 beacon_interval = le16_to_cpu(beacon->interval); 3365 u16 beacon_interval = le16_to_cpu(beacon->interval);
3366 u16 capability = le16_to_cpu(beacon->capability); 3366 u16 capability = le16_to_cpu(beacon->capability);
3367 u8 *beaconp = priv->rx_buf; 3367 u8 *beaconp = priv->rx_buf;
3368 ssid_length = beacon->ssid_length; 3368 ssid_length = beacon->ssid_length;
3369 /* this blows chunks. */ 3369 /* this blows chunks. */
3370 if (frame_len < 14 || frame_len < ssid_length + 15) 3370 if (frame_len < 14 || frame_len < ssid_length + 15)
3371 return; 3371 return;
3372 rates_length = beaconp[beacon->ssid_length + 15]; 3372 rates_length = beaconp[beacon->ssid_length + 15];
3373 if (frame_len < ssid_length + rates_length + 18) 3373 if (frame_len < ssid_length + rates_length + 18)
3374 return; 3374 return;
3375 if (ssid_length > MAX_SSID_LENGTH) 3375 if (ssid_length > MAX_SSID_LENGTH)
3376 return; 3376 return;
3377 channel = beaconp[ssid_length + rates_length + 18]; 3377 channel = beaconp[ssid_length + rates_length + 18];
3378 3378
3379 if (priv->station_state == STATION_STATE_READY) { 3379 if (priv->station_state == STATION_STATE_READY) {
3380 smooth_rssi(priv, rssi); 3380 smooth_rssi(priv, rssi);
3381 if (is_frame_from_current_bss(priv, header)) { 3381 if (is_frame_from_current_bss(priv, header)) {
3382 priv->beacons_this_sec++; 3382 priv->beacons_this_sec++;
3383 atmel_smooth_qual(priv); 3383 atmel_smooth_qual(priv);
3384 if (priv->last_beacon_timestamp) { 3384 if (priv->last_beacon_timestamp) {
3385 /* Note truncate this to 32 bits - kernel can't divide a long long */ 3385 /* Note truncate this to 32 bits - kernel can't divide a long long */
3386 u32 beacon_delay = timestamp - priv->last_beacon_timestamp; 3386 u32 beacon_delay = timestamp - priv->last_beacon_timestamp;
3387 int beacons = beacon_delay / (beacon_interval * 1000); 3387 int beacons = beacon_delay / (beacon_interval * 1000);
3388 if (beacons > 1) 3388 if (beacons > 1)
3389 priv->wstats.miss.beacon += beacons - 1; 3389 priv->wstats.miss.beacon += beacons - 1;
3390 } 3390 }
3391 priv->last_beacon_timestamp = timestamp; 3391 priv->last_beacon_timestamp = timestamp;
3392 handle_beacon_probe(priv, capability, channel); 3392 handle_beacon_probe(priv, capability, channel);
3393 } 3393 }
3394 } 3394 }
3395 3395
3396 if (priv->station_state == STATION_STATE_SCANNING) 3396 if (priv->station_state == STATION_STATE_SCANNING)
3397 store_bss_info(priv, header, capability, 3397 store_bss_info(priv, header, capability,
3398 beacon_interval, channel, rssi, 3398 beacon_interval, channel, rssi,
3399 ssid_length, 3399 ssid_length,
3400 &beacon->rates_el_id, 3400 &beacon->rates_el_id,
3401 subtype == IEEE80211_STYPE_BEACON); 3401 subtype == IEEE80211_STYPE_BEACON);
3402 } 3402 }
3403 break; 3403 break;
3404 3404
3405 case IEEE80211_STYPE_AUTH: 3405 case IEEE80211_STYPE_AUTH:
3406 3406
3407 if (priv->station_state == STATION_STATE_AUTHENTICATING) 3407 if (priv->station_state == STATION_STATE_AUTHENTICATING)
3408 authenticate(priv, frame_len); 3408 authenticate(priv, frame_len);
3409 3409
3410 break; 3410 break;
3411 3411
3412 case IEEE80211_STYPE_ASSOC_RESP: 3412 case IEEE80211_STYPE_ASSOC_RESP:
3413 case IEEE80211_STYPE_REASSOC_RESP: 3413 case IEEE80211_STYPE_REASSOC_RESP:
3414 3414
3415 if (priv->station_state == STATION_STATE_ASSOCIATING || 3415 if (priv->station_state == STATION_STATE_ASSOCIATING ||
3416 priv->station_state == STATION_STATE_REASSOCIATING) 3416 priv->station_state == STATION_STATE_REASSOCIATING)
3417 associate(priv, frame_len, subtype); 3417 associate(priv, frame_len, subtype);
3418 3418
3419 break; 3419 break;
3420 3420
3421 case IEEE80211_STYPE_DISASSOC: 3421 case IEEE80211_STYPE_DISASSOC:
3422 if (priv->station_is_associated && 3422 if (priv->station_is_associated &&
3423 priv->operating_mode == IW_MODE_INFRA && 3423 priv->operating_mode == IW_MODE_INFRA &&
3424 is_frame_from_current_bss(priv, header)) { 3424 is_frame_from_current_bss(priv, header)) {
3425 priv->station_was_associated = 0; 3425 priv->station_was_associated = 0;
3426 priv->station_is_associated = 0; 3426 priv->station_is_associated = 0;
3427 3427
3428 atmel_enter_state(priv, STATION_STATE_JOINNING); 3428 atmel_enter_state(priv, STATION_STATE_JOINNING);
3429 join(priv, BSS_TYPE_INFRASTRUCTURE); 3429 join(priv, BSS_TYPE_INFRASTRUCTURE);
3430 } 3430 }
3431 3431
3432 break; 3432 break;
3433 3433
3434 case IEEE80211_STYPE_DEAUTH: 3434 case IEEE80211_STYPE_DEAUTH:
3435 if (priv->operating_mode == IW_MODE_INFRA && 3435 if (priv->operating_mode == IW_MODE_INFRA &&
3436 is_frame_from_current_bss(priv, header)) { 3436 is_frame_from_current_bss(priv, header)) {
3437 priv->station_was_associated = 0; 3437 priv->station_was_associated = 0;
3438 3438
3439 atmel_enter_state(priv, STATION_STATE_JOINNING); 3439 atmel_enter_state(priv, STATION_STATE_JOINNING);
3440 join(priv, BSS_TYPE_INFRASTRUCTURE); 3440 join(priv, BSS_TYPE_INFRASTRUCTURE);
3441 } 3441 }
3442 3442
3443 break; 3443 break;
3444 } 3444 }
3445 } 3445 }
3446 3446
3447 /* run when timer expires */ 3447 /* run when timer expires */
3448 static void atmel_management_timer(u_long a) 3448 static void atmel_management_timer(u_long a)
3449 { 3449 {
3450 struct net_device *dev = (struct net_device *) a; 3450 struct net_device *dev = (struct net_device *) a;
3451 struct atmel_private *priv = netdev_priv(dev); 3451 struct atmel_private *priv = netdev_priv(dev);
3452 unsigned long flags; 3452 unsigned long flags;
3453 3453
3454 /* Check if the card has been yanked. */ 3454 /* Check if the card has been yanked. */
3455 if (priv->card && priv->present_callback && 3455 if (priv->card && priv->present_callback &&
3456 !(*priv->present_callback)(priv->card)) 3456 !(*priv->present_callback)(priv->card))
3457 return; 3457 return;
3458 3458
3459 spin_lock_irqsave(&priv->irqlock, flags); 3459 spin_lock_irqsave(&priv->irqlock, flags);
3460 3460
3461 switch (priv->station_state) { 3461 switch (priv->station_state) {
3462 3462
3463 case STATION_STATE_AUTHENTICATING: 3463 case STATION_STATE_AUTHENTICATING:
3464 if (priv->AuthenticationRequestRetryCnt >= MAX_AUTHENTICATION_RETRIES) { 3464 if (priv->AuthenticationRequestRetryCnt >= MAX_AUTHENTICATION_RETRIES) {
3465 atmel_enter_state(priv, STATION_STATE_MGMT_ERROR); 3465 atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3466 priv->station_is_associated = 0; 3466 priv->station_is_associated = 0;
3467 priv->AuthenticationRequestRetryCnt = 0; 3467 priv->AuthenticationRequestRetryCnt = 0;
3468 restart_search(priv); 3468 restart_search(priv);
3469 } else { 3469 } else {
3470 int auth = WLAN_AUTH_OPEN; 3470 int auth = WLAN_AUTH_OPEN;
3471 priv->AuthenticationRequestRetryCnt++; 3471 priv->AuthenticationRequestRetryCnt++;
3472 priv->CurrentAuthentTransactionSeqNum = 0x0001; 3472 priv->CurrentAuthentTransactionSeqNum = 0x0001;
3473 mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES); 3473 mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3474 if (priv->wep_is_on && priv->exclude_unencrypted) 3474 if (priv->wep_is_on && priv->exclude_unencrypted)
3475 auth = WLAN_AUTH_SHARED_KEY; 3475 auth = WLAN_AUTH_SHARED_KEY;
3476 send_authentication_request(priv, auth, NULL, 0); 3476 send_authentication_request(priv, auth, NULL, 0);
3477 } 3477 }
3478 break; 3478 break;
3479 3479
3480 case STATION_STATE_ASSOCIATING: 3480 case STATION_STATE_ASSOCIATING:
3481 if (priv->AssociationRequestRetryCnt == MAX_ASSOCIATION_RETRIES) { 3481 if (priv->AssociationRequestRetryCnt == MAX_ASSOCIATION_RETRIES) {
3482 atmel_enter_state(priv, STATION_STATE_MGMT_ERROR); 3482 atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3483 priv->station_is_associated = 0; 3483 priv->station_is_associated = 0;
3484 priv->AssociationRequestRetryCnt = 0; 3484 priv->AssociationRequestRetryCnt = 0;
3485 restart_search(priv); 3485 restart_search(priv);
3486 } else { 3486 } else {
3487 priv->AssociationRequestRetryCnt++; 3487 priv->AssociationRequestRetryCnt++;
3488 mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES); 3488 mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3489 send_association_request(priv, 0); 3489 send_association_request(priv, 0);
3490 } 3490 }
3491 break; 3491 break;
3492 3492
3493 case STATION_STATE_REASSOCIATING: 3493 case STATION_STATE_REASSOCIATING:
3494 if (priv->ReAssociationRequestRetryCnt == MAX_ASSOCIATION_RETRIES) { 3494 if (priv->ReAssociationRequestRetryCnt == MAX_ASSOCIATION_RETRIES) {
3495 atmel_enter_state(priv, STATION_STATE_MGMT_ERROR); 3495 atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
3496 priv->station_is_associated = 0; 3496 priv->station_is_associated = 0;
3497 priv->ReAssociationRequestRetryCnt = 0; 3497 priv->ReAssociationRequestRetryCnt = 0;
3498 restart_search(priv); 3498 restart_search(priv);
3499 } else { 3499 } else {
3500 priv->ReAssociationRequestRetryCnt++; 3500 priv->ReAssociationRequestRetryCnt++;
3501 mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES); 3501 mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3502 send_association_request(priv, 1); 3502 send_association_request(priv, 1);
3503 } 3503 }
3504 break; 3504 break;
3505 3505
3506 default: 3506 default:
3507 break; 3507 break;
3508 } 3508 }
3509 3509
3510 spin_unlock_irqrestore(&priv->irqlock, flags); 3510 spin_unlock_irqrestore(&priv->irqlock, flags);
3511 } 3511 }
3512 3512
3513 static void atmel_command_irq(struct atmel_private *priv) 3513 static void atmel_command_irq(struct atmel_private *priv)
3514 { 3514 {
3515 u8 status = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_STATUS_OFFSET)); 3515 u8 status = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_STATUS_OFFSET));
3516 u8 command = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_COMMAND_OFFSET)); 3516 u8 command = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_COMMAND_OFFSET));
3517 int fast_scan; 3517 int fast_scan;
3518 union iwreq_data wrqu; 3518 union iwreq_data wrqu;
3519 3519
3520 if (status == CMD_STATUS_IDLE || 3520 if (status == CMD_STATUS_IDLE ||
3521 status == CMD_STATUS_IN_PROGRESS) 3521 status == CMD_STATUS_IN_PROGRESS)
3522 return; 3522 return;
3523 3523
3524 switch (command) { 3524 switch (command) {
3525 case CMD_Start: 3525 case CMD_Start:
3526 if (status == CMD_STATUS_COMPLETE) { 3526 if (status == CMD_STATUS_COMPLETE) {
3527 priv->station_was_associated = priv->station_is_associated; 3527 priv->station_was_associated = priv->station_is_associated;
3528 atmel_get_mib(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_CUR_BSSID_POS, 3528 atmel_get_mib(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_CUR_BSSID_POS,
3529 (u8 *)priv->CurrentBSSID, 6); 3529 (u8 *)priv->CurrentBSSID, 6);
3530 atmel_enter_state(priv, STATION_STATE_READY); 3530 atmel_enter_state(priv, STATION_STATE_READY);
3531 } 3531 }
3532 break; 3532 break;
3533 3533
3534 case CMD_Scan: 3534 case CMD_Scan:
3535 fast_scan = priv->fast_scan; 3535 fast_scan = priv->fast_scan;
3536 priv->fast_scan = 0; 3536 priv->fast_scan = 0;
3537 3537
3538 if (status != CMD_STATUS_COMPLETE) { 3538 if (status != CMD_STATUS_COMPLETE) {
3539 atmel_scan(priv, 1); 3539 atmel_scan(priv, 1);
3540 } else { 3540 } else {
3541 int bss_index = retrieve_bss(priv); 3541 int bss_index = retrieve_bss(priv);
3542 int notify_scan_complete = 1; 3542 int notify_scan_complete = 1;
3543 if (bss_index != -1) { 3543 if (bss_index != -1) {
3544 atmel_join_bss(priv, bss_index); 3544 atmel_join_bss(priv, bss_index);
3545 } else if (priv->operating_mode == IW_MODE_ADHOC && 3545 } else if (priv->operating_mode == IW_MODE_ADHOC &&
3546 priv->SSID_size != 0) { 3546 priv->SSID_size != 0) {
3547 start(priv, BSS_TYPE_AD_HOC); 3547 start(priv, BSS_TYPE_AD_HOC);
3548 } else { 3548 } else {
3549 priv->fast_scan = !fast_scan; 3549 priv->fast_scan = !fast_scan;
3550 atmel_scan(priv, 1); 3550 atmel_scan(priv, 1);
3551 notify_scan_complete = 0; 3551 notify_scan_complete = 0;
3552 } 3552 }
3553 priv->site_survey_state = SITE_SURVEY_COMPLETED; 3553 priv->site_survey_state = SITE_SURVEY_COMPLETED;
3554 if (notify_scan_complete) { 3554 if (notify_scan_complete) {
3555 wrqu.data.length = 0; 3555 wrqu.data.length = 0;
3556 wrqu.data.flags = 0; 3556 wrqu.data.flags = 0;
3557 wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL); 3557 wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL);
3558 } 3558 }
3559 } 3559 }
3560 break; 3560 break;
3561 3561
3562 case CMD_SiteSurvey: 3562 case CMD_SiteSurvey:
3563 priv->fast_scan = 0; 3563 priv->fast_scan = 0;
3564 3564
3565 if (status != CMD_STATUS_COMPLETE) 3565 if (status != CMD_STATUS_COMPLETE)
3566 return; 3566 return;
3567 3567
3568 priv->site_survey_state = SITE_SURVEY_COMPLETED; 3568 priv->site_survey_state = SITE_SURVEY_COMPLETED;
3569 if (priv->station_is_associated) { 3569 if (priv->station_is_associated) {
3570 atmel_enter_state(priv, STATION_STATE_READY); 3570 atmel_enter_state(priv, STATION_STATE_READY);
3571 wrqu.data.length = 0; 3571 wrqu.data.length = 0;
3572 wrqu.data.flags = 0; 3572 wrqu.data.flags = 0;
3573 wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL); 3573 wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL);
3574 } else { 3574 } else {
3575 atmel_scan(priv, 1); 3575 atmel_scan(priv, 1);
3576 } 3576 }
3577 break; 3577 break;
3578 3578
3579 case CMD_Join: 3579 case CMD_Join:
3580 if (status == CMD_STATUS_COMPLETE) { 3580 if (status == CMD_STATUS_COMPLETE) {
3581 if (priv->operating_mode == IW_MODE_ADHOC) { 3581 if (priv->operating_mode == IW_MODE_ADHOC) {
3582 priv->station_was_associated = priv->station_is_associated; 3582 priv->station_was_associated = priv->station_is_associated;
3583 atmel_enter_state(priv, STATION_STATE_READY); 3583 atmel_enter_state(priv, STATION_STATE_READY);
3584 } else { 3584 } else {
3585 int auth = WLAN_AUTH_OPEN; 3585 int auth = WLAN_AUTH_OPEN;
3586 priv->AuthenticationRequestRetryCnt = 0; 3586 priv->AuthenticationRequestRetryCnt = 0;
3587 atmel_enter_state(priv, STATION_STATE_AUTHENTICATING); 3587 atmel_enter_state(priv, STATION_STATE_AUTHENTICATING);
3588 3588
3589 mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES); 3589 mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
3590 priv->CurrentAuthentTransactionSeqNum = 0x0001; 3590 priv->CurrentAuthentTransactionSeqNum = 0x0001;
3591 if (priv->wep_is_on && priv->exclude_unencrypted) 3591 if (priv->wep_is_on && priv->exclude_unencrypted)
3592 auth = WLAN_AUTH_SHARED_KEY; 3592 auth = WLAN_AUTH_SHARED_KEY;
3593 send_authentication_request(priv, auth, NULL, 0); 3593 send_authentication_request(priv, auth, NULL, 0);
3594 } 3594 }
3595 return; 3595 return;
3596 } 3596 }
3597 3597
3598 atmel_scan(priv, 1); 3598 atmel_scan(priv, 1);
3599 } 3599 }
3600 } 3600 }
3601 3601
3602 static int atmel_wakeup_firmware(struct atmel_private *priv) 3602 static int atmel_wakeup_firmware(struct atmel_private *priv)
3603 { 3603 {
3604 struct host_info_struct *iface = &priv->host_info; 3604 struct host_info_struct *iface = &priv->host_info;
3605 u16 mr1, mr3; 3605 u16 mr1, mr3;
3606 int i; 3606 int i;
3607 3607
3608 if (priv->card_type == CARD_TYPE_SPI_FLASH) 3608 if (priv->card_type == CARD_TYPE_SPI_FLASH)
3609 atmel_set_gcr(priv->dev, GCR_REMAP); 3609 atmel_set_gcr(priv->dev, GCR_REMAP);
3610 3610
3611 /* wake up on-board processor */ 3611 /* wake up on-board processor */
3612 atmel_clear_gcr(priv->dev, 0x0040); 3612 atmel_clear_gcr(priv->dev, 0x0040);
3613 atmel_write16(priv->dev, BSR, BSS_SRAM); 3613 atmel_write16(priv->dev, BSR, BSS_SRAM);
3614 3614
3615 if (priv->card_type == CARD_TYPE_SPI_FLASH) 3615 if (priv->card_type == CARD_TYPE_SPI_FLASH)
3616 mdelay(100); 3616 mdelay(100);
3617 3617
3618 /* and wait for it */ 3618 /* and wait for it */
3619 for (i = LOOP_RETRY_LIMIT; i; i--) { 3619 for (i = LOOP_RETRY_LIMIT; i; i--) {
3620 mr1 = atmel_read16(priv->dev, MR1); 3620 mr1 = atmel_read16(priv->dev, MR1);
3621 mr3 = atmel_read16(priv->dev, MR3); 3621 mr3 = atmel_read16(priv->dev, MR3);
3622 3622
3623 if (mr3 & MAC_BOOT_COMPLETE) 3623 if (mr3 & MAC_BOOT_COMPLETE)
3624 break; 3624 break;
3625 if (mr1 & MAC_BOOT_COMPLETE && 3625 if (mr1 & MAC_BOOT_COMPLETE &&
3626 priv->bus_type == BUS_TYPE_PCCARD) 3626 priv->bus_type == BUS_TYPE_PCCARD)
3627 break; 3627 break;
3628 } 3628 }
3629 3629
3630 if (i == 0) { 3630 if (i == 0) {
3631 printk(KERN_ALERT "%s: MAC failed to boot.\n", priv->dev->name); 3631 printk(KERN_ALERT "%s: MAC failed to boot.\n", priv->dev->name);
3632 return -EIO; 3632 return -EIO;
3633 } 3633 }
3634 3634
3635 if ((priv->host_info_base = atmel_read16(priv->dev, MR2)) == 0xffff) { 3635 if ((priv->host_info_base = atmel_read16(priv->dev, MR2)) == 0xffff) {
3636 printk(KERN_ALERT "%s: card missing.\n", priv->dev->name); 3636 printk(KERN_ALERT "%s: card missing.\n", priv->dev->name);
3637 return -ENODEV; 3637 return -ENODEV;
3638 } 3638 }
3639 3639
3640 /* now check for completion of MAC initialization through 3640 /* now check for completion of MAC initialization through
3641 the FunCtrl field of the IFACE, poll MR1 to detect completion of 3641 the FunCtrl field of the IFACE, poll MR1 to detect completion of
3642 MAC initialization, check completion status, set interrupt mask, 3642 MAC initialization, check completion status, set interrupt mask,
3643 enables interrupts and calls Tx and Rx initialization functions */ 3643 enables interrupts and calls Tx and Rx initialization functions */
3644 3644
3645 atmel_wmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET), FUNC_CTRL_INIT_COMPLETE); 3645 atmel_wmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET), FUNC_CTRL_INIT_COMPLETE);
3646 3646
3647 for (i = LOOP_RETRY_LIMIT; i; i--) { 3647 for (i = LOOP_RETRY_LIMIT; i; i--) {
3648 mr1 = atmel_read16(priv->dev, MR1); 3648 mr1 = atmel_read16(priv->dev, MR1);
3649 mr3 = atmel_read16(priv->dev, MR3); 3649 mr3 = atmel_read16(priv->dev, MR3);
3650 3650
3651 if (mr3 & MAC_INIT_COMPLETE) 3651 if (mr3 & MAC_INIT_COMPLETE)
3652 break; 3652 break;
3653 if (mr1 & MAC_INIT_COMPLETE && 3653 if (mr1 & MAC_INIT_COMPLETE &&
3654 priv->bus_type == BUS_TYPE_PCCARD) 3654 priv->bus_type == BUS_TYPE_PCCARD)
3655 break; 3655 break;
3656 } 3656 }
3657 3657
3658 if (i == 0) { 3658 if (i == 0) {
3659 printk(KERN_ALERT "%s: MAC failed to initialise.\n", 3659 printk(KERN_ALERT "%s: MAC failed to initialise.\n",
3660 priv->dev->name); 3660 priv->dev->name);
3661 return -EIO; 3661 return -EIO;
3662 } 3662 }
3663 3663
3664 /* Check for MAC_INIT_OK only on the register that the MAC_INIT_OK was set */ 3664 /* Check for MAC_INIT_OK only on the register that the MAC_INIT_OK was set */
3665 if ((mr3 & MAC_INIT_COMPLETE) && 3665 if ((mr3 & MAC_INIT_COMPLETE) &&
3666 !(atmel_read16(priv->dev, MR3) & MAC_INIT_OK)) { 3666 !(atmel_read16(priv->dev, MR3) & MAC_INIT_OK)) {
3667 printk(KERN_ALERT "%s: MAC failed MR3 self-test.\n", priv->dev->name); 3667 printk(KERN_ALERT "%s: MAC failed MR3 self-test.\n", priv->dev->name);
3668 return -EIO; 3668 return -EIO;
3669 } 3669 }
3670 if ((mr1 & MAC_INIT_COMPLETE) && 3670 if ((mr1 & MAC_INIT_COMPLETE) &&
3671 !(atmel_read16(priv->dev, MR1) & MAC_INIT_OK)) { 3671 !(atmel_read16(priv->dev, MR1) & MAC_INIT_OK)) {
3672 printk(KERN_ALERT "%s: MAC failed MR1 self-test.\n", priv->dev->name); 3672 printk(KERN_ALERT "%s: MAC failed MR1 self-test.\n", priv->dev->name);
3673 return -EIO; 3673 return -EIO;
3674 } 3674 }
3675 3675
3676 atmel_copy_to_host(priv->dev, (unsigned char *)iface, 3676 atmel_copy_to_host(priv->dev, (unsigned char *)iface,
3677 priv->host_info_base, sizeof(*iface)); 3677 priv->host_info_base, sizeof(*iface));
3678 3678
3679 iface->tx_buff_pos = le16_to_cpu(iface->tx_buff_pos); 3679 iface->tx_buff_pos = le16_to_cpu(iface->tx_buff_pos);
3680 iface->tx_buff_size = le16_to_cpu(iface->tx_buff_size); 3680 iface->tx_buff_size = le16_to_cpu(iface->tx_buff_size);
3681 iface->tx_desc_pos = le16_to_cpu(iface->tx_desc_pos); 3681 iface->tx_desc_pos = le16_to_cpu(iface->tx_desc_pos);
3682 iface->tx_desc_count = le16_to_cpu(iface->tx_desc_count); 3682 iface->tx_desc_count = le16_to_cpu(iface->tx_desc_count);
3683 iface->rx_buff_pos = le16_to_cpu(iface->rx_buff_pos); 3683 iface->rx_buff_pos = le16_to_cpu(iface->rx_buff_pos);
3684 iface->rx_buff_size = le16_to_cpu(iface->rx_buff_size); 3684 iface->rx_buff_size = le16_to_cpu(iface->rx_buff_size);
3685 iface->rx_desc_pos = le16_to_cpu(iface->rx_desc_pos); 3685 iface->rx_desc_pos = le16_to_cpu(iface->rx_desc_pos);
3686 iface->rx_desc_count = le16_to_cpu(iface->rx_desc_count); 3686 iface->rx_desc_count = le16_to_cpu(iface->rx_desc_count);
3687 iface->build_version = le16_to_cpu(iface->build_version); 3687 iface->build_version = le16_to_cpu(iface->build_version);
3688 iface->command_pos = le16_to_cpu(iface->command_pos); 3688 iface->command_pos = le16_to_cpu(iface->command_pos);
3689 iface->major_version = le16_to_cpu(iface->major_version); 3689 iface->major_version = le16_to_cpu(iface->major_version);
3690 iface->minor_version = le16_to_cpu(iface->minor_version); 3690 iface->minor_version = le16_to_cpu(iface->minor_version);
3691 iface->func_ctrl = le16_to_cpu(iface->func_ctrl); 3691 iface->func_ctrl = le16_to_cpu(iface->func_ctrl);
3692 iface->mac_status = le16_to_cpu(iface->mac_status); 3692 iface->mac_status = le16_to_cpu(iface->mac_status);
3693 3693
3694 return 0; 3694 return 0;
3695 } 3695 }
3696 3696
3697 /* determine type of memory and MAC address */ 3697 /* determine type of memory and MAC address */
3698 static int probe_atmel_card(struct net_device *dev) 3698 static int probe_atmel_card(struct net_device *dev)
3699 { 3699 {
3700 int rc = 0; 3700 int rc = 0;
3701 struct atmel_private *priv = netdev_priv(dev); 3701 struct atmel_private *priv = netdev_priv(dev);
3702 3702
3703 /* reset pccard */ 3703 /* reset pccard */
3704 if (priv->bus_type == BUS_TYPE_PCCARD) 3704 if (priv->bus_type == BUS_TYPE_PCCARD)
3705 atmel_write16(dev, GCR, 0x0060); 3705 atmel_write16(dev, GCR, 0x0060);
3706 3706
3707 atmel_write16(dev, GCR, 0x0040); 3707 atmel_write16(dev, GCR, 0x0040);
3708 mdelay(500); 3708 mdelay(500);
3709 3709
3710 if (atmel_read16(dev, MR2) == 0) { 3710 if (atmel_read16(dev, MR2) == 0) {
3711 /* No stored firmware so load a small stub which just 3711 /* No stored firmware so load a small stub which just
3712 tells us the MAC address */ 3712 tells us the MAC address */
3713 int i; 3713 int i;
3714 priv->card_type = CARD_TYPE_EEPROM; 3714 priv->card_type = CARD_TYPE_EEPROM;
3715 atmel_write16(dev, BSR, BSS_IRAM); 3715 atmel_write16(dev, BSR, BSS_IRAM);
3716 atmel_copy_to_card(dev, 0, mac_reader, sizeof(mac_reader)); 3716 atmel_copy_to_card(dev, 0, mac_reader, sizeof(mac_reader));
3717 atmel_set_gcr(dev, GCR_REMAP); 3717 atmel_set_gcr(dev, GCR_REMAP);
3718 atmel_clear_gcr(priv->dev, 0x0040); 3718 atmel_clear_gcr(priv->dev, 0x0040);
3719 atmel_write16(dev, BSR, BSS_SRAM); 3719 atmel_write16(dev, BSR, BSS_SRAM);
3720 for (i = LOOP_RETRY_LIMIT; i; i--) 3720 for (i = LOOP_RETRY_LIMIT; i; i--)
3721 if (atmel_read16(dev, MR3) & MAC_BOOT_COMPLETE) 3721 if (atmel_read16(dev, MR3) & MAC_BOOT_COMPLETE)
3722 break; 3722 break;
3723 if (i == 0) { 3723 if (i == 0) {
3724 printk(KERN_ALERT "%s: MAC failed to boot MAC address reader.\n", dev->name); 3724 printk(KERN_ALERT "%s: MAC failed to boot MAC address reader.\n", dev->name);
3725 } else { 3725 } else {
3726 atmel_copy_to_host(dev, dev->dev_addr, atmel_read16(dev, MR2), 6); 3726 atmel_copy_to_host(dev, dev->dev_addr, atmel_read16(dev, MR2), 6);
3727 /* got address, now squash it again until the network 3727 /* got address, now squash it again until the network
3728 interface is opened */ 3728 interface is opened */
3729 if (priv->bus_type == BUS_TYPE_PCCARD) 3729 if (priv->bus_type == BUS_TYPE_PCCARD)
3730 atmel_write16(dev, GCR, 0x0060); 3730 atmel_write16(dev, GCR, 0x0060);
3731 atmel_write16(dev, GCR, 0x0040); 3731 atmel_write16(dev, GCR, 0x0040);
3732 rc = 1; 3732 rc = 1;
3733 } 3733 }
3734 } else if (atmel_read16(dev, MR4) == 0) { 3734 } else if (atmel_read16(dev, MR4) == 0) {
3735 /* Mac address easy in this case. */ 3735 /* Mac address easy in this case. */
3736 priv->card_type = CARD_TYPE_PARALLEL_FLASH; 3736 priv->card_type = CARD_TYPE_PARALLEL_FLASH;
3737 atmel_write16(dev, BSR, 1); 3737 atmel_write16(dev, BSR, 1);
3738 atmel_copy_to_host(dev, dev->dev_addr, 0xc000, 6); 3738 atmel_copy_to_host(dev, dev->dev_addr, 0xc000, 6);
3739 atmel_write16(dev, BSR, 0x200); 3739 atmel_write16(dev, BSR, 0x200);
3740 rc = 1; 3740 rc = 1;
3741 } else { 3741 } else {
3742 /* Standard firmware in flash, boot it up and ask 3742 /* Standard firmware in flash, boot it up and ask
3743 for the Mac Address */ 3743 for the Mac Address */
3744 priv->card_type = CARD_TYPE_SPI_FLASH; 3744 priv->card_type = CARD_TYPE_SPI_FLASH;
3745 if (atmel_wakeup_firmware(priv) == 0) { 3745 if (atmel_wakeup_firmware(priv) == 0) {
3746 atmel_get_mib(priv, Mac_Address_Mib_Type, 0, dev->dev_addr, 6); 3746 atmel_get_mib(priv, Mac_Address_Mib_Type, 0, dev->dev_addr, 6);
3747 3747
3748 /* got address, now squash it again until the network 3748 /* got address, now squash it again until the network
3749 interface is opened */ 3749 interface is opened */
3750 if (priv->bus_type == BUS_TYPE_PCCARD) 3750 if (priv->bus_type == BUS_TYPE_PCCARD)
3751 atmel_write16(dev, GCR, 0x0060); 3751 atmel_write16(dev, GCR, 0x0060);
3752 atmel_write16(dev, GCR, 0x0040); 3752 atmel_write16(dev, GCR, 0x0040);
3753 rc = 1; 3753 rc = 1;
3754 } 3754 }
3755 } 3755 }
3756 3756
3757 if (rc) { 3757 if (rc) {
3758 if (dev->dev_addr[0] == 0xFF) { 3758 if (dev->dev_addr[0] == 0xFF) {
3759 u8 default_mac[] = {0x00, 0x04, 0x25, 0x00, 0x00, 0x00}; 3759 u8 default_mac[] = {0x00, 0x04, 0x25, 0x00, 0x00, 0x00};
3760 printk(KERN_ALERT "%s: *** Invalid MAC address. UPGRADE Firmware ****\n", dev->name); 3760 printk(KERN_ALERT "%s: *** Invalid MAC address. UPGRADE Firmware ****\n", dev->name);
3761 memcpy(dev->dev_addr, default_mac, 6); 3761 memcpy(dev->dev_addr, default_mac, 6);
3762 } 3762 }
3763 } 3763 }
3764 3764
3765 return rc; 3765 return rc;
3766 } 3766 }
3767 3767
3768 /* Move the encyption information on the MIB structure. 3768 /* Move the encyption information on the MIB structure.
3769 This routine is for the pre-WPA firmware: later firmware has 3769 This routine is for the pre-WPA firmware: later firmware has
3770 a different format MIB and a different routine. */ 3770 a different format MIB and a different routine. */
3771 static void build_wep_mib(struct atmel_private *priv) 3771 static void build_wep_mib(struct atmel_private *priv)
3772 { 3772 {
3773 struct { /* NB this is matched to the hardware, don't change. */ 3773 struct { /* NB this is matched to the hardware, don't change. */
3774 u8 wep_is_on; 3774 u8 wep_is_on;
3775 u8 default_key; /* 0..3 */ 3775 u8 default_key; /* 0..3 */
3776 u8 reserved; 3776 u8 reserved;
3777 u8 exclude_unencrypted; 3777 u8 exclude_unencrypted;
3778 3778
3779 u32 WEPICV_error_count; 3779 u32 WEPICV_error_count;
3780 u32 WEP_excluded_count; 3780 u32 WEP_excluded_count;
3781 3781
3782 u8 wep_keys[MAX_ENCRYPTION_KEYS][13]; 3782 u8 wep_keys[MAX_ENCRYPTION_KEYS][13];
3783 u8 encryption_level; /* 0, 1, 2 */ 3783 u8 encryption_level; /* 0, 1, 2 */
3784 u8 reserved2[3]; 3784 u8 reserved2[3];
3785 } mib; 3785 } mib;
3786 int i; 3786 int i;
3787 3787
3788 mib.wep_is_on = priv->wep_is_on; 3788 mib.wep_is_on = priv->wep_is_on;
3789 if (priv->wep_is_on) { 3789 if (priv->wep_is_on) {
3790 if (priv->wep_key_len[priv->default_key] > 5) 3790 if (priv->wep_key_len[priv->default_key] > 5)
3791 mib.encryption_level = 2; 3791 mib.encryption_level = 2;
3792 else 3792 else
3793 mib.encryption_level = 1; 3793 mib.encryption_level = 1;
3794 } else { 3794 } else {
3795 mib.encryption_level = 0; 3795 mib.encryption_level = 0;
3796 } 3796 }
3797 3797
3798 mib.default_key = priv->default_key; 3798 mib.default_key = priv->default_key;
3799 mib.exclude_unencrypted = priv->exclude_unencrypted; 3799 mib.exclude_unencrypted = priv->exclude_unencrypted;
3800 3800
3801 for (i = 0; i < MAX_ENCRYPTION_KEYS; i++) 3801 for (i = 0; i < MAX_ENCRYPTION_KEYS; i++)
3802 memcpy(mib.wep_keys[i], priv->wep_keys[i], 13); 3802 memcpy(mib.wep_keys[i], priv->wep_keys[i], 13);
3803 3803
3804 atmel_set_mib(priv, Mac_Wep_Mib_Type, 0, (u8 *)&mib, sizeof(mib)); 3804 atmel_set_mib(priv, Mac_Wep_Mib_Type, 0, (u8 *)&mib, sizeof(mib));
3805 } 3805 }
3806 3806
3807 static void build_wpa_mib(struct atmel_private *priv) 3807 static void build_wpa_mib(struct atmel_private *priv)
3808 { 3808 {
3809 /* This is for the later (WPA enabled) firmware. */ 3809 /* This is for the later (WPA enabled) firmware. */
3810 3810
3811 struct { /* NB this is matched to the hardware, don't change. */ 3811 struct { /* NB this is matched to the hardware, don't change. */
3812 u8 cipher_default_key_value[MAX_ENCRYPTION_KEYS][MAX_ENCRYPTION_KEY_SIZE]; 3812 u8 cipher_default_key_value[MAX_ENCRYPTION_KEYS][MAX_ENCRYPTION_KEY_SIZE];
3813 u8 receiver_address[6]; 3813 u8 receiver_address[6];
3814 u8 wep_is_on; 3814 u8 wep_is_on;
3815 u8 default_key; /* 0..3 */ 3815 u8 default_key; /* 0..3 */
3816 u8 group_key; 3816 u8 group_key;
3817 u8 exclude_unencrypted; 3817 u8 exclude_unencrypted;
3818 u8 encryption_type; 3818 u8 encryption_type;
3819 u8 reserved; 3819 u8 reserved;
3820 3820
3821 u32 WEPICV_error_count; 3821 u32 WEPICV_error_count;
3822 u32 WEP_excluded_count; 3822 u32 WEP_excluded_count;
3823 3823
3824 u8 key_RSC[4][8]; 3824 u8 key_RSC[4][8];
3825 } mib; 3825 } mib;
3826 3826
3827 int i; 3827 int i;
3828 3828
3829 mib.wep_is_on = priv->wep_is_on; 3829 mib.wep_is_on = priv->wep_is_on;
3830 mib.exclude_unencrypted = priv->exclude_unencrypted; 3830 mib.exclude_unencrypted = priv->exclude_unencrypted;
3831 memcpy(mib.receiver_address, priv->CurrentBSSID, 6); 3831 memcpy(mib.receiver_address, priv->CurrentBSSID, 6);
3832 3832
3833 /* zero all the keys before adding in valid ones. */ 3833 /* zero all the keys before adding in valid ones. */
3834 memset(mib.cipher_default_key_value, 0, sizeof(mib.cipher_default_key_value)); 3834 memset(mib.cipher_default_key_value, 0, sizeof(mib.cipher_default_key_value));
3835 3835
3836 if (priv->wep_is_on) { 3836 if (priv->wep_is_on) {
3837 /* There's a comment in the Atmel code to the effect that this 3837 /* There's a comment in the Atmel code to the effect that this
3838 is only valid when still using WEP, it may need to be set to 3838 is only valid when still using WEP, it may need to be set to
3839 something to use WPA */ 3839 something to use WPA */
3840 memset(mib.key_RSC, 0, sizeof(mib.key_RSC)); 3840 memset(mib.key_RSC, 0, sizeof(mib.key_RSC));
3841 3841
3842 mib.default_key = mib.group_key = 255; 3842 mib.default_key = mib.group_key = 255;
3843 for (i = 0; i < MAX_ENCRYPTION_KEYS; i++) { 3843 for (i = 0; i < MAX_ENCRYPTION_KEYS; i++) {
3844 if (priv->wep_key_len[i] > 0) { 3844 if (priv->wep_key_len[i] > 0) {
3845 memcpy(mib.cipher_default_key_value[i], priv->wep_keys[i], MAX_ENCRYPTION_KEY_SIZE); 3845 memcpy(mib.cipher_default_key_value[i], priv->wep_keys[i], MAX_ENCRYPTION_KEY_SIZE);
3846 if (i == priv->default_key) { 3846 if (i == priv->default_key) {
3847 mib.default_key = i; 3847 mib.default_key = i;
3848 mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-1] = 7; 3848 mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-1] = 7;
3849 mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-2] = priv->pairwise_cipher_suite; 3849 mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-2] = priv->pairwise_cipher_suite;
3850 } else { 3850 } else {
3851 mib.group_key = i; 3851 mib.group_key = i;
3852 priv->group_cipher_suite = priv->pairwise_cipher_suite; 3852 priv->group_cipher_suite = priv->pairwise_cipher_suite;
3853 mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-1] = 1; 3853 mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-1] = 1;
3854 mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-2] = priv->group_cipher_suite; 3854 mib.cipher_default_key_value[i][MAX_ENCRYPTION_KEY_SIZE-2] = priv->group_cipher_suite;
3855 } 3855 }
3856 } 3856 }
3857 } 3857 }
3858 if (mib.default_key == 255) 3858 if (mib.default_key == 255)
3859 mib.default_key = mib.group_key != 255 ? mib.group_key : 0; 3859 mib.default_key = mib.group_key != 255 ? mib.group_key : 0;
3860 if (mib.group_key == 255) 3860 if (mib.group_key == 255)
3861 mib.group_key = mib.default_key; 3861 mib.group_key = mib.default_key;
3862 3862
3863 } 3863 }
3864 3864
3865 atmel_set_mib(priv, Mac_Wep_Mib_Type, 0, (u8 *)&mib, sizeof(mib)); 3865 atmel_set_mib(priv, Mac_Wep_Mib_Type, 0, (u8 *)&mib, sizeof(mib));
3866 } 3866 }
3867 3867
3868 static int reset_atmel_card(struct net_device *dev) 3868 static int reset_atmel_card(struct net_device *dev)
3869 { 3869 {
3870 /* do everything necessary to wake up the hardware, including 3870 /* do everything necessary to wake up the hardware, including
3871 waiting for the lightning strike and throwing the knife switch.... 3871 waiting for the lightning strike and throwing the knife switch....
3872 3872
3873 set all the Mib values which matter in the card to match 3873 set all the Mib values which matter in the card to match
3874 their settings in the atmel_private structure. Some of these 3874 their settings in the atmel_private structure. Some of these
3875 can be altered on the fly, but many (WEP, infrastucture or ad-hoc) 3875 can be altered on the fly, but many (WEP, infrastucture or ad-hoc)
3876 can only be changed by tearing down the world and coming back through 3876 can only be changed by tearing down the world and coming back through
3877 here. 3877 here.
3878 3878
3879 This routine is also responsible for initialising some 3879 This routine is also responsible for initialising some
3880 hardware-specific fields in the atmel_private structure, 3880 hardware-specific fields in the atmel_private structure,
3881 including a copy of the firmware's hostinfo stucture 3881 including a copy of the firmware's hostinfo stucture
3882 which is the route into the rest of the firmware datastructures. */ 3882 which is the route into the rest of the firmware datastructures. */
3883 3883
3884 struct atmel_private *priv = netdev_priv(dev); 3884 struct atmel_private *priv = netdev_priv(dev);
3885 u8 configuration; 3885 u8 configuration;
3886 int old_state = priv->station_state; 3886 int old_state = priv->station_state;
3887 int err = 0; 3887 int err = 0;
3888 3888
3889 /* data to add to the firmware names, in priority order 3889 /* data to add to the firmware names, in priority order
3890 this implemenents firmware versioning */ 3890 this implemenents firmware versioning */
3891 3891
3892 static char *firmware_modifier[] = { 3892 static char *firmware_modifier[] = {
3893 "-wpa", 3893 "-wpa",
3894 "", 3894 "",
3895 NULL 3895 NULL
3896 }; 3896 };
3897 3897
3898 /* reset pccard */ 3898 /* reset pccard */
3899 if (priv->bus_type == BUS_TYPE_PCCARD) 3899 if (priv->bus_type == BUS_TYPE_PCCARD)
3900 atmel_write16(priv->dev, GCR, 0x0060); 3900 atmel_write16(priv->dev, GCR, 0x0060);
3901 3901
3902 /* stop card , disable interrupts */ 3902 /* stop card , disable interrupts */
3903 atmel_write16(priv->dev, GCR, 0x0040); 3903 atmel_write16(priv->dev, GCR, 0x0040);
3904 3904
3905 if (priv->card_type == CARD_TYPE_EEPROM) { 3905 if (priv->card_type == CARD_TYPE_EEPROM) {
3906 /* copy in firmware if needed */ 3906 /* copy in firmware if needed */
3907 const struct firmware *fw_entry = NULL; 3907 const struct firmware *fw_entry = NULL;
3908 const unsigned char *fw; 3908 const unsigned char *fw;
3909 int len = priv->firmware_length; 3909 int len = priv->firmware_length;
3910 if (!(fw = priv->firmware)) { 3910 if (!(fw = priv->firmware)) {
3911 if (priv->firmware_type == ATMEL_FW_TYPE_NONE) { 3911 if (priv->firmware_type == ATMEL_FW_TYPE_NONE) {
3912 if (strlen(priv->firmware_id) == 0) { 3912 if (strlen(priv->firmware_id) == 0) {
3913 printk(KERN_INFO 3913 printk(KERN_INFO
3914 "%s: card type is unknown: assuming at76c502 firmware is OK.\n", 3914 "%s: card type is unknown: assuming at76c502 firmware is OK.\n",
3915 dev->name); 3915 dev->name);
3916 printk(KERN_INFO 3916 printk(KERN_INFO
3917 "%s: if not, use the firmware= module parameter.\n", 3917 "%s: if not, use the firmware= module parameter.\n",
3918 dev->name); 3918 dev->name);
3919 strcpy(priv->firmware_id, "atmel_at76c502.bin"); 3919 strcpy(priv->firmware_id, "atmel_at76c502.bin");
3920 } 3920 }
3921 err = request_firmware(&fw_entry, priv->firmware_id, priv->sys_dev); 3921 err = request_firmware(&fw_entry, priv->firmware_id, priv->sys_dev);
3922 if (err != 0) { 3922 if (err != 0) {
3923 printk(KERN_ALERT 3923 printk(KERN_ALERT
3924 "%s: firmware %s is missing, cannot continue.\n", 3924 "%s: firmware %s is missing, cannot continue.\n",
3925 dev->name, priv->firmware_id); 3925 dev->name, priv->firmware_id);
3926 return err; 3926 return err;
3927 } 3927 }
3928 } else { 3928 } else {
3929 int fw_index = 0; 3929 int fw_index = 0;
3930 int success = 0; 3930 int success = 0;
3931 3931
3932 /* get firmware filename entry based on firmware type ID */ 3932 /* get firmware filename entry based on firmware type ID */
3933 while (fw_table[fw_index].fw_type != priv->firmware_type 3933 while (fw_table[fw_index].fw_type != priv->firmware_type
3934 && fw_table[fw_index].fw_type != ATMEL_FW_TYPE_NONE) 3934 && fw_table[fw_index].fw_type != ATMEL_FW_TYPE_NONE)
3935 fw_index++; 3935 fw_index++;
3936 3936
3937 /* construct the actual firmware file name */ 3937 /* construct the actual firmware file name */
3938 if (fw_table[fw_index].fw_type != ATMEL_FW_TYPE_NONE) { 3938 if (fw_table[fw_index].fw_type != ATMEL_FW_TYPE_NONE) {
3939 int i; 3939 int i;
3940 for (i = 0; firmware_modifier[i]; i++) { 3940 for (i = 0; firmware_modifier[i]; i++) {
3941 snprintf(priv->firmware_id, 32, "%s%s.%s", fw_table[fw_index].fw_file, 3941 snprintf(priv->firmware_id, 32, "%s%s.%s", fw_table[fw_index].fw_file,
3942 firmware_modifier[i], fw_table[fw_index].fw_file_ext); 3942 firmware_modifier[i], fw_table[fw_index].fw_file_ext);
3943 priv->firmware_id[31] = '\0'; 3943 priv->firmware_id[31] = '\0';
3944 if (request_firmware(&fw_entry, priv->firmware_id, priv->sys_dev) == 0) { 3944 if (request_firmware(&fw_entry, priv->firmware_id, priv->sys_dev) == 0) {
3945 success = 1; 3945 success = 1;
3946 break; 3946 break;
3947 } 3947 }
3948 } 3948 }
3949 } 3949 }
3950 if (!success) { 3950 if (!success) {
3951 printk(KERN_ALERT 3951 printk(KERN_ALERT
3952 "%s: firmware %s is missing, cannot start.\n", 3952 "%s: firmware %s is missing, cannot start.\n",
3953 dev->name, priv->firmware_id); 3953 dev->name, priv->firmware_id);
3954 priv->firmware_id[0] = '\0'; 3954 priv->firmware_id[0] = '\0';
3955 return -ENOENT; 3955 return -ENOENT;
3956 } 3956 }
3957 } 3957 }
3958 3958
3959 fw = fw_entry->data; 3959 fw = fw_entry->data;
3960 len = fw_entry->size; 3960 len = fw_entry->size;
3961 } 3961 }
3962 3962
3963 if (len <= 0x6000) { 3963 if (len <= 0x6000) {
3964 atmel_write16(priv->dev, BSR, BSS_IRAM); 3964 atmel_write16(priv->dev, BSR, BSS_IRAM);
3965 atmel_copy_to_card(priv->dev, 0, fw, len); 3965 atmel_copy_to_card(priv->dev, 0, fw, len);
3966 atmel_set_gcr(priv->dev, GCR_REMAP); 3966 atmel_set_gcr(priv->dev, GCR_REMAP);
3967 } else { 3967 } else {
3968 /* Remap */ 3968 /* Remap */
3969 atmel_set_gcr(priv->dev, GCR_REMAP); 3969 atmel_set_gcr(priv->dev, GCR_REMAP);
3970 atmel_write16(priv->dev, BSR, BSS_IRAM); 3970 atmel_write16(priv->dev, BSR, BSS_IRAM);
3971 atmel_copy_to_card(priv->dev, 0, fw, 0x6000); 3971 atmel_copy_to_card(priv->dev, 0, fw, 0x6000);
3972 atmel_write16(priv->dev, BSR, 0x2ff); 3972 atmel_write16(priv->dev, BSR, 0x2ff);
3973 atmel_copy_to_card(priv->dev, 0x8000, &fw[0x6000], len - 0x6000); 3973 atmel_copy_to_card(priv->dev, 0x8000, &fw[0x6000], len - 0x6000);
3974 } 3974 }
3975 3975
3976 if (fw_entry) 3976 if (fw_entry)
3977 release_firmware(fw_entry); 3977 release_firmware(fw_entry);
3978 } 3978 }
3979 3979
3980 err = atmel_wakeup_firmware(priv); 3980 err = atmel_wakeup_firmware(priv);
3981 if (err != 0) 3981 if (err != 0)
3982 return err; 3982 return err;
3983 3983
3984 /* Check the version and set the correct flag for wpa stuff, 3984 /* Check the version and set the correct flag for wpa stuff,
3985 old and new firmware is incompatible. 3985 old and new firmware is incompatible.
3986 The pre-wpa 3com firmware reports major version 5, 3986 The pre-wpa 3com firmware reports major version 5,
3987 the wpa 3com firmware is major version 4 and doesn't need 3987 the wpa 3com firmware is major version 4 and doesn't need
3988 the 3com broken-ness filter. */ 3988 the 3com broken-ness filter. */
3989 priv->use_wpa = (priv->host_info.major_version == 4); 3989 priv->use_wpa = (priv->host_info.major_version == 4);
3990 priv->radio_on_broken = (priv->host_info.major_version == 5); 3990 priv->radio_on_broken = (priv->host_info.major_version == 5);
3991 3991
3992 /* unmask all irq sources */ 3992 /* unmask all irq sources */
3993 atmel_wmem8(priv, atmel_hi(priv, IFACE_INT_MASK_OFFSET), 0xff); 3993 atmel_wmem8(priv, atmel_hi(priv, IFACE_INT_MASK_OFFSET), 0xff);
3994 3994
3995 /* int Tx system and enable Tx */ 3995 /* int Tx system and enable Tx */
3996 atmel_wmem8(priv, atmel_tx(priv, TX_DESC_FLAGS_OFFSET, 0), 0); 3996 atmel_wmem8(priv, atmel_tx(priv, TX_DESC_FLAGS_OFFSET, 0), 0);
3997 atmel_wmem32(priv, atmel_tx(priv, TX_DESC_NEXT_OFFSET, 0), 0x80000000L); 3997 atmel_wmem32(priv, atmel_tx(priv, TX_DESC_NEXT_OFFSET, 0), 0x80000000L);
3998 atmel_wmem16(priv, atmel_tx(priv, TX_DESC_POS_OFFSET, 0), 0); 3998 atmel_wmem16(priv, atmel_tx(priv, TX_DESC_POS_OFFSET, 0), 0);
3999 atmel_wmem16(priv, atmel_tx(priv, TX_DESC_SIZE_OFFSET, 0), 0); 3999 atmel_wmem16(priv, atmel_tx(priv, TX_DESC_SIZE_OFFSET, 0), 0);
4000 4000
4001 priv->tx_desc_free = priv->host_info.tx_desc_count; 4001 priv->tx_desc_free = priv->host_info.tx_desc_count;
4002 priv->tx_desc_head = 0; 4002 priv->tx_desc_head = 0;
4003 priv->tx_desc_tail = 0; 4003 priv->tx_desc_tail = 0;
4004 priv->tx_desc_previous = 0; 4004 priv->tx_desc_previous = 0;
4005 priv->tx_free_mem = priv->host_info.tx_buff_size; 4005 priv->tx_free_mem = priv->host_info.tx_buff_size;
4006 priv->tx_buff_head = 0; 4006 priv->tx_buff_head = 0;
4007 priv->tx_buff_tail = 0; 4007 priv->tx_buff_tail = 0;
4008 4008
4009 configuration = atmel_rmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET)); 4009 configuration = atmel_rmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET));
4010 atmel_wmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET), 4010 atmel_wmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET),
4011 configuration | FUNC_CTRL_TxENABLE); 4011 configuration | FUNC_CTRL_TxENABLE);
4012 4012
4013 /* init Rx system and enable */ 4013 /* init Rx system and enable */
4014 priv->rx_desc_head = 0; 4014 priv->rx_desc_head = 0;
4015 4015
4016 configuration = atmel_rmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET)); 4016 configuration = atmel_rmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET));
4017 atmel_wmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET), 4017 atmel_wmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET),
4018 configuration | FUNC_CTRL_RxENABLE); 4018 configuration | FUNC_CTRL_RxENABLE);
4019 4019
4020 if (!priv->radio_on_broken) { 4020 if (!priv->radio_on_broken) {
4021 if (atmel_send_command_wait(priv, CMD_EnableRadio, NULL, 0) == 4021 if (atmel_send_command_wait(priv, CMD_EnableRadio, NULL, 0) ==
4022 CMD_STATUS_REJECTED_RADIO_OFF) { 4022 CMD_STATUS_REJECTED_RADIO_OFF) {
4023 printk(KERN_INFO "%s: cannot turn the radio on.\n", 4023 printk(KERN_INFO "%s: cannot turn the radio on.\n",
4024 dev->name); 4024 dev->name);
4025 return -EIO; 4025 return -EIO;
4026 } 4026 }
4027 } 4027 }
4028 4028
4029 /* set up enough MIB values to run. */ 4029 /* set up enough MIB values to run. */
4030 atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_AUTO_TX_RATE_POS, priv->auto_tx_rate); 4030 atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_AUTO_TX_RATE_POS, priv->auto_tx_rate);
4031 atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_TX_PROMISCUOUS_POS, PROM_MODE_OFF); 4031 atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_TX_PROMISCUOUS_POS, PROM_MODE_OFF);
4032 atmel_set_mib16(priv, Mac_Mib_Type, MAC_MIB_RTS_THRESHOLD_POS, priv->rts_threshold); 4032 atmel_set_mib16(priv, Mac_Mib_Type, MAC_MIB_RTS_THRESHOLD_POS, priv->rts_threshold);
4033 atmel_set_mib16(priv, Mac_Mib_Type, MAC_MIB_FRAG_THRESHOLD_POS, priv->frag_threshold); 4033 atmel_set_mib16(priv, Mac_Mib_Type, MAC_MIB_FRAG_THRESHOLD_POS, priv->frag_threshold);
4034 atmel_set_mib8(priv, Mac_Mib_Type, MAC_MIB_SHORT_RETRY_POS, priv->short_retry); 4034 atmel_set_mib8(priv, Mac_Mib_Type, MAC_MIB_SHORT_RETRY_POS, priv->short_retry);
4035 atmel_set_mib8(priv, Mac_Mib_Type, MAC_MIB_LONG_RETRY_POS, priv->long_retry); 4035 atmel_set_mib8(priv, Mac_Mib_Type, MAC_MIB_LONG_RETRY_POS, priv->long_retry);
4036 atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_PREAMBLE_TYPE, priv->preamble); 4036 atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_PREAMBLE_TYPE, priv->preamble);
4037 atmel_set_mib(priv, Mac_Address_Mib_Type, MAC_ADDR_MIB_MAC_ADDR_POS, 4037 atmel_set_mib(priv, Mac_Address_Mib_Type, MAC_ADDR_MIB_MAC_ADDR_POS,
4038 priv->dev->dev_addr, 6); 4038 priv->dev->dev_addr, 6);
4039 atmel_set_mib8(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_PS_MODE_POS, ACTIVE_MODE); 4039 atmel_set_mib8(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_PS_MODE_POS, ACTIVE_MODE);
4040 atmel_set_mib16(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 1); 4040 atmel_set_mib16(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 1);
4041 atmel_set_mib16(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_BEACON_PER_POS, priv->default_beacon_period); 4041 atmel_set_mib16(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_BEACON_PER_POS, priv->default_beacon_period);
4042 atmel_set_mib(priv, Phy_Mib_Type, PHY_MIB_RATE_SET_POS, atmel_basic_rates, 4); 4042 atmel_set_mib(priv, Phy_Mib_Type, PHY_MIB_RATE_SET_POS, atmel_basic_rates, 4);
4043 atmel_set_mib8(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_CUR_PRIVACY_POS, priv->wep_is_on); 4043 atmel_set_mib8(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_CUR_PRIVACY_POS, priv->wep_is_on);
4044 if (priv->use_wpa) 4044 if (priv->use_wpa)
4045 build_wpa_mib(priv); 4045 build_wpa_mib(priv);
4046 else 4046 else
4047 build_wep_mib(priv); 4047 build_wep_mib(priv);
4048 4048
4049 if (old_state == STATION_STATE_READY) { 4049 if (old_state == STATION_STATE_READY) {
4050 union iwreq_data wrqu; 4050 union iwreq_data wrqu;
4051 4051
4052 wrqu.data.length = 0; 4052 wrqu.data.length = 0;
4053 wrqu.data.flags = 0; 4053 wrqu.data.flags = 0;
4054 wrqu.ap_addr.sa_family = ARPHRD_ETHER; 4054 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
4055 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN); 4055 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
4056 wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL); 4056 wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
4057 } 4057 }
4058 4058
4059 return 0; 4059 return 0;
4060 } 4060 }
4061 4061
4062 static void atmel_send_command(struct atmel_private *priv, int command, 4062 static void atmel_send_command(struct atmel_private *priv, int command,
4063 void *cmd, int cmd_size) 4063 void *cmd, int cmd_size)
4064 { 4064 {
4065 if (cmd) 4065 if (cmd)
4066 atmel_copy_to_card(priv->dev, atmel_co(priv, CMD_BLOCK_PARAMETERS_OFFSET), 4066 atmel_copy_to_card(priv->dev, atmel_co(priv, CMD_BLOCK_PARAMETERS_OFFSET),
4067 cmd, cmd_size); 4067 cmd, cmd_size);
4068 4068
4069 atmel_wmem8(priv, atmel_co(priv, CMD_BLOCK_COMMAND_OFFSET), command); 4069 atmel_wmem8(priv, atmel_co(priv, CMD_BLOCK_COMMAND_OFFSET), command);
4070 atmel_wmem8(priv, atmel_co(priv, CMD_BLOCK_STATUS_OFFSET), 0); 4070 atmel_wmem8(priv, atmel_co(priv, CMD_BLOCK_STATUS_OFFSET), 0);
4071 } 4071 }
4072 4072
4073 static int atmel_send_command_wait(struct atmel_private *priv, int command, 4073 static int atmel_send_command_wait(struct atmel_private *priv, int command,
4074 void *cmd, int cmd_size) 4074 void *cmd, int cmd_size)
4075 { 4075 {
4076 int i, status; 4076 int i, status;
4077 4077
4078 atmel_send_command(priv, command, cmd, cmd_size); 4078 atmel_send_command(priv, command, cmd, cmd_size);
4079 4079
4080 for (i = 5000; i; i--) { 4080 for (i = 5000; i; i--) {
4081 status = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_STATUS_OFFSET)); 4081 status = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_STATUS_OFFSET));
4082 if (status != CMD_STATUS_IDLE && 4082 if (status != CMD_STATUS_IDLE &&
4083 status != CMD_STATUS_IN_PROGRESS) 4083 status != CMD_STATUS_IN_PROGRESS)
4084 break; 4084 break;
4085 udelay(20); 4085 udelay(20);
4086 } 4086 }
4087 4087
4088 if (i == 0) { 4088 if (i == 0) {
4089 printk(KERN_ALERT "%s: failed to contact MAC.\n", priv->dev->name); 4089 printk(KERN_ALERT "%s: failed to contact MAC.\n", priv->dev->name);
4090 status = CMD_STATUS_HOST_ERROR; 4090 status = CMD_STATUS_HOST_ERROR;
4091 } else { 4091 } else {
4092 if (command != CMD_EnableRadio) 4092 if (command != CMD_EnableRadio)
4093 status = CMD_STATUS_COMPLETE; 4093 status = CMD_STATUS_COMPLETE;
4094 } 4094 }
4095 4095
4096 return status; 4096 return status;
4097 } 4097 }
4098 4098
4099 static u8 atmel_get_mib8(struct atmel_private *priv, u8 type, u8 index) 4099 static u8 atmel_get_mib8(struct atmel_private *priv, u8 type, u8 index)
4100 { 4100 {
4101 struct get_set_mib m; 4101 struct get_set_mib m;
4102 m.type = type; 4102 m.type = type;
4103 m.size = 1; 4103 m.size = 1;
4104 m.index = index; 4104 m.index = index;
4105 4105
4106 atmel_send_command_wait(priv, CMD_Get_MIB_Vars, &m, MIB_HEADER_SIZE + 1); 4106 atmel_send_command_wait(priv, CMD_Get_MIB_Vars, &m, MIB_HEADER_SIZE + 1);
4107 return atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_PARAMETERS_OFFSET + MIB_HEADER_SIZE)); 4107 return atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_PARAMETERS_OFFSET + MIB_HEADER_SIZE));
4108 } 4108 }
4109 4109
4110 static void atmel_set_mib8(struct atmel_private *priv, u8 type, u8 index, u8 data) 4110 static void atmel_set_mib8(struct atmel_private *priv, u8 type, u8 index, u8 data)
4111 { 4111 {
4112 struct get_set_mib m; 4112 struct get_set_mib m;
4113 m.type = type; 4113 m.type = type;
4114 m.size = 1; 4114 m.size = 1;
4115 m.index = index; 4115 m.index = index;
4116 m.data[0] = data; 4116 m.data[0] = data;
4117 4117
4118 atmel_send_command_wait(priv, CMD_Set_MIB_Vars, &m, MIB_HEADER_SIZE + 1); 4118 atmel_send_command_wait(priv, CMD_Set_MIB_Vars, &m, MIB_HEADER_SIZE + 1);
4119 } 4119 }
4120 4120
4121 static void atmel_set_mib16(struct atmel_private *priv, u8 type, u8 index, 4121 static void atmel_set_mib16(struct atmel_private *priv, u8 type, u8 index,
4122 u16 data) 4122 u16 data)
4123 { 4123 {
4124 struct get_set_mib m; 4124 struct get_set_mib m;
4125 m.type = type; 4125 m.type = type;
4126 m.size = 2; 4126 m.size = 2;
4127 m.index = index; 4127 m.index = index;
4128 m.data[0] = data; 4128 m.data[0] = data;
4129 m.data[1] = data >> 8; 4129 m.data[1] = data >> 8;
4130 4130
4131 atmel_send_command_wait(priv, CMD_Set_MIB_Vars, &m, MIB_HEADER_SIZE + 2); 4131 atmel_send_command_wait(priv, CMD_Set_MIB_Vars, &m, MIB_HEADER_SIZE + 2);
4132 } 4132 }
4133 4133
4134 static void atmel_set_mib(struct atmel_private *priv, u8 type, u8 index, 4134 static void atmel_set_mib(struct atmel_private *priv, u8 type, u8 index,
4135 u8 *data, int data_len) 4135 u8 *data, int data_len)
4136 { 4136 {
4137 struct get_set_mib m; 4137 struct get_set_mib m;
4138 m.type = type; 4138 m.type = type;
4139 m.size = data_len; 4139 m.size = data_len;
4140 m.index = index; 4140 m.index = index;
4141 4141
4142 if (data_len > MIB_MAX_DATA_BYTES) 4142 if (data_len > MIB_MAX_DATA_BYTES)
4143 printk(KERN_ALERT "%s: MIB buffer too small.\n", priv->dev->name); 4143 printk(KERN_ALERT "%s: MIB buffer too small.\n", priv->dev->name);
4144 4144
4145 memcpy(m.data, data, data_len); 4145 memcpy(m.data, data, data_len);
4146 atmel_send_command_wait(priv, CMD_Set_MIB_Vars, &m, MIB_HEADER_SIZE + data_len); 4146 atmel_send_command_wait(priv, CMD_Set_MIB_Vars, &m, MIB_HEADER_SIZE + data_len);
4147 } 4147 }
4148 4148
4149 static void atmel_get_mib(struct atmel_private *priv, u8 type, u8 index, 4149 static void atmel_get_mib(struct atmel_private *priv, u8 type, u8 index,
4150 u8 *data, int data_len) 4150 u8 *data, int data_len)
4151 { 4151 {
4152 struct get_set_mib m; 4152 struct get_set_mib m;
4153 m.type = type; 4153 m.type = type;
4154 m.size = data_len; 4154 m.size = data_len;
4155 m.index = index; 4155 m.index = index;
4156 4156
4157 if (data_len > MIB_MAX_DATA_BYTES) 4157 if (data_len > MIB_MAX_DATA_BYTES)
4158 printk(KERN_ALERT "%s: MIB buffer too small.\n", priv->dev->name); 4158 printk(KERN_ALERT "%s: MIB buffer too small.\n", priv->dev->name);
4159 4159
4160 atmel_send_command_wait(priv, CMD_Get_MIB_Vars, &m, MIB_HEADER_SIZE + data_len); 4160 atmel_send_command_wait(priv, CMD_Get_MIB_Vars, &m, MIB_HEADER_SIZE + data_len);
4161 atmel_copy_to_host(priv->dev, data, 4161 atmel_copy_to_host(priv->dev, data,
4162 atmel_co(priv, CMD_BLOCK_PARAMETERS_OFFSET + MIB_HEADER_SIZE), data_len); 4162 atmel_co(priv, CMD_BLOCK_PARAMETERS_OFFSET + MIB_HEADER_SIZE), data_len);
4163 } 4163 }
4164 4164
4165 static void atmel_writeAR(struct net_device *dev, u16 data) 4165 static void atmel_writeAR(struct net_device *dev, u16 data)
4166 { 4166 {
4167 int i; 4167 int i;
4168 outw(data, dev->base_addr + AR); 4168 outw(data, dev->base_addr + AR);
4169 /* Address register appears to need some convincing..... */ 4169 /* Address register appears to need some convincing..... */
4170 for (i = 0; data != inw(dev->base_addr + AR) && i < 10; i++) 4170 for (i = 0; data != inw(dev->base_addr + AR) && i < 10; i++)
4171 outw(data, dev->base_addr + AR); 4171 outw(data, dev->base_addr + AR);
4172 } 4172 }
4173 4173
4174 static void atmel_copy_to_card(struct net_device *dev, u16 dest, 4174 static void atmel_copy_to_card(struct net_device *dev, u16 dest,
4175 const unsigned char *src, u16 len) 4175 const unsigned char *src, u16 len)
4176 { 4176 {
4177 int i; 4177 int i;
4178 atmel_writeAR(dev, dest); 4178 atmel_writeAR(dev, dest);
4179 if (dest % 2) { 4179 if (dest % 2) {
4180 atmel_write8(dev, DR, *src); 4180 atmel_write8(dev, DR, *src);
4181 src++; len--; 4181 src++; len--;
4182 } 4182 }
4183 for (i = len; i > 1 ; i -= 2) { 4183 for (i = len; i > 1 ; i -= 2) {
4184 u8 lb = *src++; 4184 u8 lb = *src++;
4185 u8 hb = *src++; 4185 u8 hb = *src++;
4186 atmel_write16(dev, DR, lb | (hb << 8)); 4186 atmel_write16(dev, DR, lb | (hb << 8));
4187 } 4187 }
4188 if (i) 4188 if (i)
4189 atmel_write8(dev, DR, *src); 4189 atmel_write8(dev, DR, *src);
4190 } 4190 }
4191 4191
4192 static void atmel_copy_to_host(struct net_device *dev, unsigned char *dest, 4192 static void atmel_copy_to_host(struct net_device *dev, unsigned char *dest,
4193 u16 src, u16 len) 4193 u16 src, u16 len)
4194 { 4194 {
4195 int i; 4195 int i;
4196 atmel_writeAR(dev, src); 4196 atmel_writeAR(dev, src);
4197 if (src % 2) { 4197 if (src % 2) {
4198 *dest = atmel_read8(dev, DR); 4198 *dest = atmel_read8(dev, DR);
4199 dest++; len--; 4199 dest++; len--;
4200 } 4200 }
4201 for (i = len; i > 1 ; i -= 2) { 4201 for (i = len; i > 1 ; i -= 2) {
4202 u16 hw = atmel_read16(dev, DR); 4202 u16 hw = atmel_read16(dev, DR);
4203 *dest++ = hw; 4203 *dest++ = hw;
4204 *dest++ = hw >> 8; 4204 *dest++ = hw >> 8;
4205 } 4205 }
4206 if (i) 4206 if (i)
4207 *dest = atmel_read8(dev, DR); 4207 *dest = atmel_read8(dev, DR);
4208 } 4208 }
4209 4209
4210 static void atmel_set_gcr(struct net_device *dev, u16 mask) 4210 static void atmel_set_gcr(struct net_device *dev, u16 mask)
4211 { 4211 {
4212 outw(inw(dev->base_addr + GCR) | mask, dev->base_addr + GCR); 4212 outw(inw(dev->base_addr + GCR) | mask, dev->base_addr + GCR);
4213 } 4213 }
4214 4214
4215 static void atmel_clear_gcr(struct net_device *dev, u16 mask) 4215 static void atmel_clear_gcr(struct net_device *dev, u16 mask)
4216 { 4216 {
4217 outw(inw(dev->base_addr + GCR) & ~mask, dev->base_addr + GCR); 4217 outw(inw(dev->base_addr + GCR) & ~mask, dev->base_addr + GCR);
4218 } 4218 }
4219 4219
4220 static int atmel_lock_mac(struct atmel_private *priv) 4220 static int atmel_lock_mac(struct atmel_private *priv)
4221 { 4221 {
4222 int i, j = 20; 4222 int i, j = 20;
4223 retry: 4223 retry:
4224 for (i = 5000; i; i--) { 4224 for (i = 5000; i; i--) {
4225 if (!atmel_rmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_HOST_OFFSET))) 4225 if (!atmel_rmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_HOST_OFFSET)))
4226 break; 4226 break;
4227 udelay(20); 4227 udelay(20);
4228 } 4228 }
4229 4229
4230 if (!i) 4230 if (!i)
4231 return 0; /* timed out */ 4231 return 0; /* timed out */
4232 4232
4233 atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 1); 4233 atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 1);
4234 if (atmel_rmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_HOST_OFFSET))) { 4234 if (atmel_rmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_HOST_OFFSET))) {
4235 atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 0); 4235 atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 0);
4236 if (!j--) 4236 if (!j--)
4237 return 0; /* timed out */ 4237 return 0; /* timed out */
4238 goto retry; 4238 goto retry;
4239 } 4239 }
4240 4240
4241 return 1; 4241 return 1;
4242 } 4242 }
4243 4243
4244 static void atmel_wmem32(struct atmel_private *priv, u16 pos, u32 data) 4244 static void atmel_wmem32(struct atmel_private *priv, u16 pos, u32 data)
4245 { 4245 {
4246 atmel_writeAR(priv->dev, pos); 4246 atmel_writeAR(priv->dev, pos);
4247 atmel_write16(priv->dev, DR, data); /* card is little-endian */ 4247 atmel_write16(priv->dev, DR, data); /* card is little-endian */
4248 atmel_write16(priv->dev, DR, data >> 16); 4248 atmel_write16(priv->dev, DR, data >> 16);
4249 } 4249 }
4250 4250
4251 /***************************************************************************/ 4251 /***************************************************************************/
4252 /* There follows the source form of the MAC address reading firmware */ 4252 /* There follows the source form of the MAC address reading firmware */
4253 /***************************************************************************/ 4253 /***************************************************************************/
4254 #if 0 4254 #if 0
4255 4255
4256 /* Copyright 2003 Matthew T. Russotto */ 4256 /* Copyright 2003 Matthew T. Russotto */
4257 /* But derived from the Atmel 76C502 firmware written by Atmel and */ 4257 /* But derived from the Atmel 76C502 firmware written by Atmel and */
4258 /* included in "atmel wireless lan drivers" package */ 4258 /* included in "atmel wireless lan drivers" package */
4259 /** 4259 /**
4260 This file is part of net.russotto.AtmelMACFW, hereto referred to 4260 This file is part of net.russotto.AtmelMACFW, hereto referred to
4261 as AtmelMACFW 4261 as AtmelMACFW
4262 4262
4263 AtmelMACFW is free software; you can redistribute it and/or modify 4263 AtmelMACFW is free software; you can redistribute it and/or modify
4264 it under the terms of the GNU General Public License version 2 4264 it under the terms of the GNU General Public License version 2
4265 as published by the Free Software Foundation. 4265 as published by the Free Software Foundation.
4266 4266
4267 AtmelMACFW is distributed in the hope that it will be useful, 4267 AtmelMACFW is distributed in the hope that it will be useful,
4268 but WITHOUT ANY WARRANTY; without even the implied warranty of 4268 but WITHOUT ANY WARRANTY; without even the implied warranty of
4269 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 4269 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4270 GNU General Public License for more details. 4270 GNU General Public License for more details.
4271 4271
4272 You should have received a copy of the GNU General Public License 4272 You should have received a copy of the GNU General Public License
4273 along with AtmelMACFW; if not, write to the Free Software 4273 along with AtmelMACFW; if not, write to the Free Software
4274 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 4274 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
4275 4275
4276 ****************************************************************************/ 4276 ****************************************************************************/
4277 /* This firmware should work on the 76C502 RFMD, RFMD_D, and RFMD_E */ 4277 /* This firmware should work on the 76C502 RFMD, RFMD_D, and RFMD_E */
4278 /* It will probably work on the 76C504 and 76C502 RFMD_3COM */ 4278 /* It will probably work on the 76C504 and 76C502 RFMD_3COM */
4279 /* It only works on SPI EEPROM versions of the card. */ 4279 /* It only works on SPI EEPROM versions of the card. */
4280 4280
4281 /* This firmware initializes the SPI controller and clock, reads the MAC */ 4281 /* This firmware initializes the SPI controller and clock, reads the MAC */
4282 /* address from the EEPROM into SRAM, and puts the SRAM offset of the MAC */ 4282 /* address from the EEPROM into SRAM, and puts the SRAM offset of the MAC */
4283 /* address in MR2, and sets MR3 to 0x10 to indicate it is done */ 4283 /* address in MR2, and sets MR3 to 0x10 to indicate it is done */
4284 /* It also puts a complete copy of the EEPROM in SRAM with the offset in */ 4284 /* It also puts a complete copy of the EEPROM in SRAM with the offset in */
4285 /* MR4, for investigational purposes (maybe we can determine chip type */ 4285 /* MR4, for investigational purposes (maybe we can determine chip type */
4286 /* from that?) */ 4286 /* from that?) */
4287 4287
4288 .org 0 4288 .org 0
4289 .set MRBASE, 0x8000000 4289 .set MRBASE, 0x8000000
4290 .set CPSR_INITIAL, 0xD3 /* IRQ/FIQ disabled, ARM mode, Supervisor state */ 4290 .set CPSR_INITIAL, 0xD3 /* IRQ/FIQ disabled, ARM mode, Supervisor state */
4291 .set CPSR_USER, 0xD1 /* IRQ/FIQ disabled, ARM mode, USER state */ 4291 .set CPSR_USER, 0xD1 /* IRQ/FIQ disabled, ARM mode, USER state */
4292 .set SRAM_BASE, 0x02000000 4292 .set SRAM_BASE, 0x02000000
4293 .set SP_BASE, 0x0F300000 4293 .set SP_BASE, 0x0F300000
4294 .set UNK_BASE, 0x0F000000 /* Some internal device, but which one? */ 4294 .set UNK_BASE, 0x0F000000 /* Some internal device, but which one? */
4295 .set SPI_CGEN_BASE, 0x0E000000 /* Some internal device, but which one? */ 4295 .set SPI_CGEN_BASE, 0x0E000000 /* Some internal device, but which one? */
4296 .set UNK3_BASE, 0x02014000 /* Some internal device, but which one? */ 4296 .set UNK3_BASE, 0x02014000 /* Some internal device, but which one? */
4297 .set STACK_BASE, 0x5600 4297 .set STACK_BASE, 0x5600
4298 .set SP_SR, 0x10 4298 .set SP_SR, 0x10
4299 .set SP_TDRE, 2 /* status register bit -- TDR empty */ 4299 .set SP_TDRE, 2 /* status register bit -- TDR empty */
4300 .set SP_RDRF, 1 /* status register bit -- RDR full */ 4300 .set SP_RDRF, 1 /* status register bit -- RDR full */
4301 .set SP_SWRST, 0x80 4301 .set SP_SWRST, 0x80
4302 .set SP_SPIEN, 0x1 4302 .set SP_SPIEN, 0x1
4303 .set SP_CR, 0 /* control register */ 4303 .set SP_CR, 0 /* control register */
4304 .set SP_MR, 4 /* mode register */ 4304 .set SP_MR, 4 /* mode register */
4305 .set SP_RDR, 0x08 /* Read Data Register */ 4305 .set SP_RDR, 0x08 /* Read Data Register */
4306 .set SP_TDR, 0x0C /* Transmit Data Register */ 4306 .set SP_TDR, 0x0C /* Transmit Data Register */
4307 .set SP_CSR0, 0x30 /* chip select registers */ 4307 .set SP_CSR0, 0x30 /* chip select registers */
4308 .set SP_CSR1, 0x34 4308 .set SP_CSR1, 0x34
4309 .set SP_CSR2, 0x38 4309 .set SP_CSR2, 0x38
4310 .set SP_CSR3, 0x3C 4310 .set SP_CSR3, 0x3C
4311 .set NVRAM_CMD_RDSR, 5 /* read status register */ 4311 .set NVRAM_CMD_RDSR, 5 /* read status register */
4312 .set NVRAM_CMD_READ, 3 /* read data */ 4312 .set NVRAM_CMD_READ, 3 /* read data */
4313 .set NVRAM_SR_RDY, 1 /* RDY bit. This bit is inverted */ 4313 .set NVRAM_SR_RDY, 1 /* RDY bit. This bit is inverted */
4314 .set SPI_8CLOCKS, 0xFF /* Writing this to the TDR doesn't do anything to the 4314 .set SPI_8CLOCKS, 0xFF /* Writing this to the TDR doesn't do anything to the
4315 serial output, since SO is normally high. But it 4315 serial output, since SO is normally high. But it
4316 does cause 8 clock cycles and thus 8 bits to be 4316 does cause 8 clock cycles and thus 8 bits to be
4317 clocked in to the chip. See Atmel's SPI 4317 clocked in to the chip. See Atmel's SPI
4318 controller (e.g. AT91M55800) timing and 4K 4318 controller (e.g. AT91M55800) timing and 4K
4319 SPI EEPROM manuals */ 4319 SPI EEPROM manuals */
4320 4320
4321 .set NVRAM_SCRATCH, 0x02000100 /* arbitrary area for scratchpad memory */ 4321 .set NVRAM_SCRATCH, 0x02000100 /* arbitrary area for scratchpad memory */
4322 .set NVRAM_IMAGE, 0x02000200 4322 .set NVRAM_IMAGE, 0x02000200
4323 .set NVRAM_LENGTH, 0x0200 4323 .set NVRAM_LENGTH, 0x0200
4324 .set MAC_ADDRESS_MIB, SRAM_BASE 4324 .set MAC_ADDRESS_MIB, SRAM_BASE
4325 .set MAC_ADDRESS_LENGTH, 6 4325 .set MAC_ADDRESS_LENGTH, 6
4326 .set MAC_BOOT_FLAG, 0x10 4326 .set MAC_BOOT_FLAG, 0x10
4327 .set MR1, 0 4327 .set MR1, 0
4328 .set MR2, 4 4328 .set MR2, 4
4329 .set MR3, 8 4329 .set MR3, 8
4330 .set MR4, 0xC 4330 .set MR4, 0xC
4331 RESET_VECTOR: 4331 RESET_VECTOR:
4332 b RESET_HANDLER 4332 b RESET_HANDLER
4333 UNDEF_VECTOR: 4333 UNDEF_VECTOR:
4334 b HALT1 4334 b HALT1
4335 SWI_VECTOR: 4335 SWI_VECTOR:
4336 b HALT1 4336 b HALT1
4337 IABORT_VECTOR: 4337 IABORT_VECTOR:
4338 b HALT1 4338 b HALT1
4339 DABORT_VECTOR: 4339 DABORT_VECTOR:
4340 RESERVED_VECTOR: 4340 RESERVED_VECTOR:
4341 b HALT1 4341 b HALT1
4342 IRQ_VECTOR: 4342 IRQ_VECTOR:
4343 b HALT1 4343 b HALT1
4344 FIQ_VECTOR: 4344 FIQ_VECTOR:
4345 b HALT1 4345 b HALT1
4346 HALT1: b HALT1 4346 HALT1: b HALT1
4347 RESET_HANDLER: 4347 RESET_HANDLER:
4348 mov r0, #CPSR_INITIAL 4348 mov r0, #CPSR_INITIAL
4349 msr CPSR_c, r0 /* This is probably unnecessary */ 4349 msr CPSR_c, r0 /* This is probably unnecessary */
4350 4350
4351 /* I'm guessing this is initializing clock generator electronics for SPI */ 4351 /* I'm guessing this is initializing clock generator electronics for SPI */
4352 ldr r0, =SPI_CGEN_BASE 4352 ldr r0, =SPI_CGEN_BASE
4353 mov r1, #0 4353 mov r1, #0
4354 mov r1, r1, lsl #3 4354 mov r1, r1, lsl #3
4355 orr r1, r1, #0 4355 orr r1, r1, #0
4356 str r1, [r0] 4356 str r1, [r0]
4357 ldr r1, [r0, #28] 4357 ldr r1, [r0, #28]
4358 bic r1, r1, #16 4358 bic r1, r1, #16
4359 str r1, [r0, #28] 4359 str r1, [r0, #28]
4360 mov r1, #1 4360 mov r1, #1
4361 str r1, [r0, #8] 4361 str r1, [r0, #8]
4362 4362
4363 ldr r0, =MRBASE 4363 ldr r0, =MRBASE
4364 mov r1, #0 4364 mov r1, #0
4365 strh r1, [r0, #MR1] 4365 strh r1, [r0, #MR1]
4366 strh r1, [r0, #MR2] 4366 strh r1, [r0, #MR2]
4367 strh r1, [r0, #MR3] 4367 strh r1, [r0, #MR3]
4368 strh r1, [r0, #MR4] 4368 strh r1, [r0, #MR4]
4369 4369
4370 mov sp, #STACK_BASE 4370 mov sp, #STACK_BASE
4371 bl SP_INIT 4371 bl SP_INIT
4372 mov r0, #10 4372 mov r0, #10
4373 bl DELAY9 4373 bl DELAY9
4374 bl GET_MAC_ADDR 4374 bl GET_MAC_ADDR
4375 bl GET_WHOLE_NVRAM 4375 bl GET_WHOLE_NVRAM
4376 ldr r0, =MRBASE 4376 ldr r0, =MRBASE
4377 ldr r1, =MAC_ADDRESS_MIB 4377 ldr r1, =MAC_ADDRESS_MIB
4378 strh r1, [r0, #MR2] 4378 strh r1, [r0, #MR2]
4379 ldr r1, =NVRAM_IMAGE 4379 ldr r1, =NVRAM_IMAGE
4380 strh r1, [r0, #MR4] 4380 strh r1, [r0, #MR4]
4381 mov r1, #MAC_BOOT_FLAG 4381 mov r1, #MAC_BOOT_FLAG
4382 strh r1, [r0, #MR3] 4382 strh r1, [r0, #MR3]
4383 HALT2: b HALT2 4383 HALT2: b HALT2
4384 .func Get_Whole_NVRAM, GET_WHOLE_NVRAM 4384 .func Get_Whole_NVRAM, GET_WHOLE_NVRAM
4385 GET_WHOLE_NVRAM: 4385 GET_WHOLE_NVRAM:
4386 stmdb sp!, {lr} 4386 stmdb sp!, {lr}
4387 mov r2, #0 /* 0th bytes of NVRAM */ 4387 mov r2, #0 /* 0th bytes of NVRAM */
4388 mov r3, #NVRAM_LENGTH 4388 mov r3, #NVRAM_LENGTH
4389 mov r1, #0 /* not used in routine */ 4389 mov r1, #0 /* not used in routine */
4390 ldr r0, =NVRAM_IMAGE 4390 ldr r0, =NVRAM_IMAGE
4391 bl NVRAM_XFER 4391 bl NVRAM_XFER
4392 ldmia sp!, {lr} 4392 ldmia sp!, {lr}
4393 bx lr 4393 bx lr
4394 .endfunc 4394 .endfunc
4395 4395
4396 .func Get_MAC_Addr, GET_MAC_ADDR 4396 .func Get_MAC_Addr, GET_MAC_ADDR
4397 GET_MAC_ADDR: 4397 GET_MAC_ADDR:
4398 stmdb sp!, {lr} 4398 stmdb sp!, {lr}
4399 mov r2, #0x120 /* address of MAC Address within NVRAM */ 4399 mov r2, #0x120 /* address of MAC Address within NVRAM */
4400 mov r3, #MAC_ADDRESS_LENGTH 4400 mov r3, #MAC_ADDRESS_LENGTH
4401 mov r1, #0 /* not used in routine */ 4401 mov r1, #0 /* not used in routine */
4402 ldr r0, =MAC_ADDRESS_MIB 4402 ldr r0, =MAC_ADDRESS_MIB
4403 bl NVRAM_XFER 4403 bl NVRAM_XFER
4404 ldmia sp!, {lr} 4404 ldmia sp!, {lr}
4405 bx lr 4405 bx lr
4406 .endfunc 4406 .endfunc
4407 .ltorg 4407 .ltorg
4408 .func Delay9, DELAY9 4408 .func Delay9, DELAY9
4409 DELAY9: 4409 DELAY9:
4410 adds r0, r0, r0, LSL #3 /* r0 = r0 * 9 */ 4410 adds r0, r0, r0, LSL #3 /* r0 = r0 * 9 */
4411 DELAYLOOP: 4411 DELAYLOOP:
4412 beq DELAY9_done 4412 beq DELAY9_done
4413 subs r0, r0, #1 4413 subs r0, r0, #1
4414 b DELAYLOOP 4414 b DELAYLOOP
4415 DELAY9_done: 4415 DELAY9_done:
4416 bx lr 4416 bx lr
4417 .endfunc 4417 .endfunc
4418 4418
4419 .func SP_Init, SP_INIT 4419 .func SP_Init, SP_INIT
4420 SP_INIT: 4420 SP_INIT:
4421 mov r1, #SP_SWRST 4421 mov r1, #SP_SWRST
4422 ldr r0, =SP_BASE 4422 ldr r0, =SP_BASE
4423 str r1, [r0, #SP_CR] /* reset the SPI */ 4423 str r1, [r0, #SP_CR] /* reset the SPI */
4424 mov r1, #0 4424 mov r1, #0
4425 str r1, [r0, #SP_CR] /* release SPI from reset state */ 4425 str r1, [r0, #SP_CR] /* release SPI from reset state */
4426 mov r1, #SP_SPIEN 4426 mov r1, #SP_SPIEN
4427 str r1, [r0, #SP_MR] /* set the SPI to MASTER mode*/ 4427 str r1, [r0, #SP_MR] /* set the SPI to MASTER mode*/
4428 str r1, [r0, #SP_CR] /* enable the SPI */ 4428 str r1, [r0, #SP_CR] /* enable the SPI */
4429 4429
4430 /* My guess would be this turns on the SPI clock */ 4430 /* My guess would be this turns on the SPI clock */
4431 ldr r3, =SPI_CGEN_BASE 4431 ldr r3, =SPI_CGEN_BASE
4432 ldr r1, [r3, #28] 4432 ldr r1, [r3, #28]
4433 orr r1, r1, #0x2000 4433 orr r1, r1, #0x2000
4434 str r1, [r3, #28] 4434 str r1, [r3, #28]
4435 4435
4436 ldr r1, =0x2000c01 4436 ldr r1, =0x2000c01
4437 str r1, [r0, #SP_CSR0] 4437 str r1, [r0, #SP_CSR0]
4438 ldr r1, =0x2000201 4438 ldr r1, =0x2000201
4439 str r1, [r0, #SP_CSR1] 4439 str r1, [r0, #SP_CSR1]
4440 str r1, [r0, #SP_CSR2] 4440 str r1, [r0, #SP_CSR2]
4441 str r1, [r0, #SP_CSR3] 4441 str r1, [r0, #SP_CSR3]
4442 ldr r1, [r0, #SP_SR] 4442 ldr r1, [r0, #SP_SR]
4443 ldr r0, [r0, #SP_RDR] 4443 ldr r0, [r0, #SP_RDR]
4444 bx lr 4444 bx lr
4445 .endfunc 4445 .endfunc
4446 .func NVRAM_Init, NVRAM_INIT 4446 .func NVRAM_Init, NVRAM_INIT
4447 NVRAM_INIT: 4447 NVRAM_INIT:
4448 ldr r1, =SP_BASE 4448 ldr r1, =SP_BASE
4449 ldr r0, [r1, #SP_RDR] 4449 ldr r0, [r1, #SP_RDR]
4450 mov r0, #NVRAM_CMD_RDSR 4450 mov r0, #NVRAM_CMD_RDSR
4451 str r0, [r1, #SP_TDR] 4451 str r0, [r1, #SP_TDR]
4452 SP_loop1: 4452 SP_loop1:
4453 ldr r0, [r1, #SP_SR] 4453 ldr r0, [r1, #SP_SR]
4454 tst r0, #SP_TDRE 4454 tst r0, #SP_TDRE
4455 beq SP_loop1 4455 beq SP_loop1
4456 4456
4457 mov r0, #SPI_8CLOCKS 4457 mov r0, #SPI_8CLOCKS
4458 str r0, [r1, #SP_TDR] 4458 str r0, [r1, #SP_TDR]
4459 SP_loop2: 4459 SP_loop2:
4460 ldr r0, [r1, #SP_SR] 4460 ldr r0, [r1, #SP_SR]
4461 tst r0, #SP_TDRE 4461 tst r0, #SP_TDRE
4462 beq SP_loop2 4462 beq SP_loop2
4463 4463
4464 ldr r0, [r1, #SP_RDR] 4464 ldr r0, [r1, #SP_RDR]
4465 SP_loop3: 4465 SP_loop3:
4466 ldr r0, [r1, #SP_SR] 4466 ldr r0, [r1, #SP_SR]
4467 tst r0, #SP_RDRF 4467 tst r0, #SP_RDRF
4468 beq SP_loop3 4468 beq SP_loop3
4469 4469
4470 ldr r0, [r1, #SP_RDR] 4470 ldr r0, [r1, #SP_RDR]
4471 and r0, r0, #255 4471 and r0, r0, #255
4472 bx lr 4472 bx lr
4473 .endfunc 4473 .endfunc
4474 4474
4475 .func NVRAM_Xfer, NVRAM_XFER 4475 .func NVRAM_Xfer, NVRAM_XFER
4476 /* r0 = dest address */ 4476 /* r0 = dest address */
4477 /* r1 = not used */ 4477 /* r1 = not used */
4478 /* r2 = src address within NVRAM */ 4478 /* r2 = src address within NVRAM */
4479 /* r3 = length */ 4479 /* r3 = length */
4480 NVRAM_XFER: 4480 NVRAM_XFER:
4481 stmdb sp!, {r4, r5, lr} 4481 stmdb sp!, {r4, r5, lr}
4482 mov r5, r0 /* save r0 (dest address) */ 4482 mov r5, r0 /* save r0 (dest address) */
4483 mov r4, r3 /* save r3 (length) */ 4483 mov r4, r3 /* save r3 (length) */
4484 mov r0, r2, LSR #5 /* SPI memories put A8 in the command field */ 4484 mov r0, r2, LSR #5 /* SPI memories put A8 in the command field */
4485 and r0, r0, #8 4485 and r0, r0, #8
4486 add r0, r0, #NVRAM_CMD_READ 4486 add r0, r0, #NVRAM_CMD_READ
4487 ldr r1, =NVRAM_SCRATCH 4487 ldr r1, =NVRAM_SCRATCH
4488 strb r0, [r1, #0] /* save command in NVRAM_SCRATCH[0] */ 4488 strb r0, [r1, #0] /* save command in NVRAM_SCRATCH[0] */
4489 strb r2, [r1, #1] /* save low byte of source address in NVRAM_SCRATCH[1] */ 4489 strb r2, [r1, #1] /* save low byte of source address in NVRAM_SCRATCH[1] */
4490 _local1: 4490 _local1:
4491 bl NVRAM_INIT 4491 bl NVRAM_INIT
4492 tst r0, #NVRAM_SR_RDY 4492 tst r0, #NVRAM_SR_RDY
4493 bne _local1 4493 bne _local1
4494 mov r0, #20 4494 mov r0, #20
4495 bl DELAY9 4495 bl DELAY9
4496 mov r2, r4 /* length */ 4496 mov r2, r4 /* length */
4497 mov r1, r5 /* dest address */ 4497 mov r1, r5 /* dest address */
4498 mov r0, #2 /* bytes to transfer in command */ 4498 mov r0, #2 /* bytes to transfer in command */
4499 bl NVRAM_XFER2 4499 bl NVRAM_XFER2
4500 ldmia sp!, {r4, r5, lr} 4500 ldmia sp!, {r4, r5, lr}
4501 bx lr 4501 bx lr
4502 .endfunc 4502 .endfunc
4503 4503
4504 .func NVRAM_Xfer2, NVRAM_XFER2 4504 .func NVRAM_Xfer2, NVRAM_XFER2
4505 NVRAM_XFER2: 4505 NVRAM_XFER2:
4506 stmdb sp!, {r4, r5, r6, lr} 4506 stmdb sp!, {r4, r5, r6, lr}
4507 ldr r4, =SP_BASE 4507 ldr r4, =SP_BASE
4508 mov r3, #0 4508 mov r3, #0
4509 cmp r0, #0 4509 cmp r0, #0
4510 bls _local2 4510 bls _local2
4511 ldr r5, =NVRAM_SCRATCH 4511 ldr r5, =NVRAM_SCRATCH
4512 _local4: 4512 _local4:
4513 ldrb r6, [r5, r3] 4513 ldrb r6, [r5, r3]
4514 str r6, [r4, #SP_TDR] 4514 str r6, [r4, #SP_TDR]
4515 _local3: 4515 _local3:
4516 ldr r6, [r4, #SP_SR] 4516 ldr r6, [r4, #SP_SR]
4517 tst r6, #SP_TDRE 4517 tst r6, #SP_TDRE
4518 beq _local3 4518 beq _local3
4519 add r3, r3, #1 4519 add r3, r3, #1
4520 cmp r3, r0 /* r0 is # of bytes to send out (command+addr) */ 4520 cmp r3, r0 /* r0 is # of bytes to send out (command+addr) */
4521 blo _local4 4521 blo _local4
4522 _local2: 4522 _local2:
4523 mov r3, #SPI_8CLOCKS 4523 mov r3, #SPI_8CLOCKS
4524 str r3, [r4, #SP_TDR] 4524 str r3, [r4, #SP_TDR]
4525 ldr r0, [r4, #SP_RDR] 4525 ldr r0, [r4, #SP_RDR]
4526 _local5: 4526 _local5:
4527 ldr r0, [r4, #SP_SR] 4527 ldr r0, [r4, #SP_SR]
4528 tst r0, #SP_RDRF 4528 tst r0, #SP_RDRF
4529 beq _local5 4529 beq _local5
4530 ldr r0, [r4, #SP_RDR] /* what's this byte? It's the byte read while writing the TDR -- nonsense, because the NVRAM doesn't read and write at the same time */ 4530 ldr r0, [r4, #SP_RDR] /* what's this byte? It's the byte read while writing the TDR -- nonsense, because the NVRAM doesn't read and write at the same time */
4531 mov r0, #0 4531 mov r0, #0
4532 cmp r2, #0 /* r2 is # of bytes to copy in */ 4532 cmp r2, #0 /* r2 is # of bytes to copy in */
4533 bls _local6 4533 bls _local6
4534 _local7: 4534 _local7:
4535 ldr r5, [r4, #SP_SR] 4535 ldr r5, [r4, #SP_SR]
4536 tst r5, #SP_TDRE 4536 tst r5, #SP_TDRE
4537 beq _local7 4537 beq _local7
4538 str r3, [r4, #SP_TDR] /* r3 has SPI_8CLOCKS */ 4538 str r3, [r4, #SP_TDR] /* r3 has SPI_8CLOCKS */
4539 _local8: 4539 _local8:
4540 ldr r5, [r4, #SP_SR] 4540 ldr r5, [r4, #SP_SR]
4541 tst r5, #SP_RDRF 4541 tst r5, #SP_RDRF
4542 beq _local8 4542 beq _local8
4543 ldr r5, [r4, #SP_RDR] /* but didn't we read this byte above? */ 4543 ldr r5, [r4, #SP_RDR] /* but didn't we read this byte above? */
4544 strb r5, [r1], #1 /* postindexed */ 4544 strb r5, [r1], #1 /* postindexed */
4545 add r0, r0, #1 4545 add r0, r0, #1
4546 cmp r0, r2 4546 cmp r0, r2
4547 blo _local7 /* since we don't send another address, the NVRAM must be capable of sequential reads */ 4547 blo _local7 /* since we don't send another address, the NVRAM must be capable of sequential reads */
4548 _local6: 4548 _local6:
4549 mov r0, #200 4549 mov r0, #200
4550 bl DELAY9 4550 bl DELAY9
4551 ldmia sp!, {r4, r5, r6, lr} 4551 ldmia sp!, {r4, r5, r6, lr}
4552 bx lr 4552 bx lr
4553 #endif 4553 #endif
4554 4554
drivers/usb/host/xhci.h
1 /* 1 /*
2 * xHCI host controller driver 2 * xHCI host controller driver
3 * 3 *
4 * Copyright (C) 2008 Intel Corp. 4 * Copyright (C) 2008 Intel Corp.
5 * 5 *
6 * Author: Sarah Sharp 6 * Author: Sarah Sharp
7 * Some code borrowed from the Linux EHCI driver. 7 * Some code borrowed from the Linux EHCI driver.
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as 10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation. 11 * published by the Free Software Foundation.
12 * 12 *
13 * This program is distributed in the hope that it will be useful, but 13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 * for more details. 16 * for more details.
17 * 17 *
18 * You should have received a copy of the GNU General Public License 18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software Foundation, 19 * along with this program; if not, write to the Free Software Foundation,
20 * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */ 21 */
22 22
23 #ifndef __LINUX_XHCI_HCD_H 23 #ifndef __LINUX_XHCI_HCD_H
24 #define __LINUX_XHCI_HCD_H 24 #define __LINUX_XHCI_HCD_H
25 25
26 #include <linux/usb.h> 26 #include <linux/usb.h>
27 #include <linux/timer.h> 27 #include <linux/timer.h>
28 #include <linux/kernel.h> 28 #include <linux/kernel.h>
29 29
30 #include "../core/hcd.h" 30 #include "../core/hcd.h"
31 /* Code sharing between pci-quirks and xhci hcd */ 31 /* Code sharing between pci-quirks and xhci hcd */
32 #include "xhci-ext-caps.h" 32 #include "xhci-ext-caps.h"
33 33
34 /* xHCI PCI Configuration Registers */ 34 /* xHCI PCI Configuration Registers */
35 #define XHCI_SBRN_OFFSET (0x60) 35 #define XHCI_SBRN_OFFSET (0x60)
36 36
37 /* Max number of USB devices for any host controller - limit in section 6.1 */ 37 /* Max number of USB devices for any host controller - limit in section 6.1 */
38 #define MAX_HC_SLOTS 256 38 #define MAX_HC_SLOTS 256
39 /* Section 5.3.3 - MaxPorts */ 39 /* Section 5.3.3 - MaxPorts */
40 #define MAX_HC_PORTS 127 40 #define MAX_HC_PORTS 127
41 41
42 /* 42 /*
43 * xHCI register interface. 43 * xHCI register interface.
44 * This corresponds to the eXtensible Host Controller Interface (xHCI) 44 * This corresponds to the eXtensible Host Controller Interface (xHCI)
45 * Revision 0.95 specification 45 * Revision 0.95 specification
46 */ 46 */
47 47
48 /** 48 /**
49 * struct xhci_cap_regs - xHCI Host Controller Capability Registers. 49 * struct xhci_cap_regs - xHCI Host Controller Capability Registers.
50 * @hc_capbase: length of the capabilities register and HC version number 50 * @hc_capbase: length of the capabilities register and HC version number
51 * @hcs_params1: HCSPARAMS1 - Structural Parameters 1 51 * @hcs_params1: HCSPARAMS1 - Structural Parameters 1
52 * @hcs_params2: HCSPARAMS2 - Structural Parameters 2 52 * @hcs_params2: HCSPARAMS2 - Structural Parameters 2
53 * @hcs_params3: HCSPARAMS3 - Structural Parameters 3 53 * @hcs_params3: HCSPARAMS3 - Structural Parameters 3
54 * @hcc_params: HCCPARAMS - Capability Parameters 54 * @hcc_params: HCCPARAMS - Capability Parameters
55 * @db_off: DBOFF - Doorbell array offset 55 * @db_off: DBOFF - Doorbell array offset
56 * @run_regs_off: RTSOFF - Runtime register space offset 56 * @run_regs_off: RTSOFF - Runtime register space offset
57 */ 57 */
58 struct xhci_cap_regs { 58 struct xhci_cap_regs {
59 u32 hc_capbase; 59 u32 hc_capbase;
60 u32 hcs_params1; 60 u32 hcs_params1;
61 u32 hcs_params2; 61 u32 hcs_params2;
62 u32 hcs_params3; 62 u32 hcs_params3;
63 u32 hcc_params; 63 u32 hcc_params;
64 u32 db_off; 64 u32 db_off;
65 u32 run_regs_off; 65 u32 run_regs_off;
66 /* Reserved up to (CAPLENGTH - 0x1C) */ 66 /* Reserved up to (CAPLENGTH - 0x1C) */
67 }; 67 };
68 68
69 /* hc_capbase bitmasks */ 69 /* hc_capbase bitmasks */
70 /* bits 7:0 - how long is the Capabilities register */ 70 /* bits 7:0 - how long is the Capabilities register */
71 #define HC_LENGTH(p) XHCI_HC_LENGTH(p) 71 #define HC_LENGTH(p) XHCI_HC_LENGTH(p)
72 /* bits 31:16 */ 72 /* bits 31:16 */
73 #define HC_VERSION(p) (((p) >> 16) & 0xffff) 73 #define HC_VERSION(p) (((p) >> 16) & 0xffff)
74 74
75 /* HCSPARAMS1 - hcs_params1 - bitmasks */ 75 /* HCSPARAMS1 - hcs_params1 - bitmasks */
76 /* bits 0:7, Max Device Slots */ 76 /* bits 0:7, Max Device Slots */
77 #define HCS_MAX_SLOTS(p) (((p) >> 0) & 0xff) 77 #define HCS_MAX_SLOTS(p) (((p) >> 0) & 0xff)
78 #define HCS_SLOTS_MASK 0xff 78 #define HCS_SLOTS_MASK 0xff
79 /* bits 8:18, Max Interrupters */ 79 /* bits 8:18, Max Interrupters */
80 #define HCS_MAX_INTRS(p) (((p) >> 8) & 0x7ff) 80 #define HCS_MAX_INTRS(p) (((p) >> 8) & 0x7ff)
81 /* bits 24:31, Max Ports - max value is 0x7F = 127 ports */ 81 /* bits 24:31, Max Ports - max value is 0x7F = 127 ports */
82 #define HCS_MAX_PORTS(p) (((p) >> 24) & 0x7f) 82 #define HCS_MAX_PORTS(p) (((p) >> 24) & 0x7f)
83 83
84 /* HCSPARAMS2 - hcs_params2 - bitmasks */ 84 /* HCSPARAMS2 - hcs_params2 - bitmasks */
85 /* bits 0:3, frames or uframes that SW needs to queue transactions 85 /* bits 0:3, frames or uframes that SW needs to queue transactions
86 * ahead of the HW to meet periodic deadlines */ 86 * ahead of the HW to meet periodic deadlines */
87 #define HCS_IST(p) (((p) >> 0) & 0xf) 87 #define HCS_IST(p) (((p) >> 0) & 0xf)
88 /* bits 4:7, max number of Event Ring segments */ 88 /* bits 4:7, max number of Event Ring segments */
89 #define HCS_ERST_MAX(p) (((p) >> 4) & 0xf) 89 #define HCS_ERST_MAX(p) (((p) >> 4) & 0xf)
90 /* bit 26 Scratchpad restore - for save/restore HW state - not used yet */ 90 /* bit 26 Scratchpad restore - for save/restore HW state - not used yet */
91 /* bits 27:31 number of Scratchpad buffers SW must allocate for the HW */ 91 /* bits 27:31 number of Scratchpad buffers SW must allocate for the HW */
92 #define HCS_MAX_SCRATCHPAD(p) (((p) >> 27) & 0x1f) 92 #define HCS_MAX_SCRATCHPAD(p) (((p) >> 27) & 0x1f)
93 93
94 /* HCSPARAMS3 - hcs_params3 - bitmasks */ 94 /* HCSPARAMS3 - hcs_params3 - bitmasks */
95 /* bits 0:7, Max U1 to U0 latency for the roothub ports */ 95 /* bits 0:7, Max U1 to U0 latency for the roothub ports */
96 #define HCS_U1_LATENCY(p) (((p) >> 0) & 0xff) 96 #define HCS_U1_LATENCY(p) (((p) >> 0) & 0xff)
97 /* bits 16:31, Max U2 to U0 latency for the roothub ports */ 97 /* bits 16:31, Max U2 to U0 latency for the roothub ports */
98 #define HCS_U2_LATENCY(p) (((p) >> 16) & 0xffff) 98 #define HCS_U2_LATENCY(p) (((p) >> 16) & 0xffff)
99 99
100 /* HCCPARAMS - hcc_params - bitmasks */ 100 /* HCCPARAMS - hcc_params - bitmasks */
101 /* true: HC can use 64-bit address pointers */ 101 /* true: HC can use 64-bit address pointers */
102 #define HCC_64BIT_ADDR(p) ((p) & (1 << 0)) 102 #define HCC_64BIT_ADDR(p) ((p) & (1 << 0))
103 /* true: HC can do bandwidth negotiation */ 103 /* true: HC can do bandwidth negotiation */
104 #define HCC_BANDWIDTH_NEG(p) ((p) & (1 << 1)) 104 #define HCC_BANDWIDTH_NEG(p) ((p) & (1 << 1))
105 /* true: HC uses 64-byte Device Context structures 105 /* true: HC uses 64-byte Device Context structures
106 * FIXME 64-byte context structures aren't supported yet. 106 * FIXME 64-byte context structures aren't supported yet.
107 */ 107 */
108 #define HCC_64BYTE_CONTEXT(p) ((p) & (1 << 2)) 108 #define HCC_64BYTE_CONTEXT(p) ((p) & (1 << 2))
109 /* true: HC has port power switches */ 109 /* true: HC has port power switches */
110 #define HCC_PPC(p) ((p) & (1 << 3)) 110 #define HCC_PPC(p) ((p) & (1 << 3))
111 /* true: HC has port indicators */ 111 /* true: HC has port indicators */
112 #define HCS_INDICATOR(p) ((p) & (1 << 4)) 112 #define HCS_INDICATOR(p) ((p) & (1 << 4))
113 /* true: HC has Light HC Reset Capability */ 113 /* true: HC has Light HC Reset Capability */
114 #define HCC_LIGHT_RESET(p) ((p) & (1 << 5)) 114 #define HCC_LIGHT_RESET(p) ((p) & (1 << 5))
115 /* true: HC supports latency tolerance messaging */ 115 /* true: HC supports latency tolerance messaging */
116 #define HCC_LTC(p) ((p) & (1 << 6)) 116 #define HCC_LTC(p) ((p) & (1 << 6))
117 /* true: no secondary Stream ID Support */ 117 /* true: no secondary Stream ID Support */
118 #define HCC_NSS(p) ((p) & (1 << 7)) 118 #define HCC_NSS(p) ((p) & (1 << 7))
119 /* Max size for Primary Stream Arrays - 2^(n+1), where n is bits 12:15 */ 119 /* Max size for Primary Stream Arrays - 2^(n+1), where n is bits 12:15 */
120 #define HCC_MAX_PSA (1 << ((((p) >> 12) & 0xf) + 1)) 120 #define HCC_MAX_PSA (1 << ((((p) >> 12) & 0xf) + 1))
121 /* Extended Capabilities pointer from PCI base - section 5.3.6 */ 121 /* Extended Capabilities pointer from PCI base - section 5.3.6 */
122 #define HCC_EXT_CAPS(p) XHCI_HCC_EXT_CAPS(p) 122 #define HCC_EXT_CAPS(p) XHCI_HCC_EXT_CAPS(p)
123 123
124 /* db_off bitmask - bits 0:1 reserved */ 124 /* db_off bitmask - bits 0:1 reserved */
125 #define DBOFF_MASK (~0x3) 125 #define DBOFF_MASK (~0x3)
126 126
127 /* run_regs_off bitmask - bits 0:4 reserved */ 127 /* run_regs_off bitmask - bits 0:4 reserved */
128 #define RTSOFF_MASK (~0x1f) 128 #define RTSOFF_MASK (~0x1f)
129 129
130 130
131 /* Number of registers per port */ 131 /* Number of registers per port */
132 #define NUM_PORT_REGS 4 132 #define NUM_PORT_REGS 4
133 133
134 /** 134 /**
135 * struct xhci_op_regs - xHCI Host Controller Operational Registers. 135 * struct xhci_op_regs - xHCI Host Controller Operational Registers.
136 * @command: USBCMD - xHC command register 136 * @command: USBCMD - xHC command register
137 * @status: USBSTS - xHC status register 137 * @status: USBSTS - xHC status register
138 * @page_size: This indicates the page size that the host controller 138 * @page_size: This indicates the page size that the host controller
139 * supports. If bit n is set, the HC supports a page size 139 * supports. If bit n is set, the HC supports a page size
140 * of 2^(n+12), up to a 128MB page size. 140 * of 2^(n+12), up to a 128MB page size.
141 * 4K is the minimum page size. 141 * 4K is the minimum page size.
142 * @cmd_ring: CRP - 64-bit Command Ring Pointer 142 * @cmd_ring: CRP - 64-bit Command Ring Pointer
143 * @dcbaa_ptr: DCBAAP - 64-bit Device Context Base Address Array Pointer 143 * @dcbaa_ptr: DCBAAP - 64-bit Device Context Base Address Array Pointer
144 * @config_reg: CONFIG - Configure Register 144 * @config_reg: CONFIG - Configure Register
145 * @port_status_base: PORTSCn - base address for Port Status and Control 145 * @port_status_base: PORTSCn - base address for Port Status and Control
146 * Each port has a Port Status and Control register, 146 * Each port has a Port Status and Control register,
147 * followed by a Port Power Management Status and Control 147 * followed by a Port Power Management Status and Control
148 * register, a Port Link Info register, and a reserved 148 * register, a Port Link Info register, and a reserved
149 * register. 149 * register.
150 * @port_power_base: PORTPMSCn - base address for 150 * @port_power_base: PORTPMSCn - base address for
151 * Port Power Management Status and Control 151 * Port Power Management Status and Control
152 * @port_link_base: PORTLIn - base address for Port Link Info (current 152 * @port_link_base: PORTLIn - base address for Port Link Info (current
153 * Link PM state and control) for USB 2.1 and USB 3.0 153 * Link PM state and control) for USB 2.1 and USB 3.0
154 * devices. 154 * devices.
155 */ 155 */
156 struct xhci_op_regs { 156 struct xhci_op_regs {
157 u32 command; 157 u32 command;
158 u32 status; 158 u32 status;
159 u32 page_size; 159 u32 page_size;
160 u32 reserved1; 160 u32 reserved1;
161 u32 reserved2; 161 u32 reserved2;
162 u32 dev_notification; 162 u32 dev_notification;
163 u64 cmd_ring; 163 u64 cmd_ring;
164 /* rsvd: offset 0x20-2F */ 164 /* rsvd: offset 0x20-2F */
165 u32 reserved3[4]; 165 u32 reserved3[4];
166 u64 dcbaa_ptr; 166 u64 dcbaa_ptr;
167 u32 config_reg; 167 u32 config_reg;
168 /* rsvd: offset 0x3C-3FF */ 168 /* rsvd: offset 0x3C-3FF */
169 u32 reserved4[241]; 169 u32 reserved4[241];
170 /* port 1 registers, which serve as a base address for other ports */ 170 /* port 1 registers, which serve as a base address for other ports */
171 u32 port_status_base; 171 u32 port_status_base;
172 u32 port_power_base; 172 u32 port_power_base;
173 u32 port_link_base; 173 u32 port_link_base;
174 u32 reserved5; 174 u32 reserved5;
175 /* registers for ports 2-255 */ 175 /* registers for ports 2-255 */
176 u32 reserved6[NUM_PORT_REGS*254]; 176 u32 reserved6[NUM_PORT_REGS*254];
177 }; 177 };
178 178
179 /* USBCMD - USB command - command bitmasks */ 179 /* USBCMD - USB command - command bitmasks */
180 /* start/stop HC execution - do not write unless HC is halted*/ 180 /* start/stop HC execution - do not write unless HC is halted*/
181 #define CMD_RUN XHCI_CMD_RUN 181 #define CMD_RUN XHCI_CMD_RUN
182 /* Reset HC - resets internal HC state machine and all registers (except 182 /* Reset HC - resets internal HC state machine and all registers (except
183 * PCI config regs). HC does NOT drive a USB reset on the downstream ports. 183 * PCI config regs). HC does NOT drive a USB reset on the downstream ports.
184 * The xHCI driver must reinitialize the xHC after setting this bit. 184 * The xHCI driver must reinitialize the xHC after setting this bit.
185 */ 185 */
186 #define CMD_RESET (1 << 1) 186 #define CMD_RESET (1 << 1)
187 /* Event Interrupt Enable - a '1' allows interrupts from the host controller */ 187 /* Event Interrupt Enable - a '1' allows interrupts from the host controller */
188 #define CMD_EIE XHCI_CMD_EIE 188 #define CMD_EIE XHCI_CMD_EIE
189 /* Host System Error Interrupt Enable - get out-of-band signal for HC errors */ 189 /* Host System Error Interrupt Enable - get out-of-band signal for HC errors */
190 #define CMD_HSEIE XHCI_CMD_HSEIE 190 #define CMD_HSEIE XHCI_CMD_HSEIE
191 /* bits 4:6 are reserved (and should be preserved on writes). */ 191 /* bits 4:6 are reserved (and should be preserved on writes). */
192 /* light reset (port status stays unchanged) - reset completed when this is 0 */ 192 /* light reset (port status stays unchanged) - reset completed when this is 0 */
193 #define CMD_LRESET (1 << 7) 193 #define CMD_LRESET (1 << 7)
194 /* FIXME: ignoring host controller save/restore state for now. */ 194 /* FIXME: ignoring host controller save/restore state for now. */
195 #define CMD_CSS (1 << 8) 195 #define CMD_CSS (1 << 8)
196 #define CMD_CRS (1 << 9) 196 #define CMD_CRS (1 << 9)
197 /* Enable Wrap Event - '1' means xHC generates an event when MFINDEX wraps. */ 197 /* Enable Wrap Event - '1' means xHC generates an event when MFINDEX wraps. */
198 #define CMD_EWE XHCI_CMD_EWE 198 #define CMD_EWE XHCI_CMD_EWE
199 /* MFINDEX power management - '1' means xHC can stop MFINDEX counter if all root 199 /* MFINDEX power management - '1' means xHC can stop MFINDEX counter if all root
200 * hubs are in U3 (selective suspend), disconnect, disabled, or powered-off. 200 * hubs are in U3 (selective suspend), disconnect, disabled, or powered-off.
201 * '0' means the xHC can power it off if all ports are in the disconnect, 201 * '0' means the xHC can power it off if all ports are in the disconnect,
202 * disabled, or powered-off state. 202 * disabled, or powered-off state.
203 */ 203 */
204 #define CMD_PM_INDEX (1 << 11) 204 #define CMD_PM_INDEX (1 << 11)
205 /* bits 12:31 are reserved (and should be preserved on writes). */ 205 /* bits 12:31 are reserved (and should be preserved on writes). */
206 206
207 /* USBSTS - USB status - status bitmasks */ 207 /* USBSTS - USB status - status bitmasks */
208 /* HC not running - set to 1 when run/stop bit is cleared. */ 208 /* HC not running - set to 1 when run/stop bit is cleared. */
209 #define STS_HALT XHCI_STS_HALT 209 #define STS_HALT XHCI_STS_HALT
210 /* serious error, e.g. PCI parity error. The HC will clear the run/stop bit. */ 210 /* serious error, e.g. PCI parity error. The HC will clear the run/stop bit. */
211 #define STS_FATAL (1 << 2) 211 #define STS_FATAL (1 << 2)
212 /* event interrupt - clear this prior to clearing any IP flags in IR set*/ 212 /* event interrupt - clear this prior to clearing any IP flags in IR set*/
213 #define STS_EINT (1 << 3) 213 #define STS_EINT (1 << 3)
214 /* port change detect */ 214 /* port change detect */
215 #define STS_PORT (1 << 4) 215 #define STS_PORT (1 << 4)
216 /* bits 5:7 reserved and zeroed */ 216 /* bits 5:7 reserved and zeroed */
217 /* save state status - '1' means xHC is saving state */ 217 /* save state status - '1' means xHC is saving state */
218 #define STS_SAVE (1 << 8) 218 #define STS_SAVE (1 << 8)
219 /* restore state status - '1' means xHC is restoring state */ 219 /* restore state status - '1' means xHC is restoring state */
220 #define STS_RESTORE (1 << 9) 220 #define STS_RESTORE (1 << 9)
221 /* true: save or restore error */ 221 /* true: save or restore error */
222 #define STS_SRE (1 << 10) 222 #define STS_SRE (1 << 10)
223 /* true: Controller Not Ready to accept doorbell or op reg writes after reset */ 223 /* true: Controller Not Ready to accept doorbell or op reg writes after reset */
224 #define STS_CNR XHCI_STS_CNR 224 #define STS_CNR XHCI_STS_CNR
225 /* true: internal Host Controller Error - SW needs to reset and reinitialize */ 225 /* true: internal Host Controller Error - SW needs to reset and reinitialize */
226 #define STS_HCE (1 << 12) 226 #define STS_HCE (1 << 12)
227 /* bits 13:31 reserved and should be preserved */ 227 /* bits 13:31 reserved and should be preserved */
228 228
229 /* 229 /*
230 * DNCTRL - Device Notification Control Register - dev_notification bitmasks 230 * DNCTRL - Device Notification Control Register - dev_notification bitmasks
231 * Generate a device notification event when the HC sees a transaction with a 231 * Generate a device notification event when the HC sees a transaction with a
232 * notification type that matches a bit set in this bit field. 232 * notification type that matches a bit set in this bit field.
233 */ 233 */
234 #define DEV_NOTE_MASK (0xffff) 234 #define DEV_NOTE_MASK (0xffff)
235 #define ENABLE_DEV_NOTE(x) (1 << x) 235 #define ENABLE_DEV_NOTE(x) (1 << x)
236 /* Most of the device notification types should only be used for debug. 236 /* Most of the device notification types should only be used for debug.
237 * SW does need to pay attention to function wake notifications. 237 * SW does need to pay attention to function wake notifications.
238 */ 238 */
239 #define DEV_NOTE_FWAKE ENABLE_DEV_NOTE(1) 239 #define DEV_NOTE_FWAKE ENABLE_DEV_NOTE(1)
240 240
241 /* CRCR - Command Ring Control Register - cmd_ring bitmasks */ 241 /* CRCR - Command Ring Control Register - cmd_ring bitmasks */
242 /* bit 0 is the command ring cycle state */ 242 /* bit 0 is the command ring cycle state */
243 /* stop ring operation after completion of the currently executing command */ 243 /* stop ring operation after completion of the currently executing command */
244 #define CMD_RING_PAUSE (1 << 1) 244 #define CMD_RING_PAUSE (1 << 1)
245 /* stop ring immediately - abort the currently executing command */ 245 /* stop ring immediately - abort the currently executing command */
246 #define CMD_RING_ABORT (1 << 2) 246 #define CMD_RING_ABORT (1 << 2)
247 /* true: command ring is running */ 247 /* true: command ring is running */
248 #define CMD_RING_RUNNING (1 << 3) 248 #define CMD_RING_RUNNING (1 << 3)
249 /* bits 4:5 reserved and should be preserved */ 249 /* bits 4:5 reserved and should be preserved */
250 /* Command Ring pointer - bit mask for the lower 32 bits. */ 250 /* Command Ring pointer - bit mask for the lower 32 bits. */
251 #define CMD_RING_RSVD_BITS (0x3f) 251 #define CMD_RING_RSVD_BITS (0x3f)
252 252
253 /* CONFIG - Configure Register - config_reg bitmasks */ 253 /* CONFIG - Configure Register - config_reg bitmasks */
254 /* bits 0:7 - maximum number of device slots enabled (NumSlotsEn) */ 254 /* bits 0:7 - maximum number of device slots enabled (NumSlotsEn) */
255 #define MAX_DEVS(p) ((p) & 0xff) 255 #define MAX_DEVS(p) ((p) & 0xff)
256 /* bits 8:31 - reserved and should be preserved */ 256 /* bits 8:31 - reserved and should be preserved */
257 257
258 /* PORTSC - Port Status and Control Register - port_status_base bitmasks */ 258 /* PORTSC - Port Status and Control Register - port_status_base bitmasks */
259 /* true: device connected */ 259 /* true: device connected */
260 #define PORT_CONNECT (1 << 0) 260 #define PORT_CONNECT (1 << 0)
261 /* true: port enabled */ 261 /* true: port enabled */
262 #define PORT_PE (1 << 1) 262 #define PORT_PE (1 << 1)
263 /* bit 2 reserved and zeroed */ 263 /* bit 2 reserved and zeroed */
264 /* true: port has an over-current condition */ 264 /* true: port has an over-current condition */
265 #define PORT_OC (1 << 3) 265 #define PORT_OC (1 << 3)
266 /* true: port reset signaling asserted */ 266 /* true: port reset signaling asserted */
267 #define PORT_RESET (1 << 4) 267 #define PORT_RESET (1 << 4)
268 /* Port Link State - bits 5:8 268 /* Port Link State - bits 5:8
269 * A read gives the current link PM state of the port, 269 * A read gives the current link PM state of the port,
270 * a write with Link State Write Strobe set sets the link state. 270 * a write with Link State Write Strobe set sets the link state.
271 */ 271 */
272 /* true: port has power (see HCC_PPC) */ 272 /* true: port has power (see HCC_PPC) */
273 #define PORT_POWER (1 << 9) 273 #define PORT_POWER (1 << 9)
274 /* bits 10:13 indicate device speed: 274 /* bits 10:13 indicate device speed:
275 * 0 - undefined speed - port hasn't be initialized by a reset yet 275 * 0 - undefined speed - port hasn't be initialized by a reset yet
276 * 1 - full speed 276 * 1 - full speed
277 * 2 - low speed 277 * 2 - low speed
278 * 3 - high speed 278 * 3 - high speed
279 * 4 - super speed 279 * 4 - super speed
280 * 5-15 reserved 280 * 5-15 reserved
281 */ 281 */
282 #define DEV_SPEED_MASK (0xf << 10) 282 #define DEV_SPEED_MASK (0xf << 10)
283 #define XDEV_FS (0x1 << 10) 283 #define XDEV_FS (0x1 << 10)
284 #define XDEV_LS (0x2 << 10) 284 #define XDEV_LS (0x2 << 10)
285 #define XDEV_HS (0x3 << 10) 285 #define XDEV_HS (0x3 << 10)
286 #define XDEV_SS (0x4 << 10) 286 #define XDEV_SS (0x4 << 10)
287 #define DEV_UNDEFSPEED(p) (((p) & DEV_SPEED_MASK) == (0x0<<10)) 287 #define DEV_UNDEFSPEED(p) (((p) & DEV_SPEED_MASK) == (0x0<<10))
288 #define DEV_FULLSPEED(p) (((p) & DEV_SPEED_MASK) == XDEV_FS) 288 #define DEV_FULLSPEED(p) (((p) & DEV_SPEED_MASK) == XDEV_FS)
289 #define DEV_LOWSPEED(p) (((p) & DEV_SPEED_MASK) == XDEV_LS) 289 #define DEV_LOWSPEED(p) (((p) & DEV_SPEED_MASK) == XDEV_LS)
290 #define DEV_HIGHSPEED(p) (((p) & DEV_SPEED_MASK) == XDEV_HS) 290 #define DEV_HIGHSPEED(p) (((p) & DEV_SPEED_MASK) == XDEV_HS)
291 #define DEV_SUPERSPEED(p) (((p) & DEV_SPEED_MASK) == XDEV_SS) 291 #define DEV_SUPERSPEED(p) (((p) & DEV_SPEED_MASK) == XDEV_SS)
292 /* Bits 20:23 in the Slot Context are the speed for the device */ 292 /* Bits 20:23 in the Slot Context are the speed for the device */
293 #define SLOT_SPEED_FS (XDEV_FS << 10) 293 #define SLOT_SPEED_FS (XDEV_FS << 10)
294 #define SLOT_SPEED_LS (XDEV_LS << 10) 294 #define SLOT_SPEED_LS (XDEV_LS << 10)
295 #define SLOT_SPEED_HS (XDEV_HS << 10) 295 #define SLOT_SPEED_HS (XDEV_HS << 10)
296 #define SLOT_SPEED_SS (XDEV_SS << 10) 296 #define SLOT_SPEED_SS (XDEV_SS << 10)
297 /* Port Indicator Control */ 297 /* Port Indicator Control */
298 #define PORT_LED_OFF (0 << 14) 298 #define PORT_LED_OFF (0 << 14)
299 #define PORT_LED_AMBER (1 << 14) 299 #define PORT_LED_AMBER (1 << 14)
300 #define PORT_LED_GREEN (2 << 14) 300 #define PORT_LED_GREEN (2 << 14)
301 #define PORT_LED_MASK (3 << 14) 301 #define PORT_LED_MASK (3 << 14)
302 /* Port Link State Write Strobe - set this when changing link state */ 302 /* Port Link State Write Strobe - set this when changing link state */
303 #define PORT_LINK_STROBE (1 << 16) 303 #define PORT_LINK_STROBE (1 << 16)
304 /* true: connect status change */ 304 /* true: connect status change */
305 #define PORT_CSC (1 << 17) 305 #define PORT_CSC (1 << 17)
306 /* true: port enable change */ 306 /* true: port enable change */
307 #define PORT_PEC (1 << 18) 307 #define PORT_PEC (1 << 18)
308 /* true: warm reset for a USB 3.0 device is done. A "hot" reset puts the port 308 /* true: warm reset for a USB 3.0 device is done. A "hot" reset puts the port
309 * into an enabled state, and the device into the default state. A "warm" reset 309 * into an enabled state, and the device into the default state. A "warm" reset
310 * also resets the link, forcing the device through the link training sequence. 310 * also resets the link, forcing the device through the link training sequence.
311 * SW can also look at the Port Reset register to see when warm reset is done. 311 * SW can also look at the Port Reset register to see when warm reset is done.
312 */ 312 */
313 #define PORT_WRC (1 << 19) 313 #define PORT_WRC (1 << 19)
314 /* true: over-current change */ 314 /* true: over-current change */
315 #define PORT_OCC (1 << 20) 315 #define PORT_OCC (1 << 20)
316 /* true: reset change - 1 to 0 transition of PORT_RESET */ 316 /* true: reset change - 1 to 0 transition of PORT_RESET */
317 #define PORT_RC (1 << 21) 317 #define PORT_RC (1 << 21)
318 /* port link status change - set on some port link state transitions: 318 /* port link status change - set on some port link state transitions:
319 * Transition Reason 319 * Transition Reason
320 * ------------------------------------------------------------------------------ 320 * ------------------------------------------------------------------------------
321 * - U3 to Resume Wakeup signaling from a device 321 * - U3 to Resume Wakeup signaling from a device
322 * - Resume to Recovery to U0 USB 3.0 device resume 322 * - Resume to Recovery to U0 USB 3.0 device resume
323 * - Resume to U0 USB 2.0 device resume 323 * - Resume to U0 USB 2.0 device resume
324 * - U3 to Recovery to U0 Software resume of USB 3.0 device complete 324 * - U3 to Recovery to U0 Software resume of USB 3.0 device complete
325 * - U3 to U0 Software resume of USB 2.0 device complete 325 * - U3 to U0 Software resume of USB 2.0 device complete
326 * - U2 to U0 L1 resume of USB 2.1 device complete 326 * - U2 to U0 L1 resume of USB 2.1 device complete
327 * - U0 to U0 (???) L1 entry rejection by USB 2.1 device 327 * - U0 to U0 (???) L1 entry rejection by USB 2.1 device
328 * - U0 to disabled L1 entry error with USB 2.1 device 328 * - U0 to disabled L1 entry error with USB 2.1 device
329 * - Any state to inactive Error on USB 3.0 port 329 * - Any state to inactive Error on USB 3.0 port
330 */ 330 */
331 #define PORT_PLC (1 << 22) 331 #define PORT_PLC (1 << 22)
332 /* port configure error change - port failed to configure its link partner */ 332 /* port configure error change - port failed to configure its link partner */
333 #define PORT_CEC (1 << 23) 333 #define PORT_CEC (1 << 23)
334 /* bit 24 reserved */ 334 /* bit 24 reserved */
335 /* wake on connect (enable) */ 335 /* wake on connect (enable) */
336 #define PORT_WKCONN_E (1 << 25) 336 #define PORT_WKCONN_E (1 << 25)
337 /* wake on disconnect (enable) */ 337 /* wake on disconnect (enable) */
338 #define PORT_WKDISC_E (1 << 26) 338 #define PORT_WKDISC_E (1 << 26)
339 /* wake on over-current (enable) */ 339 /* wake on over-current (enable) */
340 #define PORT_WKOC_E (1 << 27) 340 #define PORT_WKOC_E (1 << 27)
341 /* bits 28:29 reserved */ 341 /* bits 28:29 reserved */
342 /* true: device is removable - for USB 3.0 roothub emulation */ 342 /* true: device is removable - for USB 3.0 roothub emulation */
343 #define PORT_DEV_REMOVE (1 << 30) 343 #define PORT_DEV_REMOVE (1 << 30)
344 /* Initiate a warm port reset - complete when PORT_WRC is '1' */ 344 /* Initiate a warm port reset - complete when PORT_WRC is '1' */
345 #define PORT_WR (1 << 31) 345 #define PORT_WR (1 << 31)
346 346
347 /* Port Power Management Status and Control - port_power_base bitmasks */ 347 /* Port Power Management Status and Control - port_power_base bitmasks */
348 /* Inactivity timer value for transitions into U1, in microseconds. 348 /* Inactivity timer value for transitions into U1, in microseconds.
349 * Timeout can be up to 127us. 0xFF means an infinite timeout. 349 * Timeout can be up to 127us. 0xFF means an infinite timeout.
350 */ 350 */
351 #define PORT_U1_TIMEOUT(p) ((p) & 0xff) 351 #define PORT_U1_TIMEOUT(p) ((p) & 0xff)
352 /* Inactivity timer value for transitions into U2 */ 352 /* Inactivity timer value for transitions into U2 */
353 #define PORT_U2_TIMEOUT(p) (((p) & 0xff) << 8) 353 #define PORT_U2_TIMEOUT(p) (((p) & 0xff) << 8)
354 /* Bits 24:31 for port testing */ 354 /* Bits 24:31 for port testing */
355 355
356 356
357 /** 357 /**
358 * struct xhci_intr_reg - Interrupt Register Set 358 * struct xhci_intr_reg - Interrupt Register Set
359 * @irq_pending: IMAN - Interrupt Management Register. Used to enable 359 * @irq_pending: IMAN - Interrupt Management Register. Used to enable
360 * interrupts and check for pending interrupts. 360 * interrupts and check for pending interrupts.
361 * @irq_control: IMOD - Interrupt Moderation Register. 361 * @irq_control: IMOD - Interrupt Moderation Register.
362 * Used to throttle interrupts. 362 * Used to throttle interrupts.
363 * @erst_size: Number of segments in the Event Ring Segment Table (ERST). 363 * @erst_size: Number of segments in the Event Ring Segment Table (ERST).
364 * @erst_base: ERST base address. 364 * @erst_base: ERST base address.
365 * @erst_dequeue: Event ring dequeue pointer. 365 * @erst_dequeue: Event ring dequeue pointer.
366 * 366 *
367 * Each interrupter (defined by a MSI-X vector) has an event ring and an Event 367 * Each interrupter (defined by a MSI-X vector) has an event ring and an Event
368 * Ring Segment Table (ERST) associated with it. The event ring is comprised of 368 * Ring Segment Table (ERST) associated with it. The event ring is comprised of
369 * multiple segments of the same size. The HC places events on the ring and 369 * multiple segments of the same size. The HC places events on the ring and
370 * "updates the Cycle bit in the TRBs to indicate to software the current 370 * "updates the Cycle bit in the TRBs to indicate to software the current
371 * position of the Enqueue Pointer." The HCD (Linux) processes those events and 371 * position of the Enqueue Pointer." The HCD (Linux) processes those events and
372 * updates the dequeue pointer. 372 * updates the dequeue pointer.
373 */ 373 */
374 struct xhci_intr_reg { 374 struct xhci_intr_reg {
375 u32 irq_pending; 375 u32 irq_pending;
376 u32 irq_control; 376 u32 irq_control;
377 u32 erst_size; 377 u32 erst_size;
378 u32 rsvd; 378 u32 rsvd;
379 u64 erst_base; 379 u64 erst_base;
380 u64 erst_dequeue; 380 u64 erst_dequeue;
381 }; 381 };
382 382
383 /* irq_pending bitmasks */ 383 /* irq_pending bitmasks */
384 #define ER_IRQ_PENDING(p) ((p) & 0x1) 384 #define ER_IRQ_PENDING(p) ((p) & 0x1)
385 /* bits 2:31 need to be preserved */ 385 /* bits 2:31 need to be preserved */
386 /* THIS IS BUGGY - FIXME - IP IS WRITE 1 TO CLEAR */ 386 /* THIS IS BUGGY - FIXME - IP IS WRITE 1 TO CLEAR */
387 #define ER_IRQ_CLEAR(p) ((p) & 0xfffffffe) 387 #define ER_IRQ_CLEAR(p) ((p) & 0xfffffffe)
388 #define ER_IRQ_ENABLE(p) ((ER_IRQ_CLEAR(p)) | 0x2) 388 #define ER_IRQ_ENABLE(p) ((ER_IRQ_CLEAR(p)) | 0x2)
389 #define ER_IRQ_DISABLE(p) ((ER_IRQ_CLEAR(p)) & ~(0x2)) 389 #define ER_IRQ_DISABLE(p) ((ER_IRQ_CLEAR(p)) & ~(0x2))
390 390
391 /* irq_control bitmasks */ 391 /* irq_control bitmasks */
392 /* Minimum interval between interrupts (in 250ns intervals). The interval 392 /* Minimum interval between interrupts (in 250ns intervals). The interval
393 * between interrupts will be longer if there are no events on the event ring. 393 * between interrupts will be longer if there are no events on the event ring.
394 * Default is 4000 (1 ms). 394 * Default is 4000 (1 ms).
395 */ 395 */
396 #define ER_IRQ_INTERVAL_MASK (0xffff) 396 #define ER_IRQ_INTERVAL_MASK (0xffff)
397 /* Counter used to count down the time to the next interrupt - HW use only */ 397 /* Counter used to count down the time to the next interrupt - HW use only */
398 #define ER_IRQ_COUNTER_MASK (0xffff << 16) 398 #define ER_IRQ_COUNTER_MASK (0xffff << 16)
399 399
400 /* erst_size bitmasks */ 400 /* erst_size bitmasks */
401 /* Preserve bits 16:31 of erst_size */ 401 /* Preserve bits 16:31 of erst_size */
402 #define ERST_SIZE_MASK (0xffff << 16) 402 #define ERST_SIZE_MASK (0xffff << 16)
403 403
404 /* erst_dequeue bitmasks */ 404 /* erst_dequeue bitmasks */
405 /* Dequeue ERST Segment Index (DESI) - Segment number (or alias) 405 /* Dequeue ERST Segment Index (DESI) - Segment number (or alias)
406 * where the current dequeue pointer lies. This is an optional HW hint. 406 * where the current dequeue pointer lies. This is an optional HW hint.
407 */ 407 */
408 #define ERST_DESI_MASK (0x7) 408 #define ERST_DESI_MASK (0x7)
409 /* Event Handler Busy (EHB) - is the event ring scheduled to be serviced by 409 /* Event Handler Busy (EHB) - is the event ring scheduled to be serviced by
410 * a work queue (or delayed service routine)? 410 * a work queue (or delayed service routine)?
411 */ 411 */
412 #define ERST_EHB (1 << 3) 412 #define ERST_EHB (1 << 3)
413 #define ERST_PTR_MASK (0xf) 413 #define ERST_PTR_MASK (0xf)
414 414
415 /** 415 /**
416 * struct xhci_run_regs 416 * struct xhci_run_regs
417 * @microframe_index: 417 * @microframe_index:
418 * MFINDEX - current microframe number 418 * MFINDEX - current microframe number
419 * 419 *
420 * Section 5.5 Host Controller Runtime Registers: 420 * Section 5.5 Host Controller Runtime Registers:
421 * "Software should read and write these registers using only Dword (32 bit) 421 * "Software should read and write these registers using only Dword (32 bit)
422 * or larger accesses" 422 * or larger accesses"
423 */ 423 */
424 struct xhci_run_regs { 424 struct xhci_run_regs {
425 u32 microframe_index; 425 u32 microframe_index;
426 u32 rsvd[7]; 426 u32 rsvd[7];
427 struct xhci_intr_reg ir_set[128]; 427 struct xhci_intr_reg ir_set[128];
428 }; 428 };
429 429
430 /** 430 /**
431 * struct doorbell_array 431 * struct doorbell_array
432 * 432 *
433 * Section 5.6 433 * Section 5.6
434 */ 434 */
435 struct xhci_doorbell_array { 435 struct xhci_doorbell_array {
436 u32 doorbell[256]; 436 u32 doorbell[256];
437 }; 437 };
438 438
439 #define DB_TARGET_MASK 0xFFFFFF00 439 #define DB_TARGET_MASK 0xFFFFFF00
440 #define DB_STREAM_ID_MASK 0x0000FFFF 440 #define DB_STREAM_ID_MASK 0x0000FFFF
441 #define DB_TARGET_HOST 0x0 441 #define DB_TARGET_HOST 0x0
442 #define DB_STREAM_ID_HOST 0x0 442 #define DB_STREAM_ID_HOST 0x0
443 #define DB_MASK (0xff << 8) 443 #define DB_MASK (0xff << 8)
444 444
445 /* Endpoint Target - bits 0:7 */ 445 /* Endpoint Target - bits 0:7 */
446 #define EPI_TO_DB(p) (((p) + 1) & 0xff) 446 #define EPI_TO_DB(p) (((p) + 1) & 0xff)
447 447
448 448
449 /** 449 /**
450 * struct xhci_container_ctx 450 * struct xhci_container_ctx
451 * @type: Type of context. Used to calculated offsets to contained contexts. 451 * @type: Type of context. Used to calculated offsets to contained contexts.
452 * @size: Size of the context data 452 * @size: Size of the context data
453 * @bytes: The raw context data given to HW 453 * @bytes: The raw context data given to HW
454 * @dma: dma address of the bytes 454 * @dma: dma address of the bytes
455 * 455 *
456 * Represents either a Device or Input context. Holds a pointer to the raw 456 * Represents either a Device or Input context. Holds a pointer to the raw
457 * memory used for the context (bytes) and dma address of it (dma). 457 * memory used for the context (bytes) and dma address of it (dma).
458 */ 458 */
459 struct xhci_container_ctx { 459 struct xhci_container_ctx {
460 unsigned type; 460 unsigned type;
461 #define XHCI_CTX_TYPE_DEVICE 0x1 461 #define XHCI_CTX_TYPE_DEVICE 0x1
462 #define XHCI_CTX_TYPE_INPUT 0x2 462 #define XHCI_CTX_TYPE_INPUT 0x2
463 463
464 int size; 464 int size;
465 465
466 u8 *bytes; 466 u8 *bytes;
467 dma_addr_t dma; 467 dma_addr_t dma;
468 }; 468 };
469 469
470 /** 470 /**
471 * struct xhci_slot_ctx 471 * struct xhci_slot_ctx
472 * @dev_info: Route string, device speed, hub info, and last valid endpoint 472 * @dev_info: Route string, device speed, hub info, and last valid endpoint
473 * @dev_info2: Max exit latency for device number, root hub port number 473 * @dev_info2: Max exit latency for device number, root hub port number
474 * @tt_info: tt_info is used to construct split transaction tokens 474 * @tt_info: tt_info is used to construct split transaction tokens
475 * @dev_state: slot state and device address 475 * @dev_state: slot state and device address
476 * 476 *
477 * Slot Context - section 6.2.1.1. This assumes the HC uses 32-byte context 477 * Slot Context - section 6.2.1.1. This assumes the HC uses 32-byte context
478 * structures. If the HC uses 64-byte contexts, there is an additional 32 bytes 478 * structures. If the HC uses 64-byte contexts, there is an additional 32 bytes
479 * reserved at the end of the slot context for HC internal use. 479 * reserved at the end of the slot context for HC internal use.
480 */ 480 */
481 struct xhci_slot_ctx { 481 struct xhci_slot_ctx {
482 u32 dev_info; 482 u32 dev_info;
483 u32 dev_info2; 483 u32 dev_info2;
484 u32 tt_info; 484 u32 tt_info;
485 u32 dev_state; 485 u32 dev_state;
486 /* offset 0x10 to 0x1f reserved for HC internal use */ 486 /* offset 0x10 to 0x1f reserved for HC internal use */
487 u32 reserved[4]; 487 u32 reserved[4];
488 }; 488 };
489 489
490 /* dev_info bitmasks */ 490 /* dev_info bitmasks */
491 /* Route String - 0:19 */ 491 /* Route String - 0:19 */
492 #define ROUTE_STRING_MASK (0xfffff) 492 #define ROUTE_STRING_MASK (0xfffff)
493 /* Device speed - values defined by PORTSC Device Speed field - 20:23 */ 493 /* Device speed - values defined by PORTSC Device Speed field - 20:23 */
494 #define DEV_SPEED (0xf << 20) 494 #define DEV_SPEED (0xf << 20)
495 /* bit 24 reserved */ 495 /* bit 24 reserved */
496 /* Is this LS/FS device connected through a HS hub? - bit 25 */ 496 /* Is this LS/FS device connected through a HS hub? - bit 25 */
497 #define DEV_MTT (0x1 << 25) 497 #define DEV_MTT (0x1 << 25)
498 /* Set if the device is a hub - bit 26 */ 498 /* Set if the device is a hub - bit 26 */
499 #define DEV_HUB (0x1 << 26) 499 #define DEV_HUB (0x1 << 26)
500 /* Index of the last valid endpoint context in this device context - 27:31 */ 500 /* Index of the last valid endpoint context in this device context - 27:31 */
501 #define LAST_CTX_MASK (0x1f << 27) 501 #define LAST_CTX_MASK (0x1f << 27)
502 #define LAST_CTX(p) ((p) << 27) 502 #define LAST_CTX(p) ((p) << 27)
503 #define LAST_CTX_TO_EP_NUM(p) (((p) >> 27) - 1) 503 #define LAST_CTX_TO_EP_NUM(p) (((p) >> 27) - 1)
504 #define SLOT_FLAG (1 << 0) 504 #define SLOT_FLAG (1 << 0)
505 #define EP0_FLAG (1 << 1) 505 #define EP0_FLAG (1 << 1)
506 506
507 /* dev_info2 bitmasks */ 507 /* dev_info2 bitmasks */
508 /* Max Exit Latency (ms) - worst case time to wake up all links in dev path */ 508 /* Max Exit Latency (ms) - worst case time to wake up all links in dev path */
509 #define MAX_EXIT (0xffff) 509 #define MAX_EXIT (0xffff)
510 /* Root hub port number that is needed to access the USB device */ 510 /* Root hub port number that is needed to access the USB device */
511 #define ROOT_HUB_PORT(p) (((p) & 0xff) << 16) 511 #define ROOT_HUB_PORT(p) (((p) & 0xff) << 16)
512 512
513 /* tt_info bitmasks */ 513 /* tt_info bitmasks */
514 /* 514 /*
515 * TT Hub Slot ID - for low or full speed devices attached to a high-speed hub 515 * TT Hub Slot ID - for low or full speed devices attached to a high-speed hub
516 * The Slot ID of the hub that isolates the high speed signaling from 516 * The Slot ID of the hub that isolates the high speed signaling from
517 * this low or full-speed device. '0' if attached to root hub port. 517 * this low or full-speed device. '0' if attached to root hub port.
518 */ 518 */
519 #define TT_SLOT (0xff) 519 #define TT_SLOT (0xff)
520 /* 520 /*
521 * The number of the downstream facing port of the high-speed hub 521 * The number of the downstream facing port of the high-speed hub
522 * '0' if the device is not low or full speed. 522 * '0' if the device is not low or full speed.
523 */ 523 */
524 #define TT_PORT (0xff << 8) 524 #define TT_PORT (0xff << 8)
525 525
526 /* dev_state bitmasks */ 526 /* dev_state bitmasks */
527 /* USB device address - assigned by the HC */ 527 /* USB device address - assigned by the HC */
528 #define DEV_ADDR_MASK (0xff) 528 #define DEV_ADDR_MASK (0xff)
529 /* bits 8:26 reserved */ 529 /* bits 8:26 reserved */
530 /* Slot state */ 530 /* Slot state */
531 #define SLOT_STATE (0x1f << 27) 531 #define SLOT_STATE (0x1f << 27)
532 #define GET_SLOT_STATE(p) (((p) & (0x1f << 27)) >> 27) 532 #define GET_SLOT_STATE(p) (((p) & (0x1f << 27)) >> 27)
533 533
534 534
535 /** 535 /**
536 * struct xhci_ep_ctx 536 * struct xhci_ep_ctx
537 * @ep_info: endpoint state, streams, mult, and interval information. 537 * @ep_info: endpoint state, streams, mult, and interval information.
538 * @ep_info2: information on endpoint type, max packet size, max burst size, 538 * @ep_info2: information on endpoint type, max packet size, max burst size,
539 * error count, and whether the HC will force an event for all 539 * error count, and whether the HC will force an event for all
540 * transactions. 540 * transactions.
541 * @deq: 64-bit ring dequeue pointer address. If the endpoint only 541 * @deq: 64-bit ring dequeue pointer address. If the endpoint only
542 * defines one stream, this points to the endpoint transfer ring. 542 * defines one stream, this points to the endpoint transfer ring.
543 * Otherwise, it points to a stream context array, which has a 543 * Otherwise, it points to a stream context array, which has a
544 * ring pointer for each flow. 544 * ring pointer for each flow.
545 * @tx_info: 545 * @tx_info:
546 * Average TRB lengths for the endpoint ring and 546 * Average TRB lengths for the endpoint ring and
547 * max payload within an Endpoint Service Interval Time (ESIT). 547 * max payload within an Endpoint Service Interval Time (ESIT).
548 * 548 *
549 * Endpoint Context - section 6.2.1.2. This assumes the HC uses 32-byte context 549 * Endpoint Context - section 6.2.1.2. This assumes the HC uses 32-byte context
550 * structures. If the HC uses 64-byte contexts, there is an additional 32 bytes 550 * structures. If the HC uses 64-byte contexts, there is an additional 32 bytes
551 * reserved at the end of the endpoint context for HC internal use. 551 * reserved at the end of the endpoint context for HC internal use.
552 */ 552 */
553 struct xhci_ep_ctx { 553 struct xhci_ep_ctx {
554 u32 ep_info; 554 u32 ep_info;
555 u32 ep_info2; 555 u32 ep_info2;
556 u64 deq; 556 u64 deq;
557 u32 tx_info; 557 u32 tx_info;
558 /* offset 0x14 - 0x1f reserved for HC internal use */ 558 /* offset 0x14 - 0x1f reserved for HC internal use */
559 u32 reserved[3]; 559 u32 reserved[3];
560 }; 560 };
561 561
562 /* ep_info bitmasks */ 562 /* ep_info bitmasks */
563 /* 563 /*
564 * Endpoint State - bits 0:2 564 * Endpoint State - bits 0:2
565 * 0 - disabled 565 * 0 - disabled
566 * 1 - running 566 * 1 - running
567 * 2 - halted due to halt condition - ok to manipulate endpoint ring 567 * 2 - halted due to halt condition - ok to manipulate endpoint ring
568 * 3 - stopped 568 * 3 - stopped
569 * 4 - TRB error 569 * 4 - TRB error
570 * 5-7 - reserved 570 * 5-7 - reserved
571 */ 571 */
572 #define EP_STATE_MASK (0xf) 572 #define EP_STATE_MASK (0xf)
573 #define EP_STATE_DISABLED 0 573 #define EP_STATE_DISABLED 0
574 #define EP_STATE_RUNNING 1 574 #define EP_STATE_RUNNING 1
575 #define EP_STATE_HALTED 2 575 #define EP_STATE_HALTED 2
576 #define EP_STATE_STOPPED 3 576 #define EP_STATE_STOPPED 3
577 #define EP_STATE_ERROR 4 577 #define EP_STATE_ERROR 4
578 /* Mult - Max number of burtst within an interval, in EP companion desc. */ 578 /* Mult - Max number of burtst within an interval, in EP companion desc. */
579 #define EP_MULT(p) ((p & 0x3) << 8) 579 #define EP_MULT(p) ((p & 0x3) << 8)
580 /* bits 10:14 are Max Primary Streams */ 580 /* bits 10:14 are Max Primary Streams */
581 /* bit 15 is Linear Stream Array */ 581 /* bit 15 is Linear Stream Array */
582 /* Interval - period between requests to an endpoint - 125u increments. */ 582 /* Interval - period between requests to an endpoint - 125u increments. */
583 #define EP_INTERVAL(p) ((p & 0xff) << 16) 583 #define EP_INTERVAL(p) ((p & 0xff) << 16)
584 584
585 /* ep_info2 bitmasks */ 585 /* ep_info2 bitmasks */
586 /* 586 /*
587 * Force Event - generate transfer events for all TRBs for this endpoint 587 * Force Event - generate transfer events for all TRBs for this endpoint
588 * This will tell the HC to ignore the IOC and ISP flags (for debugging only). 588 * This will tell the HC to ignore the IOC and ISP flags (for debugging only).
589 */ 589 */
590 #define FORCE_EVENT (0x1) 590 #define FORCE_EVENT (0x1)
591 #define ERROR_COUNT(p) (((p) & 0x3) << 1) 591 #define ERROR_COUNT(p) (((p) & 0x3) << 1)
592 #define EP_TYPE(p) ((p) << 3) 592 #define EP_TYPE(p) ((p) << 3)
593 #define ISOC_OUT_EP 1 593 #define ISOC_OUT_EP 1
594 #define BULK_OUT_EP 2 594 #define BULK_OUT_EP 2
595 #define INT_OUT_EP 3 595 #define INT_OUT_EP 3
596 #define CTRL_EP 4 596 #define CTRL_EP 4
597 #define ISOC_IN_EP 5 597 #define ISOC_IN_EP 5
598 #define BULK_IN_EP 6 598 #define BULK_IN_EP 6
599 #define INT_IN_EP 7 599 #define INT_IN_EP 7
600 /* bit 6 reserved */ 600 /* bit 6 reserved */
601 /* bit 7 is Host Initiate Disable - for disabling stream selection */ 601 /* bit 7 is Host Initiate Disable - for disabling stream selection */
602 #define MAX_BURST(p) (((p)&0xff) << 8) 602 #define MAX_BURST(p) (((p)&0xff) << 8)
603 #define MAX_PACKET(p) (((p)&0xffff) << 16) 603 #define MAX_PACKET(p) (((p)&0xffff) << 16)
604 604
605 605
606 /** 606 /**
607 * struct xhci_input_control_context 607 * struct xhci_input_control_context
608 * Input control context; see section 6.2.5. 608 * Input control context; see section 6.2.5.
609 * 609 *
610 * @drop_context: set the bit of the endpoint context you want to disable 610 * @drop_context: set the bit of the endpoint context you want to disable
611 * @add_context: set the bit of the endpoint context you want to enable 611 * @add_context: set the bit of the endpoint context you want to enable
612 */ 612 */
613 struct xhci_input_control_ctx { 613 struct xhci_input_control_ctx {
614 u32 drop_flags; 614 u32 drop_flags;
615 u32 add_flags; 615 u32 add_flags;
616 u32 rsvd2[6]; 616 u32 rsvd2[6];
617 }; 617 };
618 618
619 /* drop context bitmasks */ 619 /* drop context bitmasks */
620 #define DROP_EP(x) (0x1 << x) 620 #define DROP_EP(x) (0x1 << x)
621 /* add context bitmasks */ 621 /* add context bitmasks */
622 #define ADD_EP(x) (0x1 << x) 622 #define ADD_EP(x) (0x1 << x)
623 623
624 struct xhci_virt_device { 624 struct xhci_virt_device {
625 /* 625 /*
626 * Commands to the hardware are passed an "input context" that 626 * Commands to the hardware are passed an "input context" that
627 * tells the hardware what to change in its data structures. 627 * tells the hardware what to change in its data structures.
628 * The hardware will return changes in an "output context" that 628 * The hardware will return changes in an "output context" that
629 * software must allocate for the hardware. We need to keep 629 * software must allocate for the hardware. We need to keep
630 * track of input and output contexts separately because 630 * track of input and output contexts separately because
631 * these commands might fail and we don't trust the hardware. 631 * these commands might fail and we don't trust the hardware.
632 */ 632 */
633 struct xhci_container_ctx *out_ctx; 633 struct xhci_container_ctx *out_ctx;
634 /* Used for addressing devices and configuration changes */ 634 /* Used for addressing devices and configuration changes */
635 struct xhci_container_ctx *in_ctx; 635 struct xhci_container_ctx *in_ctx;
636 636
637 /* FIXME when stream support is added */ 637 /* FIXME when stream support is added */
638 struct xhci_ring *ep_rings[31]; 638 struct xhci_ring *ep_rings[31];
639 /* Temporary storage in case the configure endpoint command fails and we 639 /* Temporary storage in case the configure endpoint command fails and we
640 * have to restore the device state to the previous state 640 * have to restore the device state to the previous state
641 */ 641 */
642 struct xhci_ring *new_ep_rings[31]; 642 struct xhci_ring *new_ep_rings[31];
643 struct completion cmd_completion; 643 struct completion cmd_completion;
644 /* Status of the last command issued for this device */ 644 /* Status of the last command issued for this device */
645 u32 cmd_status; 645 u32 cmd_status;
646 }; 646 };
647 647
648 648
649 /** 649 /**
650 * struct xhci_device_context_array 650 * struct xhci_device_context_array
651 * @dev_context_ptr array of 64-bit DMA addresses for device contexts 651 * @dev_context_ptr array of 64-bit DMA addresses for device contexts
652 */ 652 */
653 struct xhci_device_context_array { 653 struct xhci_device_context_array {
654 /* 64-bit device addresses; we only write 32-bit addresses */ 654 /* 64-bit device addresses; we only write 32-bit addresses */
655 u64 dev_context_ptrs[MAX_HC_SLOTS]; 655 u64 dev_context_ptrs[MAX_HC_SLOTS];
656 /* private xHCD pointers */ 656 /* private xHCD pointers */
657 dma_addr_t dma; 657 dma_addr_t dma;
658 }; 658 };
659 /* TODO: write function to set the 64-bit device DMA address */ 659 /* TODO: write function to set the 64-bit device DMA address */
660 /* 660 /*
661 * TODO: change this to be dynamically sized at HC mem init time since the HC 661 * TODO: change this to be dynamically sized at HC mem init time since the HC
662 * might not be able to handle the maximum number of devices possible. 662 * might not be able to handle the maximum number of devices possible.
663 */ 663 */
664 664
665 665
666 struct xhci_stream_ctx { 666 struct xhci_stream_ctx {
667 /* 64-bit stream ring address, cycle state, and stream type */ 667 /* 64-bit stream ring address, cycle state, and stream type */
668 u64 stream_ring; 668 u64 stream_ring;
669 /* offset 0x14 - 0x1f reserved for HC internal use */ 669 /* offset 0x14 - 0x1f reserved for HC internal use */
670 u32 reserved[2]; 670 u32 reserved[2];
671 }; 671 };
672 672
673 673
674 struct xhci_transfer_event { 674 struct xhci_transfer_event {
675 /* 64-bit buffer address, or immediate data */ 675 /* 64-bit buffer address, or immediate data */
676 u64 buffer; 676 u64 buffer;
677 u32 transfer_len; 677 u32 transfer_len;
678 /* This field is interpreted differently based on the type of TRB */ 678 /* This field is interpreted differently based on the type of TRB */
679 u32 flags; 679 u32 flags;
680 }; 680 };
681 681
682 /** Transfer Event bit fields **/ 682 /** Transfer Event bit fields **/
683 #define TRB_TO_EP_ID(p) (((p) >> 16) & 0x1f) 683 #define TRB_TO_EP_ID(p) (((p) >> 16) & 0x1f)
684 684
685 /* Completion Code - only applicable for some types of TRBs */ 685 /* Completion Code - only applicable for some types of TRBs */
686 #define COMP_CODE_MASK (0xff << 24) 686 #define COMP_CODE_MASK (0xff << 24)
687 #define GET_COMP_CODE(p) (((p) & COMP_CODE_MASK) >> 24) 687 #define GET_COMP_CODE(p) (((p) & COMP_CODE_MASK) >> 24)
688 #define COMP_SUCCESS 1 688 #define COMP_SUCCESS 1
689 /* Data Buffer Error */ 689 /* Data Buffer Error */
690 #define COMP_DB_ERR 2 690 #define COMP_DB_ERR 2
691 /* Babble Detected Error */ 691 /* Babble Detected Error */
692 #define COMP_BABBLE 3 692 #define COMP_BABBLE 3
693 /* USB Transaction Error */ 693 /* USB Transaction Error */
694 #define COMP_TX_ERR 4 694 #define COMP_TX_ERR 4
695 /* TRB Error - some TRB field is invalid */ 695 /* TRB Error - some TRB field is invalid */
696 #define COMP_TRB_ERR 5 696 #define COMP_TRB_ERR 5
697 /* Stall Error - USB device is stalled */ 697 /* Stall Error - USB device is stalled */
698 #define COMP_STALL 6 698 #define COMP_STALL 6
699 /* Resource Error - HC doesn't have memory for that device configuration */ 699 /* Resource Error - HC doesn't have memory for that device configuration */
700 #define COMP_ENOMEM 7 700 #define COMP_ENOMEM 7
701 /* Bandwidth Error - not enough room in schedule for this dev config */ 701 /* Bandwidth Error - not enough room in schedule for this dev config */
702 #define COMP_BW_ERR 8 702 #define COMP_BW_ERR 8
703 /* No Slots Available Error - HC ran out of device slots */ 703 /* No Slots Available Error - HC ran out of device slots */
704 #define COMP_ENOSLOTS 9 704 #define COMP_ENOSLOTS 9
705 /* Invalid Stream Type Error */ 705 /* Invalid Stream Type Error */
706 #define COMP_STREAM_ERR 10 706 #define COMP_STREAM_ERR 10
707 /* Slot Not Enabled Error - doorbell rung for disabled device slot */ 707 /* Slot Not Enabled Error - doorbell rung for disabled device slot */
708 #define COMP_EBADSLT 11 708 #define COMP_EBADSLT 11
709 /* Endpoint Not Enabled Error */ 709 /* Endpoint Not Enabled Error */
710 #define COMP_EBADEP 12 710 #define COMP_EBADEP 12
711 /* Short Packet */ 711 /* Short Packet */
712 #define COMP_SHORT_TX 13 712 #define COMP_SHORT_TX 13
713 /* Ring Underrun - doorbell rung for an empty isoc OUT ep ring */ 713 /* Ring Underrun - doorbell rung for an empty isoc OUT ep ring */
714 #define COMP_UNDERRUN 14 714 #define COMP_UNDERRUN 14
715 /* Ring Overrun - isoc IN ep ring is empty when ep is scheduled to RX */ 715 /* Ring Overrun - isoc IN ep ring is empty when ep is scheduled to RX */
716 #define COMP_OVERRUN 15 716 #define COMP_OVERRUN 15
717 /* Virtual Function Event Ring Full Error */ 717 /* Virtual Function Event Ring Full Error */
718 #define COMP_VF_FULL 16 718 #define COMP_VF_FULL 16
719 /* Parameter Error - Context parameter is invalid */ 719 /* Parameter Error - Context parameter is invalid */
720 #define COMP_EINVAL 17 720 #define COMP_EINVAL 17
721 /* Bandwidth Overrun Error - isoc ep exceeded its allocated bandwidth */ 721 /* Bandwidth Overrun Error - isoc ep exceeded its allocated bandwidth */
722 #define COMP_BW_OVER 18 722 #define COMP_BW_OVER 18
723 /* Context State Error - illegal context state transition requested */ 723 /* Context State Error - illegal context state transition requested */
724 #define COMP_CTX_STATE 19 724 #define COMP_CTX_STATE 19
725 /* No Ping Response Error - HC didn't get PING_RESPONSE in time to TX */ 725 /* No Ping Response Error - HC didn't get PING_RESPONSE in time to TX */
726 #define COMP_PING_ERR 20 726 #define COMP_PING_ERR 20
727 /* Event Ring is full */ 727 /* Event Ring is full */
728 #define COMP_ER_FULL 21 728 #define COMP_ER_FULL 21
729 /* Missed Service Error - HC couldn't service an isoc ep within interval */ 729 /* Missed Service Error - HC couldn't service an isoc ep within interval */
730 #define COMP_MISSED_INT 23 730 #define COMP_MISSED_INT 23
731 /* Successfully stopped command ring */ 731 /* Successfully stopped command ring */
732 #define COMP_CMD_STOP 24 732 #define COMP_CMD_STOP 24
733 /* Successfully aborted current command and stopped command ring */ 733 /* Successfully aborted current command and stopped command ring */
734 #define COMP_CMD_ABORT 25 734 #define COMP_CMD_ABORT 25
735 /* Stopped - transfer was terminated by a stop endpoint command */ 735 /* Stopped - transfer was terminated by a stop endpoint command */
736 #define COMP_STOP 26 736 #define COMP_STOP 26
737 /* Same as COMP_EP_STOPPED, but the transfered length in the event is invalid */ 737 /* Same as COMP_EP_STOPPED, but the transfered length in the event is invalid */
738 #define COMP_STOP_INVAL 27 738 #define COMP_STOP_INVAL 27
739 /* Control Abort Error - Debug Capability - control pipe aborted */ 739 /* Control Abort Error - Debug Capability - control pipe aborted */
740 #define COMP_DBG_ABORT 28 740 #define COMP_DBG_ABORT 28
741 /* TRB type 29 and 30 reserved */ 741 /* TRB type 29 and 30 reserved */
742 /* Isoc Buffer Overrun - an isoc IN ep sent more data than could fit in TD */ 742 /* Isoc Buffer Overrun - an isoc IN ep sent more data than could fit in TD */
743 #define COMP_BUFF_OVER 31 743 #define COMP_BUFF_OVER 31
744 /* Event Lost Error - xHC has an "internal event overrun condition" */ 744 /* Event Lost Error - xHC has an "internal event overrun condition" */
745 #define COMP_ISSUES 32 745 #define COMP_ISSUES 32
746 /* Undefined Error - reported when other error codes don't apply */ 746 /* Undefined Error - reported when other error codes don't apply */
747 #define COMP_UNKNOWN 33 747 #define COMP_UNKNOWN 33
748 /* Invalid Stream ID Error */ 748 /* Invalid Stream ID Error */
749 #define COMP_STRID_ERR 34 749 #define COMP_STRID_ERR 34
750 /* Secondary Bandwidth Error - may be returned by a Configure Endpoint cmd */ 750 /* Secondary Bandwidth Error - may be returned by a Configure Endpoint cmd */
751 /* FIXME - check for this */ 751 /* FIXME - check for this */
752 #define COMP_2ND_BW_ERR 35 752 #define COMP_2ND_BW_ERR 35
753 /* Split Transaction Error */ 753 /* Split Transaction Error */
754 #define COMP_SPLIT_ERR 36 754 #define COMP_SPLIT_ERR 36
755 755
756 struct xhci_link_trb { 756 struct xhci_link_trb {
757 /* 64-bit segment pointer*/ 757 /* 64-bit segment pointer*/
758 u64 segment_ptr; 758 u64 segment_ptr;
759 u32 intr_target; 759 u32 intr_target;
760 u32 control; 760 u32 control;
761 }; 761 };
762 762
763 /* control bitfields */ 763 /* control bitfields */
764 #define LINK_TOGGLE (0x1<<1) 764 #define LINK_TOGGLE (0x1<<1)
765 765
766 /* Command completion event TRB */ 766 /* Command completion event TRB */
767 struct xhci_event_cmd { 767 struct xhci_event_cmd {
768 /* Pointer to command TRB, or the value passed by the event data trb */ 768 /* Pointer to command TRB, or the value passed by the event data trb */
769 u64 cmd_trb; 769 u64 cmd_trb;
770 u32 status; 770 u32 status;
771 u32 flags; 771 u32 flags;
772 }; 772 };
773 773
774 /* flags bitmasks */ 774 /* flags bitmasks */
775 /* bits 16:23 are the virtual function ID */ 775 /* bits 16:23 are the virtual function ID */
776 /* bits 24:31 are the slot ID */ 776 /* bits 24:31 are the slot ID */
777 #define TRB_TO_SLOT_ID(p) (((p) & (0xff<<24)) >> 24) 777 #define TRB_TO_SLOT_ID(p) (((p) & (0xff<<24)) >> 24)
778 #define SLOT_ID_FOR_TRB(p) (((p) & 0xff) << 24) 778 #define SLOT_ID_FOR_TRB(p) (((p) & 0xff) << 24)
779 779
780 /* Stop Endpoint TRB - ep_index to endpoint ID for this TRB */ 780 /* Stop Endpoint TRB - ep_index to endpoint ID for this TRB */
781 #define TRB_TO_EP_INDEX(p) ((((p) & (0x1f << 16)) >> 16) - 1) 781 #define TRB_TO_EP_INDEX(p) ((((p) & (0x1f << 16)) >> 16) - 1)
782 #define EP_ID_FOR_TRB(p) ((((p) + 1) & 0x1f) << 16) 782 #define EP_ID_FOR_TRB(p) ((((p) + 1) & 0x1f) << 16)
783 783
784 784
785 /* Port Status Change Event TRB fields */ 785 /* Port Status Change Event TRB fields */
786 /* Port ID - bits 31:24 */ 786 /* Port ID - bits 31:24 */
787 #define GET_PORT_ID(p) (((p) & (0xff << 24)) >> 24) 787 #define GET_PORT_ID(p) (((p) & (0xff << 24)) >> 24)
788 788
789 /* Normal TRB fields */ 789 /* Normal TRB fields */
790 /* transfer_len bitmasks - bits 0:16 */ 790 /* transfer_len bitmasks - bits 0:16 */
791 #define TRB_LEN(p) ((p) & 0x1ffff) 791 #define TRB_LEN(p) ((p) & 0x1ffff)
792 /* TD size - number of bytes remaining in the TD (including this TRB): 792 /* TD size - number of bytes remaining in the TD (including this TRB):
793 * bits 17 - 21. Shift the number of bytes by 10. */ 793 * bits 17 - 21. Shift the number of bytes by 10. */
794 #define TD_REMAINDER(p) ((((p) >> 10) & 0x1f) << 17) 794 #define TD_REMAINDER(p) ((((p) >> 10) & 0x1f) << 17)
795 /* Interrupter Target - which MSI-X vector to target the completion event at */ 795 /* Interrupter Target - which MSI-X vector to target the completion event at */
796 #define TRB_INTR_TARGET(p) (((p) & 0x3ff) << 22) 796 #define TRB_INTR_TARGET(p) (((p) & 0x3ff) << 22)
797 #define GET_INTR_TARGET(p) (((p) >> 22) & 0x3ff) 797 #define GET_INTR_TARGET(p) (((p) >> 22) & 0x3ff)
798 798
799 /* Cycle bit - indicates TRB ownership by HC or HCD */ 799 /* Cycle bit - indicates TRB ownership by HC or HCD */
800 #define TRB_CYCLE (1<<0) 800 #define TRB_CYCLE (1<<0)
801 /* 801 /*
802 * Force next event data TRB to be evaluated before task switch. 802 * Force next event data TRB to be evaluated before task switch.
803 * Used to pass OS data back after a TD completes. 803 * Used to pass OS data back after a TD completes.
804 */ 804 */
805 #define TRB_ENT (1<<1) 805 #define TRB_ENT (1<<1)
806 /* Interrupt on short packet */ 806 /* Interrupt on short packet */
807 #define TRB_ISP (1<<2) 807 #define TRB_ISP (1<<2)
808 /* Set PCIe no snoop attribute */ 808 /* Set PCIe no snoop attribute */
809 #define TRB_NO_SNOOP (1<<3) 809 #define TRB_NO_SNOOP (1<<3)
810 /* Chain multiple TRBs into a TD */ 810 /* Chain multiple TRBs into a TD */
811 #define TRB_CHAIN (1<<4) 811 #define TRB_CHAIN (1<<4)
812 /* Interrupt on completion */ 812 /* Interrupt on completion */
813 #define TRB_IOC (1<<5) 813 #define TRB_IOC (1<<5)
814 /* The buffer pointer contains immediate data */ 814 /* The buffer pointer contains immediate data */
815 #define TRB_IDT (1<<6) 815 #define TRB_IDT (1<<6)
816 816
817 817
818 /* Control transfer TRB specific fields */ 818 /* Control transfer TRB specific fields */
819 #define TRB_DIR_IN (1<<16) 819 #define TRB_DIR_IN (1<<16)
820 820
821 struct xhci_generic_trb { 821 struct xhci_generic_trb {
822 u32 field[4]; 822 u32 field[4];
823 }; 823 };
824 824
825 union xhci_trb { 825 union xhci_trb {
826 struct xhci_link_trb link; 826 struct xhci_link_trb link;
827 struct xhci_transfer_event trans_event; 827 struct xhci_transfer_event trans_event;
828 struct xhci_event_cmd event_cmd; 828 struct xhci_event_cmd event_cmd;
829 struct xhci_generic_trb generic; 829 struct xhci_generic_trb generic;
830 }; 830 };
831 831
832 /* TRB bit mask */ 832 /* TRB bit mask */
833 #define TRB_TYPE_BITMASK (0xfc00) 833 #define TRB_TYPE_BITMASK (0xfc00)
834 #define TRB_TYPE(p) ((p) << 10) 834 #define TRB_TYPE(p) ((p) << 10)
835 /* TRB type IDs */ 835 /* TRB type IDs */
836 /* bulk, interrupt, isoc scatter/gather, and control data stage */ 836 /* bulk, interrupt, isoc scatter/gather, and control data stage */
837 #define TRB_NORMAL 1 837 #define TRB_NORMAL 1
838 /* setup stage for control transfers */ 838 /* setup stage for control transfers */
839 #define TRB_SETUP 2 839 #define TRB_SETUP 2
840 /* data stage for control transfers */ 840 /* data stage for control transfers */
841 #define TRB_DATA 3 841 #define TRB_DATA 3
842 /* status stage for control transfers */ 842 /* status stage for control transfers */
843 #define TRB_STATUS 4 843 #define TRB_STATUS 4
844 /* isoc transfers */ 844 /* isoc transfers */
845 #define TRB_ISOC 5 845 #define TRB_ISOC 5
846 /* TRB for linking ring segments */ 846 /* TRB for linking ring segments */
847 #define TRB_LINK 6 847 #define TRB_LINK 6
848 #define TRB_EVENT_DATA 7 848 #define TRB_EVENT_DATA 7
849 /* Transfer Ring No-op (not for the command ring) */ 849 /* Transfer Ring No-op (not for the command ring) */
850 #define TRB_TR_NOOP 8 850 #define TRB_TR_NOOP 8
851 /* Command TRBs */ 851 /* Command TRBs */
852 /* Enable Slot Command */ 852 /* Enable Slot Command */
853 #define TRB_ENABLE_SLOT 9 853 #define TRB_ENABLE_SLOT 9
854 /* Disable Slot Command */ 854 /* Disable Slot Command */
855 #define TRB_DISABLE_SLOT 10 855 #define TRB_DISABLE_SLOT 10
856 /* Address Device Command */ 856 /* Address Device Command */
857 #define TRB_ADDR_DEV 11 857 #define TRB_ADDR_DEV 11
858 /* Configure Endpoint Command */ 858 /* Configure Endpoint Command */
859 #define TRB_CONFIG_EP 12 859 #define TRB_CONFIG_EP 12
860 /* Evaluate Context Command */ 860 /* Evaluate Context Command */
861 #define TRB_EVAL_CONTEXT 13 861 #define TRB_EVAL_CONTEXT 13
862 /* Reset Endpoint Command */ 862 /* Reset Endpoint Command */
863 #define TRB_RESET_EP 14 863 #define TRB_RESET_EP 14
864 /* Stop Transfer Ring Command */ 864 /* Stop Transfer Ring Command */
865 #define TRB_STOP_RING 15 865 #define TRB_STOP_RING 15
866 /* Set Transfer Ring Dequeue Pointer Command */ 866 /* Set Transfer Ring Dequeue Pointer Command */
867 #define TRB_SET_DEQ 16 867 #define TRB_SET_DEQ 16
868 /* Reset Device Command */ 868 /* Reset Device Command */
869 #define TRB_RESET_DEV 17 869 #define TRB_RESET_DEV 17
870 /* Force Event Command (opt) */ 870 /* Force Event Command (opt) */
871 #define TRB_FORCE_EVENT 18 871 #define TRB_FORCE_EVENT 18
872 /* Negotiate Bandwidth Command (opt) */ 872 /* Negotiate Bandwidth Command (opt) */
873 #define TRB_NEG_BANDWIDTH 19 873 #define TRB_NEG_BANDWIDTH 19
874 /* Set Latency Tolerance Value Command (opt) */ 874 /* Set Latency Tolerance Value Command (opt) */
875 #define TRB_SET_LT 20 875 #define TRB_SET_LT 20
876 /* Get port bandwidth Command */ 876 /* Get port bandwidth Command */
877 #define TRB_GET_BW 21 877 #define TRB_GET_BW 21
878 /* Force Header Command - generate a transaction or link management packet */ 878 /* Force Header Command - generate a transaction or link management packet */
879 #define TRB_FORCE_HEADER 22 879 #define TRB_FORCE_HEADER 22
880 /* No-op Command - not for transfer rings */ 880 /* No-op Command - not for transfer rings */
881 #define TRB_CMD_NOOP 23 881 #define TRB_CMD_NOOP 23
882 /* TRB IDs 24-31 reserved */ 882 /* TRB IDs 24-31 reserved */
883 /* Event TRBS */ 883 /* Event TRBS */
884 /* Transfer Event */ 884 /* Transfer Event */
885 #define TRB_TRANSFER 32 885 #define TRB_TRANSFER 32
886 /* Command Completion Event */ 886 /* Command Completion Event */
887 #define TRB_COMPLETION 33 887 #define TRB_COMPLETION 33
888 /* Port Status Change Event */ 888 /* Port Status Change Event */
889 #define TRB_PORT_STATUS 34 889 #define TRB_PORT_STATUS 34
890 /* Bandwidth Request Event (opt) */ 890 /* Bandwidth Request Event (opt) */
891 #define TRB_BANDWIDTH_EVENT 35 891 #define TRB_BANDWIDTH_EVENT 35
892 /* Doorbell Event (opt) */ 892 /* Doorbell Event (opt) */
893 #define TRB_DOORBELL 36 893 #define TRB_DOORBELL 36
894 /* Host Controller Event */ 894 /* Host Controller Event */
895 #define TRB_HC_EVENT 37 895 #define TRB_HC_EVENT 37
896 /* Device Notification Event - device sent function wake notification */ 896 /* Device Notification Event - device sent function wake notification */
897 #define TRB_DEV_NOTE 38 897 #define TRB_DEV_NOTE 38
898 /* MFINDEX Wrap Event - microframe counter wrapped */ 898 /* MFINDEX Wrap Event - microframe counter wrapped */
899 #define TRB_MFINDEX_WRAP 39 899 #define TRB_MFINDEX_WRAP 39
900 /* TRB IDs 40-47 reserved, 48-63 is vendor-defined */ 900 /* TRB IDs 40-47 reserved, 48-63 is vendor-defined */
901 901
902 /* 902 /*
903 * TRBS_PER_SEGMENT must be a multiple of 4, 903 * TRBS_PER_SEGMENT must be a multiple of 4,
904 * since the command ring is 64-byte aligned. 904 * since the command ring is 64-byte aligned.
905 * It must also be greater than 16. 905 * It must also be greater than 16.
906 */ 906 */
907 #define TRBS_PER_SEGMENT 64 907 #define TRBS_PER_SEGMENT 64
908 #define SEGMENT_SIZE (TRBS_PER_SEGMENT*16) 908 #define SEGMENT_SIZE (TRBS_PER_SEGMENT*16)
909 /* TRB buffer pointers can't cross 64KB boundaries */ 909 /* TRB buffer pointers can't cross 64KB boundaries */
910 #define TRB_MAX_BUFF_SHIFT 16 910 #define TRB_MAX_BUFF_SHIFT 16
911 #define TRB_MAX_BUFF_SIZE (1 << TRB_MAX_BUFF_SHIFT) 911 #define TRB_MAX_BUFF_SIZE (1 << TRB_MAX_BUFF_SHIFT)
912 912
913 struct xhci_segment { 913 struct xhci_segment {
914 union xhci_trb *trbs; 914 union xhci_trb *trbs;
915 /* private to HCD */ 915 /* private to HCD */
916 struct xhci_segment *next; 916 struct xhci_segment *next;
917 dma_addr_t dma; 917 dma_addr_t dma;
918 }; 918 };
919 919
920 struct xhci_td { 920 struct xhci_td {
921 struct list_head td_list; 921 struct list_head td_list;
922 struct list_head cancelled_td_list; 922 struct list_head cancelled_td_list;
923 struct urb *urb; 923 struct urb *urb;
924 struct xhci_segment *start_seg; 924 struct xhci_segment *start_seg;
925 union xhci_trb *first_trb; 925 union xhci_trb *first_trb;
926 union xhci_trb *last_trb; 926 union xhci_trb *last_trb;
927 }; 927 };
928 928
929 struct xhci_ring { 929 struct xhci_ring {
930 struct xhci_segment *first_seg; 930 struct xhci_segment *first_seg;
931 union xhci_trb *enqueue; 931 union xhci_trb *enqueue;
932 struct xhci_segment *enq_seg; 932 struct xhci_segment *enq_seg;
933 unsigned int enq_updates; 933 unsigned int enq_updates;
934 union xhci_trb *dequeue; 934 union xhci_trb *dequeue;
935 struct xhci_segment *deq_seg; 935 struct xhci_segment *deq_seg;
936 unsigned int deq_updates; 936 unsigned int deq_updates;
937 struct list_head td_list; 937 struct list_head td_list;
938 /* ---- Related to URB cancellation ---- */ 938 /* ---- Related to URB cancellation ---- */
939 struct list_head cancelled_td_list; 939 struct list_head cancelled_td_list;
940 unsigned int cancels_pending; 940 unsigned int cancels_pending;
941 unsigned int state; 941 unsigned int state;
942 #define SET_DEQ_PENDING (1 << 0) 942 #define SET_DEQ_PENDING (1 << 0)
943 #define EP_HALTED (1 << 1) 943 #define EP_HALTED (1 << 1)
944 /* The TRB that was last reported in a stopped endpoint ring */ 944 /* The TRB that was last reported in a stopped endpoint ring */
945 union xhci_trb *stopped_trb; 945 union xhci_trb *stopped_trb;
946 struct xhci_td *stopped_td; 946 struct xhci_td *stopped_td;
947 /* 947 /*
948 * Write the cycle state into the TRB cycle field to give ownership of 948 * Write the cycle state into the TRB cycle field to give ownership of
949 * the TRB to the host controller (if we are the producer), or to check 949 * the TRB to the host controller (if we are the producer), or to check
950 * if we own the TRB (if we are the consumer). See section 4.9.1. 950 * if we own the TRB (if we are the consumer). See section 4.9.1.
951 */ 951 */
952 u32 cycle_state; 952 u32 cycle_state;
953 }; 953 };
954 954
955 struct xhci_dequeue_state { 955 struct xhci_dequeue_state {
956 struct xhci_segment *new_deq_seg; 956 struct xhci_segment *new_deq_seg;
957 union xhci_trb *new_deq_ptr; 957 union xhci_trb *new_deq_ptr;
958 int new_cycle_state; 958 int new_cycle_state;
959 }; 959 };
960 960
961 struct xhci_erst_entry { 961 struct xhci_erst_entry {
962 /* 64-bit event ring segment address */ 962 /* 64-bit event ring segment address */
963 u64 seg_addr; 963 u64 seg_addr;
964 u32 seg_size; 964 u32 seg_size;
965 /* Set to zero */ 965 /* Set to zero */
966 u32 rsvd; 966 u32 rsvd;
967 }; 967 };
968 968
969 struct xhci_erst { 969 struct xhci_erst {
970 struct xhci_erst_entry *entries; 970 struct xhci_erst_entry *entries;
971 unsigned int num_entries; 971 unsigned int num_entries;
972 /* xhci->event_ring keeps track of segment dma addresses */ 972 /* xhci->event_ring keeps track of segment dma addresses */
973 dma_addr_t erst_dma_addr; 973 dma_addr_t erst_dma_addr;
974 /* Num entries the ERST can contain */ 974 /* Num entries the ERST can contain */
975 unsigned int erst_size; 975 unsigned int erst_size;
976 }; 976 };
977 977
978 struct xhci_scratchpad { 978 struct xhci_scratchpad {
979 u64 *sp_array; 979 u64 *sp_array;
980 dma_addr_t sp_dma; 980 dma_addr_t sp_dma;
981 void **sp_buffers; 981 void **sp_buffers;
982 dma_addr_t *sp_dma_buffers; 982 dma_addr_t *sp_dma_buffers;
983 }; 983 };
984 984
985 /* 985 /*
986 * Each segment table entry is 4*32bits long. 1K seems like an ok size: 986 * Each segment table entry is 4*32bits long. 1K seems like an ok size:
987 * (1K bytes * 8bytes/bit) / (4*32 bits) = 64 segment entries in the table, 987 * (1K bytes * 8bytes/bit) / (4*32 bits) = 64 segment entries in the table,
988 * meaning 64 ring segments. 988 * meaning 64 ring segments.
989 * Initial allocated size of the ERST, in number of entries */ 989 * Initial allocated size of the ERST, in number of entries */
990 #define ERST_NUM_SEGS 1 990 #define ERST_NUM_SEGS 1
991 /* Initial allocated size of the ERST, in number of entries */ 991 /* Initial allocated size of the ERST, in number of entries */
992 #define ERST_SIZE 64 992 #define ERST_SIZE 64
993 /* Initial number of event segment rings allocated */ 993 /* Initial number of event segment rings allocated */
994 #define ERST_ENTRIES 1 994 #define ERST_ENTRIES 1
995 /* Poll every 60 seconds */ 995 /* Poll every 60 seconds */
996 #define POLL_TIMEOUT 60 996 #define POLL_TIMEOUT 60
997 /* XXX: Make these module parameters */ 997 /* XXX: Make these module parameters */
998 998
999 999
1000 /* There is one ehci_hci structure per controller */ 1000 /* There is one ehci_hci structure per controller */
1001 struct xhci_hcd { 1001 struct xhci_hcd {
1002 /* glue to PCI and HCD framework */ 1002 /* glue to PCI and HCD framework */
1003 struct xhci_cap_regs __iomem *cap_regs; 1003 struct xhci_cap_regs __iomem *cap_regs;
1004 struct xhci_op_regs __iomem *op_regs; 1004 struct xhci_op_regs __iomem *op_regs;
1005 struct xhci_run_regs __iomem *run_regs; 1005 struct xhci_run_regs __iomem *run_regs;
1006 struct xhci_doorbell_array __iomem *dba; 1006 struct xhci_doorbell_array __iomem *dba;
1007 /* Our HCD's current interrupter register set */ 1007 /* Our HCD's current interrupter register set */
1008 struct xhci_intr_reg __iomem *ir_set; 1008 struct xhci_intr_reg __iomem *ir_set;
1009 1009
1010 /* Cached register copies of read-only HC data */ 1010 /* Cached register copies of read-only HC data */
1011 __u32 hcs_params1; 1011 __u32 hcs_params1;
1012 __u32 hcs_params2; 1012 __u32 hcs_params2;
1013 __u32 hcs_params3; 1013 __u32 hcs_params3;
1014 __u32 hcc_params; 1014 __u32 hcc_params;
1015 1015
1016 spinlock_t lock; 1016 spinlock_t lock;
1017 1017
1018 /* packed release number */ 1018 /* packed release number */
1019 u8 sbrn; 1019 u8 sbrn;
1020 u16 hci_version; 1020 u16 hci_version;
1021 u8 max_slots; 1021 u8 max_slots;
1022 u8 max_interrupters; 1022 u8 max_interrupters;
1023 u8 max_ports; 1023 u8 max_ports;
1024 u8 isoc_threshold; 1024 u8 isoc_threshold;
1025 int event_ring_max; 1025 int event_ring_max;
1026 int addr_64; 1026 int addr_64;
1027 /* 4KB min, 128MB max */ 1027 /* 4KB min, 128MB max */
1028 int page_size; 1028 int page_size;
1029 /* Valid values are 12 to 20, inclusive */ 1029 /* Valid values are 12 to 20, inclusive */
1030 int page_shift; 1030 int page_shift;
1031 /* only one MSI vector for now, but might need more later */ 1031 /* only one MSI vector for now, but might need more later */
1032 int msix_count; 1032 int msix_count;
1033 struct msix_entry *msix_entries; 1033 struct msix_entry *msix_entries;
1034 /* data structures */ 1034 /* data structures */
1035 struct xhci_device_context_array *dcbaa; 1035 struct xhci_device_context_array *dcbaa;
1036 struct xhci_ring *cmd_ring; 1036 struct xhci_ring *cmd_ring;
1037 struct xhci_ring *event_ring; 1037 struct xhci_ring *event_ring;
1038 struct xhci_erst erst; 1038 struct xhci_erst erst;
1039 /* Scratchpad */ 1039 /* Scratchpad */
1040 struct xhci_scratchpad *scratchpad; 1040 struct xhci_scratchpad *scratchpad;
1041 1041
1042 /* slot enabling and address device helpers */ 1042 /* slot enabling and address device helpers */
1043 struct completion addr_dev; 1043 struct completion addr_dev;
1044 int slot_id; 1044 int slot_id;
1045 /* Internal mirror of the HW's dcbaa */ 1045 /* Internal mirror of the HW's dcbaa */
1046 struct xhci_virt_device *devs[MAX_HC_SLOTS]; 1046 struct xhci_virt_device *devs[MAX_HC_SLOTS];
1047 1047
1048 /* DMA pools */ 1048 /* DMA pools */
1049 struct dma_pool *device_pool; 1049 struct dma_pool *device_pool;
1050 struct dma_pool *segment_pool; 1050 struct dma_pool *segment_pool;
1051 1051
1052 #ifdef CONFIG_USB_XHCI_HCD_DEBUGGING 1052 #ifdef CONFIG_USB_XHCI_HCD_DEBUGGING
1053 /* Poll the rings - for debugging */ 1053 /* Poll the rings - for debugging */
1054 struct timer_list event_ring_timer; 1054 struct timer_list event_ring_timer;
1055 int zombie; 1055 int zombie;
1056 #endif 1056 #endif
1057 /* Statistics */ 1057 /* Statistics */
1058 int noops_submitted; 1058 int noops_submitted;
1059 int noops_handled; 1059 int noops_handled;
1060 int error_bitmask; 1060 int error_bitmask;
1061 }; 1061 };
1062 1062
1063 /* For testing purposes */ 1063 /* For testing purposes */
1064 #define NUM_TEST_NOOPS 0 1064 #define NUM_TEST_NOOPS 0
1065 1065
1066 /* convert between an HCD pointer and the corresponding EHCI_HCD */ 1066 /* convert between an HCD pointer and the corresponding EHCI_HCD */
1067 static inline struct xhci_hcd *hcd_to_xhci(struct usb_hcd *hcd) 1067 static inline struct xhci_hcd *hcd_to_xhci(struct usb_hcd *hcd)
1068 { 1068 {
1069 return (struct xhci_hcd *) (hcd->hcd_priv); 1069 return (struct xhci_hcd *) (hcd->hcd_priv);
1070 } 1070 }
1071 1071
1072 static inline struct usb_hcd *xhci_to_hcd(struct xhci_hcd *xhci) 1072 static inline struct usb_hcd *xhci_to_hcd(struct xhci_hcd *xhci)
1073 { 1073 {
1074 return container_of((void *) xhci, struct usb_hcd, hcd_priv); 1074 return container_of((void *) xhci, struct usb_hcd, hcd_priv);
1075 } 1075 }
1076 1076
1077 #ifdef CONFIG_USB_XHCI_HCD_DEBUGGING 1077 #ifdef CONFIG_USB_XHCI_HCD_DEBUGGING
1078 #define XHCI_DEBUG 1 1078 #define XHCI_DEBUG 1
1079 #else 1079 #else
1080 #define XHCI_DEBUG 0 1080 #define XHCI_DEBUG 0
1081 #endif 1081 #endif
1082 1082
1083 #define xhci_dbg(xhci, fmt, args...) \ 1083 #define xhci_dbg(xhci, fmt, args...) \
1084 do { if (XHCI_DEBUG) dev_dbg(xhci_to_hcd(xhci)->self.controller , fmt , ## args); } while (0) 1084 do { if (XHCI_DEBUG) dev_dbg(xhci_to_hcd(xhci)->self.controller , fmt , ## args); } while (0)
1085 #define xhci_info(xhci, fmt, args...) \ 1085 #define xhci_info(xhci, fmt, args...) \
1086 do { if (XHCI_DEBUG) dev_info(xhci_to_hcd(xhci)->self.controller , fmt , ## args); } while (0) 1086 do { if (XHCI_DEBUG) dev_info(xhci_to_hcd(xhci)->self.controller , fmt , ## args); } while (0)
1087 #define xhci_err(xhci, fmt, args...) \ 1087 #define xhci_err(xhci, fmt, args...) \
1088 dev_err(xhci_to_hcd(xhci)->self.controller , fmt , ## args) 1088 dev_err(xhci_to_hcd(xhci)->self.controller , fmt , ## args)
1089 #define xhci_warn(xhci, fmt, args...) \ 1089 #define xhci_warn(xhci, fmt, args...) \
1090 dev_warn(xhci_to_hcd(xhci)->self.controller , fmt , ## args) 1090 dev_warn(xhci_to_hcd(xhci)->self.controller , fmt , ## args)
1091 1091
1092 /* TODO: copied from ehci.h - can be refactored? */ 1092 /* TODO: copied from ehci.h - can be refactored? */
1093 /* xHCI spec says all registers are little endian */ 1093 /* xHCI spec says all registers are little endian */
1094 static inline unsigned int xhci_readl(const struct xhci_hcd *xhci, 1094 static inline unsigned int xhci_readl(const struct xhci_hcd *xhci,
1095 __u32 __iomem *regs) 1095 __u32 __iomem *regs)
1096 { 1096 {
1097 return readl(regs); 1097 return readl(regs);
1098 } 1098 }
1099 static inline void xhci_writel(struct xhci_hcd *xhci, 1099 static inline void xhci_writel(struct xhci_hcd *xhci,
1100 const unsigned int val, __u32 __iomem *regs) 1100 const unsigned int val, __u32 __iomem *regs)
1101 { 1101 {
1102 xhci_dbg(xhci, 1102 xhci_dbg(xhci,
1103 "`MEM_WRITE_DWORD(3'b000, 32'h%p, 32'h%0x, 4'hf);\n", 1103 "`MEM_WRITE_DWORD(3'b000, 32'h%p, 32'h%0x, 4'hf);\n",
1104 regs, val); 1104 regs, val);
1105 writel(val, regs); 1105 writel(val, regs);
1106 } 1106 }
1107 1107
1108 /* 1108 /*
1109 * Registers should always be accessed with double word or quad word accesses. 1109 * Registers should always be accessed with double word or quad word accesses.
1110 * 1110 *
1111 * Some xHCI implementations may support 64-bit address pointers. Registers 1111 * Some xHCI implementations may support 64-bit address pointers. Registers
1112 * with 64-bit address pointers should be written to with dword accesses by 1112 * with 64-bit address pointers should be written to with dword accesses by
1113 * writing the low dword first (ptr[0]), then the high dword (ptr[1]) second. 1113 * writing the low dword first (ptr[0]), then the high dword (ptr[1]) second.
1114 * xHCI implementations that do not support 64-bit address pointers will ignore 1114 * xHCI implementations that do not support 64-bit address pointers will ignore
1115 * the high dword, and write order is irrelevant. 1115 * the high dword, and write order is irrelevant.
1116 */ 1116 */
1117 static inline u64 xhci_read_64(const struct xhci_hcd *xhci, 1117 static inline u64 xhci_read_64(const struct xhci_hcd *xhci,
1118 __u64 __iomem *regs) 1118 __u64 __iomem *regs)
1119 { 1119 {
1120 __u32 __iomem *ptr = (__u32 __iomem *) regs; 1120 __u32 __iomem *ptr = (__u32 __iomem *) regs;
1121 u64 val_lo = readl(ptr); 1121 u64 val_lo = readl(ptr);
1122 u64 val_hi = readl(ptr + 1); 1122 u64 val_hi = readl(ptr + 1);
1123 return val_lo + (val_hi << 32); 1123 return val_lo + (val_hi << 32);
1124 } 1124 }
1125 static inline void xhci_write_64(struct xhci_hcd *xhci, 1125 static inline void xhci_write_64(struct xhci_hcd *xhci,
1126 const u64 val, __u64 __iomem *regs) 1126 const u64 val, __u64 __iomem *regs)
1127 { 1127 {
1128 __u32 __iomem *ptr = (__u32 __iomem *) regs; 1128 __u32 __iomem *ptr = (__u32 __iomem *) regs;
1129 u32 val_lo = lower_32_bits(val); 1129 u32 val_lo = lower_32_bits(val);
1130 u32 val_hi = upper_32_bits(val); 1130 u32 val_hi = upper_32_bits(val);
1131 1131
1132 xhci_dbg(xhci, 1132 xhci_dbg(xhci,
1133 "`MEM_WRITE_DWORD(3'b000, 64'h%p, 64'h%0lx, 4'hf);\n", 1133 "`MEM_WRITE_DWORD(3'b000, 64'h%p, 64'h%0lx, 4'hf);\n",
1134 regs, (long unsigned int) val); 1134 regs, (long unsigned int) val);
1135 writel(val_lo, ptr); 1135 writel(val_lo, ptr);
1136 writel(val_hi, ptr + 1); 1136 writel(val_hi, ptr + 1);
1137 } 1137 }
1138 1138
1139 /* xHCI debugging */ 1139 /* xHCI debugging */
1140 void xhci_print_ir_set(struct xhci_hcd *xhci, struct xhci_intr_reg *ir_set, int set_num); 1140 void xhci_print_ir_set(struct xhci_hcd *xhci, struct xhci_intr_reg *ir_set, int set_num);
1141 void xhci_print_registers(struct xhci_hcd *xhci); 1141 void xhci_print_registers(struct xhci_hcd *xhci);
1142 void xhci_dbg_regs(struct xhci_hcd *xhci); 1142 void xhci_dbg_regs(struct xhci_hcd *xhci);
1143 void xhci_print_run_regs(struct xhci_hcd *xhci); 1143 void xhci_print_run_regs(struct xhci_hcd *xhci);
1144 void xhci_print_trb_offsets(struct xhci_hcd *xhci, union xhci_trb *trb); 1144 void xhci_print_trb_offsets(struct xhci_hcd *xhci, union xhci_trb *trb);
1145 void xhci_debug_trb(struct xhci_hcd *xhci, union xhci_trb *trb); 1145 void xhci_debug_trb(struct xhci_hcd *xhci, union xhci_trb *trb);
1146 void xhci_debug_segment(struct xhci_hcd *xhci, struct xhci_segment *seg); 1146 void xhci_debug_segment(struct xhci_hcd *xhci, struct xhci_segment *seg);
1147 void xhci_debug_ring(struct xhci_hcd *xhci, struct xhci_ring *ring); 1147 void xhci_debug_ring(struct xhci_hcd *xhci, struct xhci_ring *ring);
1148 void xhci_dbg_erst(struct xhci_hcd *xhci, struct xhci_erst *erst); 1148 void xhci_dbg_erst(struct xhci_hcd *xhci, struct xhci_erst *erst);
1149 void xhci_dbg_cmd_ptrs(struct xhci_hcd *xhci); 1149 void xhci_dbg_cmd_ptrs(struct xhci_hcd *xhci);
1150 void xhci_dbg_ring_ptrs(struct xhci_hcd *xhci, struct xhci_ring *ring); 1150 void xhci_dbg_ring_ptrs(struct xhci_hcd *xhci, struct xhci_ring *ring);
1151 void xhci_dbg_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx, unsigned int last_ep); 1151 void xhci_dbg_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx, unsigned int last_ep);
1152 1152
1153 /* xHCI memory managment */ 1153 /* xHCI memory management */
1154 void xhci_mem_cleanup(struct xhci_hcd *xhci); 1154 void xhci_mem_cleanup(struct xhci_hcd *xhci);
1155 int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags); 1155 int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags);
1156 void xhci_free_virt_device(struct xhci_hcd *xhci, int slot_id); 1156 void xhci_free_virt_device(struct xhci_hcd *xhci, int slot_id);
1157 int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id, struct usb_device *udev, gfp_t flags); 1157 int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id, struct usb_device *udev, gfp_t flags);
1158 int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *udev); 1158 int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *udev);
1159 unsigned int xhci_get_endpoint_index(struct usb_endpoint_descriptor *desc); 1159 unsigned int xhci_get_endpoint_index(struct usb_endpoint_descriptor *desc);
1160 unsigned int xhci_get_endpoint_flag(struct usb_endpoint_descriptor *desc); 1160 unsigned int xhci_get_endpoint_flag(struct usb_endpoint_descriptor *desc);
1161 void xhci_endpoint_zero(struct xhci_hcd *xhci, struct xhci_virt_device *virt_dev, struct usb_host_endpoint *ep); 1161 void xhci_endpoint_zero(struct xhci_hcd *xhci, struct xhci_virt_device *virt_dev, struct usb_host_endpoint *ep);
1162 int xhci_endpoint_init(struct xhci_hcd *xhci, struct xhci_virt_device *virt_dev, 1162 int xhci_endpoint_init(struct xhci_hcd *xhci, struct xhci_virt_device *virt_dev,
1163 struct usb_device *udev, struct usb_host_endpoint *ep, 1163 struct usb_device *udev, struct usb_host_endpoint *ep,
1164 gfp_t mem_flags); 1164 gfp_t mem_flags);
1165 void xhci_ring_free(struct xhci_hcd *xhci, struct xhci_ring *ring); 1165 void xhci_ring_free(struct xhci_hcd *xhci, struct xhci_ring *ring);
1166 1166
1167 #ifdef CONFIG_PCI 1167 #ifdef CONFIG_PCI
1168 /* xHCI PCI glue */ 1168 /* xHCI PCI glue */
1169 int xhci_register_pci(void); 1169 int xhci_register_pci(void);
1170 void xhci_unregister_pci(void); 1170 void xhci_unregister_pci(void);
1171 #endif 1171 #endif
1172 1172
1173 /* xHCI host controller glue */ 1173 /* xHCI host controller glue */
1174 int xhci_halt(struct xhci_hcd *xhci); 1174 int xhci_halt(struct xhci_hcd *xhci);
1175 int xhci_reset(struct xhci_hcd *xhci); 1175 int xhci_reset(struct xhci_hcd *xhci);
1176 int xhci_init(struct usb_hcd *hcd); 1176 int xhci_init(struct usb_hcd *hcd);
1177 int xhci_run(struct usb_hcd *hcd); 1177 int xhci_run(struct usb_hcd *hcd);
1178 void xhci_stop(struct usb_hcd *hcd); 1178 void xhci_stop(struct usb_hcd *hcd);
1179 void xhci_shutdown(struct usb_hcd *hcd); 1179 void xhci_shutdown(struct usb_hcd *hcd);
1180 int xhci_get_frame(struct usb_hcd *hcd); 1180 int xhci_get_frame(struct usb_hcd *hcd);
1181 irqreturn_t xhci_irq(struct usb_hcd *hcd); 1181 irqreturn_t xhci_irq(struct usb_hcd *hcd);
1182 int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev); 1182 int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev);
1183 void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev); 1183 void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev);
1184 int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev); 1184 int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev);
1185 int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags); 1185 int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags);
1186 int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status); 1186 int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status);
1187 int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, struct usb_host_endpoint *ep); 1187 int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, struct usb_host_endpoint *ep);
1188 int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev, struct usb_host_endpoint *ep); 1188 int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev, struct usb_host_endpoint *ep);
1189 void xhci_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep); 1189 void xhci_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep);
1190 int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev); 1190 int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev);
1191 void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev); 1191 void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev);
1192 1192
1193 /* xHCI ring, segment, TRB, and TD functions */ 1193 /* xHCI ring, segment, TRB, and TD functions */
1194 dma_addr_t xhci_trb_virt_to_dma(struct xhci_segment *seg, union xhci_trb *trb); 1194 dma_addr_t xhci_trb_virt_to_dma(struct xhci_segment *seg, union xhci_trb *trb);
1195 void xhci_ring_cmd_db(struct xhci_hcd *xhci); 1195 void xhci_ring_cmd_db(struct xhci_hcd *xhci);
1196 void *xhci_setup_one_noop(struct xhci_hcd *xhci); 1196 void *xhci_setup_one_noop(struct xhci_hcd *xhci);
1197 void xhci_handle_event(struct xhci_hcd *xhci); 1197 void xhci_handle_event(struct xhci_hcd *xhci);
1198 void xhci_set_hc_event_deq(struct xhci_hcd *xhci); 1198 void xhci_set_hc_event_deq(struct xhci_hcd *xhci);
1199 int xhci_queue_slot_control(struct xhci_hcd *xhci, u32 trb_type, u32 slot_id); 1199 int xhci_queue_slot_control(struct xhci_hcd *xhci, u32 trb_type, u32 slot_id);
1200 int xhci_queue_address_device(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr, 1200 int xhci_queue_address_device(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr,
1201 u32 slot_id); 1201 u32 slot_id);
1202 int xhci_queue_stop_endpoint(struct xhci_hcd *xhci, int slot_id, 1202 int xhci_queue_stop_endpoint(struct xhci_hcd *xhci, int slot_id,
1203 unsigned int ep_index); 1203 unsigned int ep_index);
1204 int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags, struct urb *urb, 1204 int xhci_queue_ctrl_tx(struct xhci_hcd *xhci, gfp_t mem_flags, struct urb *urb,
1205 int slot_id, unsigned int ep_index); 1205 int slot_id, unsigned int ep_index);
1206 int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, struct urb *urb, 1206 int xhci_queue_bulk_tx(struct xhci_hcd *xhci, gfp_t mem_flags, struct urb *urb,
1207 int slot_id, unsigned int ep_index); 1207 int slot_id, unsigned int ep_index);
1208 int xhci_queue_configure_endpoint(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr, 1208 int xhci_queue_configure_endpoint(struct xhci_hcd *xhci, dma_addr_t in_ctx_ptr,
1209 u32 slot_id); 1209 u32 slot_id);
1210 int xhci_queue_reset_ep(struct xhci_hcd *xhci, int slot_id, 1210 int xhci_queue_reset_ep(struct xhci_hcd *xhci, int slot_id,
1211 unsigned int ep_index); 1211 unsigned int ep_index);
1212 void xhci_find_new_dequeue_state(struct xhci_hcd *xhci, 1212 void xhci_find_new_dequeue_state(struct xhci_hcd *xhci,
1213 unsigned int slot_id, unsigned int ep_index, 1213 unsigned int slot_id, unsigned int ep_index,
1214 struct xhci_td *cur_td, struct xhci_dequeue_state *state); 1214 struct xhci_td *cur_td, struct xhci_dequeue_state *state);
1215 void xhci_queue_new_dequeue_state(struct xhci_hcd *xhci, 1215 void xhci_queue_new_dequeue_state(struct xhci_hcd *xhci,
1216 struct xhci_ring *ep_ring, unsigned int slot_id, 1216 struct xhci_ring *ep_ring, unsigned int slot_id,
1217 unsigned int ep_index, struct xhci_dequeue_state *deq_state); 1217 unsigned int ep_index, struct xhci_dequeue_state *deq_state);
1218 1218
1219 /* xHCI roothub code */ 1219 /* xHCI roothub code */
1220 int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex, 1220 int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex,
1221 char *buf, u16 wLength); 1221 char *buf, u16 wLength);
1222 int xhci_hub_status_data(struct usb_hcd *hcd, char *buf); 1222 int xhci_hub_status_data(struct usb_hcd *hcd, char *buf);
1223 1223
1224 /* xHCI contexts */ 1224 /* xHCI contexts */
1225 struct xhci_input_control_ctx *xhci_get_input_control_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx); 1225 struct xhci_input_control_ctx *xhci_get_input_control_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx);
1226 struct xhci_slot_ctx *xhci_get_slot_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx); 1226 struct xhci_slot_ctx *xhci_get_slot_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx);
1227 struct xhci_ep_ctx *xhci_get_ep_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx, unsigned int ep_index); 1227 struct xhci_ep_ctx *xhci_get_ep_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx, unsigned int ep_index);
1228 1228
1229 #endif /* __LINUX_XHCI_HCD_H */ 1229 #endif /* __LINUX_XHCI_HCD_H */
1230 1230
drivers/usb/wusbcore/wa-hc.h
1 /* 1 /*
2 * HWA Host Controller Driver 2 * HWA Host Controller Driver
3 * Wire Adapter Control/Data Streaming Iface (WUSB1.0[8]) 3 * Wire Adapter Control/Data Streaming Iface (WUSB1.0[8])
4 * 4 *
5 * Copyright (C) 2005-2006 Intel Corporation 5 * Copyright (C) 2005-2006 Intel Corporation
6 * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com> 6 * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
7 * 7 *
8 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License version 9 * modify it under the terms of the GNU General Public License version
10 * 2 as published by the Free Software Foundation. 10 * 2 as published by the Free Software Foundation.
11 * 11 *
12 * This program is distributed in the hope that it will be useful, 12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details. 15 * GNU General Public License for more details.
16 * 16 *
17 * You should have received a copy of the GNU General Public License 17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software 18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301, USA. 20 * 02110-1301, USA.
21 * 21 *
22 * 22 *
23 * This driver implements a USB Host Controller (struct usb_hcd) for a 23 * This driver implements a USB Host Controller (struct usb_hcd) for a
24 * Wireless USB Host Controller based on the Wireless USB 1.0 24 * Wireless USB Host Controller based on the Wireless USB 1.0
25 * Host-Wire-Adapter specification (in layman terms, a USB-dongle that 25 * Host-Wire-Adapter specification (in layman terms, a USB-dongle that
26 * implements a Wireless USB host). 26 * implements a Wireless USB host).
27 * 27 *
28 * Check out the Design-overview.txt file in the source documentation 28 * Check out the Design-overview.txt file in the source documentation
29 * for other details on the implementation. 29 * for other details on the implementation.
30 * 30 *
31 * Main blocks: 31 * Main blocks:
32 * 32 *
33 * driver glue with the driver API, workqueue daemon 33 * driver glue with the driver API, workqueue daemon
34 * 34 *
35 * lc RC instance life cycle management (create, destroy...) 35 * lc RC instance life cycle management (create, destroy...)
36 * 36 *
37 * hcd glue with the USB API Host Controller Interface API. 37 * hcd glue with the USB API Host Controller Interface API.
38 * 38 *
39 * nep Notification EndPoint managent: collect notifications 39 * nep Notification EndPoint managent: collect notifications
40 * and queue them with the workqueue daemon. 40 * and queue them with the workqueue daemon.
41 * 41 *
42 * Handle notifications as coming from the NEP. Sends them 42 * Handle notifications as coming from the NEP. Sends them
43 * off others to their respective modules (eg: connect, 43 * off others to their respective modules (eg: connect,
44 * disconnect and reset go to devconnect). 44 * disconnect and reset go to devconnect).
45 * 45 *
46 * rpipe Remote Pipe management; rpipe is what we use to write 46 * rpipe Remote Pipe management; rpipe is what we use to write
47 * to an endpoint on a WUSB device that is connected to a 47 * to an endpoint on a WUSB device that is connected to a
48 * HWA RC. 48 * HWA RC.
49 * 49 *
50 * xfer Transfer managment -- this is all the code that gets a 50 * xfer Transfer management -- this is all the code that gets a
51 * buffer and pushes it to a device (or viceversa). * 51 * buffer and pushes it to a device (or viceversa). *
52 * 52 *
53 * Some day a lot of this code will be shared between this driver and 53 * Some day a lot of this code will be shared between this driver and
54 * the drivers for DWA (xfer, rpipe). 54 * the drivers for DWA (xfer, rpipe).
55 * 55 *
56 * All starts at driver.c:hwahc_probe(), when one of this guys is 56 * All starts at driver.c:hwahc_probe(), when one of this guys is
57 * connected. hwahc_disconnect() stops it. 57 * connected. hwahc_disconnect() stops it.
58 * 58 *
59 * During operation, the main driver is devices connecting or 59 * During operation, the main driver is devices connecting or
60 * disconnecting. They cause the HWA RC to send notifications into 60 * disconnecting. They cause the HWA RC to send notifications into
61 * nep.c:hwahc_nep_cb() that will dispatch them to 61 * nep.c:hwahc_nep_cb() that will dispatch them to
62 * notif.c:wa_notif_dispatch(). From there they will fan to cause 62 * notif.c:wa_notif_dispatch(). From there they will fan to cause
63 * device connects, disconnects, etc. 63 * device connects, disconnects, etc.
64 * 64 *
65 * Note much of the activity is difficult to follow. For example a 65 * Note much of the activity is difficult to follow. For example a
66 * device connect goes to devconnect, which will cause the "fake" root 66 * device connect goes to devconnect, which will cause the "fake" root
67 * hub port to show a connect and stop there. Then khubd will notice 67 * hub port to show a connect and stop there. Then khubd will notice
68 * and call into the rh.c:hwahc_rc_port_reset() code to authenticate 68 * and call into the rh.c:hwahc_rc_port_reset() code to authenticate
69 * the device (and this might require user intervention) and enable 69 * the device (and this might require user intervention) and enable
70 * the port. 70 * the port.
71 * 71 *
72 * We also have a timer workqueue going from devconnect.c that 72 * We also have a timer workqueue going from devconnect.c that
73 * schedules in hwahc_devconnect_create(). 73 * schedules in hwahc_devconnect_create().
74 * 74 *
75 * The rest of the traffic is in the usual entry points of a USB HCD, 75 * The rest of the traffic is in the usual entry points of a USB HCD,
76 * which are hooked up in driver.c:hwahc_rc_driver, and defined in 76 * which are hooked up in driver.c:hwahc_rc_driver, and defined in
77 * hcd.c. 77 * hcd.c.
78 */ 78 */
79 79
80 #ifndef __HWAHC_INTERNAL_H__ 80 #ifndef __HWAHC_INTERNAL_H__
81 #define __HWAHC_INTERNAL_H__ 81 #define __HWAHC_INTERNAL_H__
82 82
83 #include <linux/completion.h> 83 #include <linux/completion.h>
84 #include <linux/usb.h> 84 #include <linux/usb.h>
85 #include <linux/mutex.h> 85 #include <linux/mutex.h>
86 #include <linux/spinlock.h> 86 #include <linux/spinlock.h>
87 #include <linux/uwb.h> 87 #include <linux/uwb.h>
88 #include <linux/usb/wusb.h> 88 #include <linux/usb/wusb.h>
89 #include <linux/usb/wusb-wa.h> 89 #include <linux/usb/wusb-wa.h>
90 90
91 struct wusbhc; 91 struct wusbhc;
92 struct wahc; 92 struct wahc;
93 extern void wa_urb_enqueue_run(struct work_struct *ws); 93 extern void wa_urb_enqueue_run(struct work_struct *ws);
94 94
95 /** 95 /**
96 * RPipe instance 96 * RPipe instance
97 * 97 *
98 * @descr's fields are kept in LE, as we need to send it back and 98 * @descr's fields are kept in LE, as we need to send it back and
99 * forth. 99 * forth.
100 * 100 *
101 * @wa is referenced when set 101 * @wa is referenced when set
102 * 102 *
103 * @segs_available is the number of requests segments that still can 103 * @segs_available is the number of requests segments that still can
104 * be submitted to the controller without overloading 104 * be submitted to the controller without overloading
105 * it. It is initialized to descr->wRequests when 105 * it. It is initialized to descr->wRequests when
106 * aiming. 106 * aiming.
107 * 107 *
108 * A rpipe supports a max of descr->wRequests at the same time; before 108 * A rpipe supports a max of descr->wRequests at the same time; before
109 * submitting seg_lock has to be taken. If segs_avail > 0, then we can 109 * submitting seg_lock has to be taken. If segs_avail > 0, then we can
110 * submit; if not, we have to queue them. 110 * submit; if not, we have to queue them.
111 */ 111 */
112 struct wa_rpipe { 112 struct wa_rpipe {
113 struct kref refcnt; 113 struct kref refcnt;
114 struct usb_rpipe_descriptor descr; 114 struct usb_rpipe_descriptor descr;
115 struct usb_host_endpoint *ep; 115 struct usb_host_endpoint *ep;
116 struct wahc *wa; 116 struct wahc *wa;
117 spinlock_t seg_lock; 117 spinlock_t seg_lock;
118 struct list_head seg_list; 118 struct list_head seg_list;
119 atomic_t segs_available; 119 atomic_t segs_available;
120 u8 buffer[1]; /* For reads/writes on USB */ 120 u8 buffer[1]; /* For reads/writes on USB */
121 }; 121 };
122 122
123 123
124 /** 124 /**
125 * Instance of a HWA Host Controller 125 * Instance of a HWA Host Controller
126 * 126 *
127 * Except where a more specific lock/mutex applies or atomic, all 127 * Except where a more specific lock/mutex applies or atomic, all
128 * fields protected by @mutex. 128 * fields protected by @mutex.
129 * 129 *
130 * @wa_descr Can be accessed without locking because it is in 130 * @wa_descr Can be accessed without locking because it is in
131 * the same area where the device descriptors were 131 * the same area where the device descriptors were
132 * read, so it is guaranteed to exist umodified while 132 * read, so it is guaranteed to exist umodified while
133 * the device exists. 133 * the device exists.
134 * 134 *
135 * Endianess has been converted to CPU's. 135 * Endianess has been converted to CPU's.
136 * 136 *
137 * @nep_* can be accessed without locking as its processing is 137 * @nep_* can be accessed without locking as its processing is
138 * serialized; we submit a NEP URB and it comes to 138 * serialized; we submit a NEP URB and it comes to
139 * hwahc_nep_cb(), which won't issue another URB until it is 139 * hwahc_nep_cb(), which won't issue another URB until it is
140 * done processing it. 140 * done processing it.
141 * 141 *
142 * @xfer_list: 142 * @xfer_list:
143 * 143 *
144 * List of active transfers to verify existence from a xfer id 144 * List of active transfers to verify existence from a xfer id
145 * gotten from the xfer result message. Can't use urb->list because 145 * gotten from the xfer result message. Can't use urb->list because
146 * it goes by endpoint, and we don't know the endpoint at the time 146 * it goes by endpoint, and we don't know the endpoint at the time
147 * when we get the xfer result message. We can't really rely on the 147 * when we get the xfer result message. We can't really rely on the
148 * pointer (will have to change for 64 bits) as the xfer id is 32 bits. 148 * pointer (will have to change for 64 bits) as the xfer id is 32 bits.
149 * 149 *
150 * @xfer_delayed_list: List of transfers that need to be started 150 * @xfer_delayed_list: List of transfers that need to be started
151 * (with a workqueue, because they were 151 * (with a workqueue, because they were
152 * submitted from an atomic context). 152 * submitted from an atomic context).
153 * 153 *
154 * FIXME: this needs to be layered up: a wusbhc layer (for sharing 154 * FIXME: this needs to be layered up: a wusbhc layer (for sharing
155 * comonalities with WHCI), a wa layer (for sharing 155 * comonalities with WHCI), a wa layer (for sharing
156 * comonalities with DWA-RC). 156 * comonalities with DWA-RC).
157 */ 157 */
158 struct wahc { 158 struct wahc {
159 struct usb_device *usb_dev; 159 struct usb_device *usb_dev;
160 struct usb_interface *usb_iface; 160 struct usb_interface *usb_iface;
161 161
162 /* HC to deliver notifications */ 162 /* HC to deliver notifications */
163 union { 163 union {
164 struct wusbhc *wusb; 164 struct wusbhc *wusb;
165 struct dwahc *dwa; 165 struct dwahc *dwa;
166 }; 166 };
167 167
168 const struct usb_endpoint_descriptor *dto_epd, *dti_epd; 168 const struct usb_endpoint_descriptor *dto_epd, *dti_epd;
169 const struct usb_wa_descriptor *wa_descr; 169 const struct usb_wa_descriptor *wa_descr;
170 170
171 struct urb *nep_urb; /* Notification EndPoint [lockless] */ 171 struct urb *nep_urb; /* Notification EndPoint [lockless] */
172 struct edc nep_edc; 172 struct edc nep_edc;
173 void *nep_buffer; 173 void *nep_buffer;
174 size_t nep_buffer_size; 174 size_t nep_buffer_size;
175 175
176 atomic_t notifs_queued; 176 atomic_t notifs_queued;
177 177
178 u16 rpipes; 178 u16 rpipes;
179 unsigned long *rpipe_bm; /* rpipe usage bitmap */ 179 unsigned long *rpipe_bm; /* rpipe usage bitmap */
180 spinlock_t rpipe_bm_lock; /* protect rpipe_bm */ 180 spinlock_t rpipe_bm_lock; /* protect rpipe_bm */
181 struct mutex rpipe_mutex; /* assigning resources to endpoints */ 181 struct mutex rpipe_mutex; /* assigning resources to endpoints */
182 182
183 struct urb *dti_urb; /* URB for reading xfer results */ 183 struct urb *dti_urb; /* URB for reading xfer results */
184 struct urb *buf_in_urb; /* URB for reading data in */ 184 struct urb *buf_in_urb; /* URB for reading data in */
185 struct edc dti_edc; /* DTI error density counter */ 185 struct edc dti_edc; /* DTI error density counter */
186 struct wa_xfer_result *xfer_result; /* real size = dti_ep maxpktsize */ 186 struct wa_xfer_result *xfer_result; /* real size = dti_ep maxpktsize */
187 size_t xfer_result_size; 187 size_t xfer_result_size;
188 188
189 s32 status; /* For reading status */ 189 s32 status; /* For reading status */
190 190
191 struct list_head xfer_list; 191 struct list_head xfer_list;
192 struct list_head xfer_delayed_list; 192 struct list_head xfer_delayed_list;
193 spinlock_t xfer_list_lock; 193 spinlock_t xfer_list_lock;
194 struct work_struct xfer_work; 194 struct work_struct xfer_work;
195 atomic_t xfer_id_count; 195 atomic_t xfer_id_count;
196 }; 196 };
197 197
198 198
199 extern int wa_create(struct wahc *wa, struct usb_interface *iface); 199 extern int wa_create(struct wahc *wa, struct usb_interface *iface);
200 extern void __wa_destroy(struct wahc *wa); 200 extern void __wa_destroy(struct wahc *wa);
201 void wa_reset_all(struct wahc *wa); 201 void wa_reset_all(struct wahc *wa);
202 202
203 203
204 /* Miscellaneous constants */ 204 /* Miscellaneous constants */
205 enum { 205 enum {
206 /** Max number of EPROTO errors we tolerate on the NEP in a 206 /** Max number of EPROTO errors we tolerate on the NEP in a
207 * period of time */ 207 * period of time */
208 HWAHC_EPROTO_MAX = 16, 208 HWAHC_EPROTO_MAX = 16,
209 /** Period of time for EPROTO errors (in jiffies) */ 209 /** Period of time for EPROTO errors (in jiffies) */
210 HWAHC_EPROTO_PERIOD = 4 * HZ, 210 HWAHC_EPROTO_PERIOD = 4 * HZ,
211 }; 211 };
212 212
213 213
214 /* Notification endpoint handling */ 214 /* Notification endpoint handling */
215 extern int wa_nep_create(struct wahc *, struct usb_interface *); 215 extern int wa_nep_create(struct wahc *, struct usb_interface *);
216 extern void wa_nep_destroy(struct wahc *); 216 extern void wa_nep_destroy(struct wahc *);
217 217
218 static inline int wa_nep_arm(struct wahc *wa, gfp_t gfp_mask) 218 static inline int wa_nep_arm(struct wahc *wa, gfp_t gfp_mask)
219 { 219 {
220 struct urb *urb = wa->nep_urb; 220 struct urb *urb = wa->nep_urb;
221 urb->transfer_buffer = wa->nep_buffer; 221 urb->transfer_buffer = wa->nep_buffer;
222 urb->transfer_buffer_length = wa->nep_buffer_size; 222 urb->transfer_buffer_length = wa->nep_buffer_size;
223 return usb_submit_urb(urb, gfp_mask); 223 return usb_submit_urb(urb, gfp_mask);
224 } 224 }
225 225
226 static inline void wa_nep_disarm(struct wahc *wa) 226 static inline void wa_nep_disarm(struct wahc *wa)
227 { 227 {
228 usb_kill_urb(wa->nep_urb); 228 usb_kill_urb(wa->nep_urb);
229 } 229 }
230 230
231 231
232 /* RPipes */ 232 /* RPipes */
233 static inline void wa_rpipe_init(struct wahc *wa) 233 static inline void wa_rpipe_init(struct wahc *wa)
234 { 234 {
235 spin_lock_init(&wa->rpipe_bm_lock); 235 spin_lock_init(&wa->rpipe_bm_lock);
236 mutex_init(&wa->rpipe_mutex); 236 mutex_init(&wa->rpipe_mutex);
237 } 237 }
238 238
239 static inline void wa_init(struct wahc *wa) 239 static inline void wa_init(struct wahc *wa)
240 { 240 {
241 edc_init(&wa->nep_edc); 241 edc_init(&wa->nep_edc);
242 atomic_set(&wa->notifs_queued, 0); 242 atomic_set(&wa->notifs_queued, 0);
243 wa_rpipe_init(wa); 243 wa_rpipe_init(wa);
244 edc_init(&wa->dti_edc); 244 edc_init(&wa->dti_edc);
245 INIT_LIST_HEAD(&wa->xfer_list); 245 INIT_LIST_HEAD(&wa->xfer_list);
246 INIT_LIST_HEAD(&wa->xfer_delayed_list); 246 INIT_LIST_HEAD(&wa->xfer_delayed_list);
247 spin_lock_init(&wa->xfer_list_lock); 247 spin_lock_init(&wa->xfer_list_lock);
248 INIT_WORK(&wa->xfer_work, wa_urb_enqueue_run); 248 INIT_WORK(&wa->xfer_work, wa_urb_enqueue_run);
249 atomic_set(&wa->xfer_id_count, 1); 249 atomic_set(&wa->xfer_id_count, 1);
250 } 250 }
251 251
252 /** 252 /**
253 * Destroy a pipe (when refcount drops to zero) 253 * Destroy a pipe (when refcount drops to zero)
254 * 254 *
255 * Assumes it has been moved to the "QUIESCING" state. 255 * Assumes it has been moved to the "QUIESCING" state.
256 */ 256 */
257 struct wa_xfer; 257 struct wa_xfer;
258 extern void rpipe_destroy(struct kref *_rpipe); 258 extern void rpipe_destroy(struct kref *_rpipe);
259 static inline 259 static inline
260 void __rpipe_get(struct wa_rpipe *rpipe) 260 void __rpipe_get(struct wa_rpipe *rpipe)
261 { 261 {
262 kref_get(&rpipe->refcnt); 262 kref_get(&rpipe->refcnt);
263 } 263 }
264 extern int rpipe_get_by_ep(struct wahc *, struct usb_host_endpoint *, 264 extern int rpipe_get_by_ep(struct wahc *, struct usb_host_endpoint *,
265 struct urb *, gfp_t); 265 struct urb *, gfp_t);
266 static inline void rpipe_put(struct wa_rpipe *rpipe) 266 static inline void rpipe_put(struct wa_rpipe *rpipe)
267 { 267 {
268 kref_put(&rpipe->refcnt, rpipe_destroy); 268 kref_put(&rpipe->refcnt, rpipe_destroy);
269 269
270 } 270 }
271 extern void rpipe_ep_disable(struct wahc *, struct usb_host_endpoint *); 271 extern void rpipe_ep_disable(struct wahc *, struct usb_host_endpoint *);
272 extern int wa_rpipes_create(struct wahc *); 272 extern int wa_rpipes_create(struct wahc *);
273 extern void wa_rpipes_destroy(struct wahc *); 273 extern void wa_rpipes_destroy(struct wahc *);
274 static inline void rpipe_avail_dec(struct wa_rpipe *rpipe) 274 static inline void rpipe_avail_dec(struct wa_rpipe *rpipe)
275 { 275 {
276 atomic_dec(&rpipe->segs_available); 276 atomic_dec(&rpipe->segs_available);
277 } 277 }
278 278
279 /** 279 /**
280 * Returns true if the rpipe is ready to submit more segments. 280 * Returns true if the rpipe is ready to submit more segments.
281 */ 281 */
282 static inline int rpipe_avail_inc(struct wa_rpipe *rpipe) 282 static inline int rpipe_avail_inc(struct wa_rpipe *rpipe)
283 { 283 {
284 return atomic_inc_return(&rpipe->segs_available) > 0 284 return atomic_inc_return(&rpipe->segs_available) > 0
285 && !list_empty(&rpipe->seg_list); 285 && !list_empty(&rpipe->seg_list);
286 } 286 }
287 287
288 288
289 /* Transferring data */ 289 /* Transferring data */
290 extern int wa_urb_enqueue(struct wahc *, struct usb_host_endpoint *, 290 extern int wa_urb_enqueue(struct wahc *, struct usb_host_endpoint *,
291 struct urb *, gfp_t); 291 struct urb *, gfp_t);
292 extern int wa_urb_dequeue(struct wahc *, struct urb *); 292 extern int wa_urb_dequeue(struct wahc *, struct urb *);
293 extern void wa_handle_notif_xfer(struct wahc *, struct wa_notif_hdr *); 293 extern void wa_handle_notif_xfer(struct wahc *, struct wa_notif_hdr *);
294 294
295 295
296 /* Misc 296 /* Misc
297 * 297 *
298 * FIXME: Refcounting for the actual @hwahc object is not correct; I 298 * FIXME: Refcounting for the actual @hwahc object is not correct; I
299 * mean, this should be refcounting on the HCD underneath, but 299 * mean, this should be refcounting on the HCD underneath, but
300 * it is not. In any case, the semantics for HCD refcounting 300 * it is not. In any case, the semantics for HCD refcounting
301 * are *weird*...on refcount reaching zero it just frees 301 * are *weird*...on refcount reaching zero it just frees
302 * it...no RC specific function is called...unless I miss 302 * it...no RC specific function is called...unless I miss
303 * something. 303 * something.
304 * 304 *
305 * FIXME: has to go away in favour of an 'struct' hcd based sollution 305 * FIXME: has to go away in favour of an 'struct' hcd based sollution
306 */ 306 */
307 static inline struct wahc *wa_get(struct wahc *wa) 307 static inline struct wahc *wa_get(struct wahc *wa)
308 { 308 {
309 usb_get_intf(wa->usb_iface); 309 usb_get_intf(wa->usb_iface);
310 return wa; 310 return wa;
311 } 311 }
312 312
313 static inline void wa_put(struct wahc *wa) 313 static inline void wa_put(struct wahc *wa)
314 { 314 {
315 usb_put_intf(wa->usb_iface); 315 usb_put_intf(wa->usb_iface);
316 } 316 }
317 317
318 318
319 static inline int __wa_feature(struct wahc *wa, unsigned op, u16 feature) 319 static inline int __wa_feature(struct wahc *wa, unsigned op, u16 feature)
320 { 320 {
321 return usb_control_msg(wa->usb_dev, usb_sndctrlpipe(wa->usb_dev, 0), 321 return usb_control_msg(wa->usb_dev, usb_sndctrlpipe(wa->usb_dev, 0),
322 op ? USB_REQ_SET_FEATURE : USB_REQ_CLEAR_FEATURE, 322 op ? USB_REQ_SET_FEATURE : USB_REQ_CLEAR_FEATURE,
323 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, 323 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
324 feature, 324 feature,
325 wa->usb_iface->cur_altsetting->desc.bInterfaceNumber, 325 wa->usb_iface->cur_altsetting->desc.bInterfaceNumber,
326 NULL, 0, 1000 /* FIXME: arbitrary */); 326 NULL, 0, 1000 /* FIXME: arbitrary */);
327 } 327 }
328 328
329 329
330 static inline int __wa_set_feature(struct wahc *wa, u16 feature) 330 static inline int __wa_set_feature(struct wahc *wa, u16 feature)
331 { 331 {
332 return __wa_feature(wa, 1, feature); 332 return __wa_feature(wa, 1, feature);
333 } 333 }
334 334
335 335
336 static inline int __wa_clear_feature(struct wahc *wa, u16 feature) 336 static inline int __wa_clear_feature(struct wahc *wa, u16 feature)
337 { 337 {
338 return __wa_feature(wa, 0, feature); 338 return __wa_feature(wa, 0, feature);
339 } 339 }
340 340
341 341
342 /** 342 /**
343 * Return the status of a Wire Adapter 343 * Return the status of a Wire Adapter
344 * 344 *
345 * @wa: Wire Adapter instance 345 * @wa: Wire Adapter instance
346 * @returns < 0 errno code on error, or status bitmap as described 346 * @returns < 0 errno code on error, or status bitmap as described
347 * in WUSB1.0[8.3.1.6]. 347 * in WUSB1.0[8.3.1.6].
348 * 348 *
349 * NOTE: need malloc, some arches don't take USB from the stack 349 * NOTE: need malloc, some arches don't take USB from the stack
350 */ 350 */
351 static inline 351 static inline
352 s32 __wa_get_status(struct wahc *wa) 352 s32 __wa_get_status(struct wahc *wa)
353 { 353 {
354 s32 result; 354 s32 result;
355 result = usb_control_msg( 355 result = usb_control_msg(
356 wa->usb_dev, usb_rcvctrlpipe(wa->usb_dev, 0), 356 wa->usb_dev, usb_rcvctrlpipe(wa->usb_dev, 0),
357 USB_REQ_GET_STATUS, 357 USB_REQ_GET_STATUS,
358 USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, 358 USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
359 0, wa->usb_iface->cur_altsetting->desc.bInterfaceNumber, 359 0, wa->usb_iface->cur_altsetting->desc.bInterfaceNumber,
360 &wa->status, sizeof(wa->status), 360 &wa->status, sizeof(wa->status),
361 1000 /* FIXME: arbitrary */); 361 1000 /* FIXME: arbitrary */);
362 if (result >= 0) 362 if (result >= 0)
363 result = wa->status; 363 result = wa->status;
364 return result; 364 return result;
365 } 365 }
366 366
367 367
368 /** 368 /**
369 * Waits until the Wire Adapter's status matches @mask/@value 369 * Waits until the Wire Adapter's status matches @mask/@value
370 * 370 *
371 * @wa: Wire Adapter instance. 371 * @wa: Wire Adapter instance.
372 * @returns < 0 errno code on error, otherwise status. 372 * @returns < 0 errno code on error, otherwise status.
373 * 373 *
374 * Loop until the WAs status matches the mask and value (status & mask 374 * Loop until the WAs status matches the mask and value (status & mask
375 * == value). Timeout if it doesn't happen. 375 * == value). Timeout if it doesn't happen.
376 * 376 *
377 * FIXME: is there an official specification on how long status 377 * FIXME: is there an official specification on how long status
378 * changes can take? 378 * changes can take?
379 */ 379 */
380 static inline s32 __wa_wait_status(struct wahc *wa, u32 mask, u32 value) 380 static inline s32 __wa_wait_status(struct wahc *wa, u32 mask, u32 value)
381 { 381 {
382 s32 result; 382 s32 result;
383 unsigned loops = 10; 383 unsigned loops = 10;
384 do { 384 do {
385 msleep(50); 385 msleep(50);
386 result = __wa_get_status(wa); 386 result = __wa_get_status(wa);
387 if ((result & mask) == value) 387 if ((result & mask) == value)
388 break; 388 break;
389 if (loops-- == 0) { 389 if (loops-- == 0) {
390 result = -ETIMEDOUT; 390 result = -ETIMEDOUT;
391 break; 391 break;
392 } 392 }
393 } while (result >= 0); 393 } while (result >= 0);
394 return result; 394 return result;
395 } 395 }
396 396
397 397
398 /** Command @hwahc to stop, @returns 0 if ok, < 0 errno code on error */ 398 /** Command @hwahc to stop, @returns 0 if ok, < 0 errno code on error */
399 static inline int __wa_stop(struct wahc *wa) 399 static inline int __wa_stop(struct wahc *wa)
400 { 400 {
401 int result; 401 int result;
402 struct device *dev = &wa->usb_iface->dev; 402 struct device *dev = &wa->usb_iface->dev;
403 403
404 result = __wa_clear_feature(wa, WA_ENABLE); 404 result = __wa_clear_feature(wa, WA_ENABLE);
405 if (result < 0 && result != -ENODEV) { 405 if (result < 0 && result != -ENODEV) {
406 dev_err(dev, "error commanding HC to stop: %d\n", result); 406 dev_err(dev, "error commanding HC to stop: %d\n", result);
407 goto out; 407 goto out;
408 } 408 }
409 result = __wa_wait_status(wa, WA_ENABLE, 0); 409 result = __wa_wait_status(wa, WA_ENABLE, 0);
410 if (result < 0 && result != -ENODEV) 410 if (result < 0 && result != -ENODEV)
411 dev_err(dev, "error waiting for HC to stop: %d\n", result); 411 dev_err(dev, "error waiting for HC to stop: %d\n", result);
412 out: 412 out:
413 return 0; 413 return 0;
414 } 414 }
415 415
416 416
417 #endif /* #ifndef __HWAHC_INTERNAL_H__ */ 417 #endif /* #ifndef __HWAHC_INTERNAL_H__ */
418 418
include/linux/mISDNif.h
1 /* 1 /*
2 * 2 *
3 * Author Karsten Keil <kkeil@novell.com> 3 * Author Karsten Keil <kkeil@novell.com>
4 * 4 *
5 * Copyright 2008 by Karsten Keil <kkeil@novell.com> 5 * Copyright 2008 by Karsten Keil <kkeil@novell.com>
6 * 6 *
7 * This code is free software; you can redistribute it and/or modify 7 * This code is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE 8 * it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE
9 * version 2.1 as published by the Free Software Foundation. 9 * version 2.1 as published by the Free Software Foundation.
10 * 10 *
11 * This code is distributed in the hope that it will be useful, 11 * This code is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU LESSER GENERAL PUBLIC LICENSE for more details. 14 * GNU LESSER GENERAL PUBLIC LICENSE for more details.
15 * 15 *
16 */ 16 */
17 17
18 #ifndef mISDNIF_H 18 #ifndef mISDNIF_H
19 #define mISDNIF_H 19 #define mISDNIF_H
20 20
21 #include <stdarg.h> 21 #include <stdarg.h>
22 #include <linux/types.h> 22 #include <linux/types.h>
23 #include <linux/errno.h> 23 #include <linux/errno.h>
24 #include <linux/socket.h> 24 #include <linux/socket.h>
25 25
26 /* 26 /*
27 * ABI Version 32 bit 27 * ABI Version 32 bit
28 * 28 *
29 * <8 bit> Major version 29 * <8 bit> Major version
30 * - changed if any interface become backwards incompatible 30 * - changed if any interface become backwards incompatible
31 * 31 *
32 * <8 bit> Minor version 32 * <8 bit> Minor version
33 * - changed if any interface is extended but backwards compatible 33 * - changed if any interface is extended but backwards compatible
34 * 34 *
35 * <16 bit> Release number 35 * <16 bit> Release number
36 * - should be incremented on every checkin 36 * - should be incremented on every checkin
37 */ 37 */
38 #define MISDN_MAJOR_VERSION 1 38 #define MISDN_MAJOR_VERSION 1
39 #define MISDN_MINOR_VERSION 1 39 #define MISDN_MINOR_VERSION 1
40 #define MISDN_RELEASE 21 40 #define MISDN_RELEASE 21
41 41
42 /* primitives for information exchange 42 /* primitives for information exchange
43 * generell format 43 * generell format
44 * <16 bit 0 > 44 * <16 bit 0 >
45 * <8 bit command> 45 * <8 bit command>
46 * BIT 8 = 1 LAYER private 46 * BIT 8 = 1 LAYER private
47 * BIT 7 = 1 answer 47 * BIT 7 = 1 answer
48 * BIT 6 = 1 DATA 48 * BIT 6 = 1 DATA
49 * <8 bit target layer mask> 49 * <8 bit target layer mask>
50 * 50 *
51 * Layer = 00 is reserved for general commands 51 * Layer = 00 is reserved for general commands
52 Layer = 01 L2 -> HW 52 Layer = 01 L2 -> HW
53 Layer = 02 HW -> L2 53 Layer = 02 HW -> L2
54 Layer = 04 L3 -> L2 54 Layer = 04 L3 -> L2
55 Layer = 08 L2 -> L3 55 Layer = 08 L2 -> L3
56 * Layer = FF is reserved for broadcast commands 56 * Layer = FF is reserved for broadcast commands
57 */ 57 */
58 58
59 #define MISDN_CMDMASK 0xff00 59 #define MISDN_CMDMASK 0xff00
60 #define MISDN_LAYERMASK 0x00ff 60 #define MISDN_LAYERMASK 0x00ff
61 61
62 /* generell commands */ 62 /* generell commands */
63 #define OPEN_CHANNEL 0x0100 63 #define OPEN_CHANNEL 0x0100
64 #define CLOSE_CHANNEL 0x0200 64 #define CLOSE_CHANNEL 0x0200
65 #define CONTROL_CHANNEL 0x0300 65 #define CONTROL_CHANNEL 0x0300
66 #define CHECK_DATA 0x0400 66 #define CHECK_DATA 0x0400
67 67
68 /* layer 2 -> layer 1 */ 68 /* layer 2 -> layer 1 */
69 #define PH_ACTIVATE_REQ 0x0101 69 #define PH_ACTIVATE_REQ 0x0101
70 #define PH_DEACTIVATE_REQ 0x0201 70 #define PH_DEACTIVATE_REQ 0x0201
71 #define PH_DATA_REQ 0x2001 71 #define PH_DATA_REQ 0x2001
72 #define MPH_ACTIVATE_REQ 0x0501 72 #define MPH_ACTIVATE_REQ 0x0501
73 #define MPH_DEACTIVATE_REQ 0x0601 73 #define MPH_DEACTIVATE_REQ 0x0601
74 #define MPH_INFORMATION_REQ 0x0701 74 #define MPH_INFORMATION_REQ 0x0701
75 #define PH_CONTROL_REQ 0x0801 75 #define PH_CONTROL_REQ 0x0801
76 76
77 /* layer 1 -> layer 2 */ 77 /* layer 1 -> layer 2 */
78 #define PH_ACTIVATE_IND 0x0102 78 #define PH_ACTIVATE_IND 0x0102
79 #define PH_ACTIVATE_CNF 0x4102 79 #define PH_ACTIVATE_CNF 0x4102
80 #define PH_DEACTIVATE_IND 0x0202 80 #define PH_DEACTIVATE_IND 0x0202
81 #define PH_DEACTIVATE_CNF 0x4202 81 #define PH_DEACTIVATE_CNF 0x4202
82 #define PH_DATA_IND 0x2002 82 #define PH_DATA_IND 0x2002
83 #define PH_DATA_E_IND 0x3002 83 #define PH_DATA_E_IND 0x3002
84 #define MPH_ACTIVATE_IND 0x0502 84 #define MPH_ACTIVATE_IND 0x0502
85 #define MPH_DEACTIVATE_IND 0x0602 85 #define MPH_DEACTIVATE_IND 0x0602
86 #define MPH_INFORMATION_IND 0x0702 86 #define MPH_INFORMATION_IND 0x0702
87 #define PH_DATA_CNF 0x6002 87 #define PH_DATA_CNF 0x6002
88 #define PH_CONTROL_IND 0x0802 88 #define PH_CONTROL_IND 0x0802
89 #define PH_CONTROL_CNF 0x4802 89 #define PH_CONTROL_CNF 0x4802
90 90
91 /* layer 3 -> layer 2 */ 91 /* layer 3 -> layer 2 */
92 #define DL_ESTABLISH_REQ 0x1004 92 #define DL_ESTABLISH_REQ 0x1004
93 #define DL_RELEASE_REQ 0x1104 93 #define DL_RELEASE_REQ 0x1104
94 #define DL_DATA_REQ 0x3004 94 #define DL_DATA_REQ 0x3004
95 #define DL_UNITDATA_REQ 0x3104 95 #define DL_UNITDATA_REQ 0x3104
96 #define DL_INFORMATION_REQ 0x0004 96 #define DL_INFORMATION_REQ 0x0004
97 97
98 /* layer 2 -> layer 3 */ 98 /* layer 2 -> layer 3 */
99 #define DL_ESTABLISH_IND 0x1008 99 #define DL_ESTABLISH_IND 0x1008
100 #define DL_ESTABLISH_CNF 0x5008 100 #define DL_ESTABLISH_CNF 0x5008
101 #define DL_RELEASE_IND 0x1108 101 #define DL_RELEASE_IND 0x1108
102 #define DL_RELEASE_CNF 0x5108 102 #define DL_RELEASE_CNF 0x5108
103 #define DL_DATA_IND 0x3008 103 #define DL_DATA_IND 0x3008
104 #define DL_UNITDATA_IND 0x3108 104 #define DL_UNITDATA_IND 0x3108
105 #define DL_INFORMATION_IND 0x0008 105 #define DL_INFORMATION_IND 0x0008
106 106
107 /* intern layer 2 managment */ 107 /* intern layer 2 management */
108 #define MDL_ASSIGN_REQ 0x1804 108 #define MDL_ASSIGN_REQ 0x1804
109 #define MDL_ASSIGN_IND 0x1904 109 #define MDL_ASSIGN_IND 0x1904
110 #define MDL_REMOVE_REQ 0x1A04 110 #define MDL_REMOVE_REQ 0x1A04
111 #define MDL_REMOVE_IND 0x1B04 111 #define MDL_REMOVE_IND 0x1B04
112 #define MDL_STATUS_UP_IND 0x1C04 112 #define MDL_STATUS_UP_IND 0x1C04
113 #define MDL_STATUS_DOWN_IND 0x1D04 113 #define MDL_STATUS_DOWN_IND 0x1D04
114 #define MDL_STATUS_UI_IND 0x1E04 114 #define MDL_STATUS_UI_IND 0x1E04
115 #define MDL_ERROR_IND 0x1F04 115 #define MDL_ERROR_IND 0x1F04
116 #define MDL_ERROR_RSP 0x5F04 116 #define MDL_ERROR_RSP 0x5F04
117 117
118 /* DL_INFORMATION_IND types */ 118 /* DL_INFORMATION_IND types */
119 #define DL_INFO_L2_CONNECT 0x0001 119 #define DL_INFO_L2_CONNECT 0x0001
120 #define DL_INFO_L2_REMOVED 0x0002 120 #define DL_INFO_L2_REMOVED 0x0002
121 121
122 /* PH_CONTROL types */ 122 /* PH_CONTROL types */
123 /* TOUCH TONE IS 0x20XX XX "0"..."9", "A","B","C","D","*","#" */ 123 /* TOUCH TONE IS 0x20XX XX "0"..."9", "A","B","C","D","*","#" */
124 #define DTMF_TONE_VAL 0x2000 124 #define DTMF_TONE_VAL 0x2000
125 #define DTMF_TONE_MASK 0x007F 125 #define DTMF_TONE_MASK 0x007F
126 #define DTMF_TONE_START 0x2100 126 #define DTMF_TONE_START 0x2100
127 #define DTMF_TONE_STOP 0x2200 127 #define DTMF_TONE_STOP 0x2200
128 #define DTMF_HFC_COEF 0x4000 128 #define DTMF_HFC_COEF 0x4000
129 #define DSP_CONF_JOIN 0x2403 129 #define DSP_CONF_JOIN 0x2403
130 #define DSP_CONF_SPLIT 0x2404 130 #define DSP_CONF_SPLIT 0x2404
131 #define DSP_RECEIVE_OFF 0x2405 131 #define DSP_RECEIVE_OFF 0x2405
132 #define DSP_RECEIVE_ON 0x2406 132 #define DSP_RECEIVE_ON 0x2406
133 #define DSP_ECHO_ON 0x2407 133 #define DSP_ECHO_ON 0x2407
134 #define DSP_ECHO_OFF 0x2408 134 #define DSP_ECHO_OFF 0x2408
135 #define DSP_MIX_ON 0x2409 135 #define DSP_MIX_ON 0x2409
136 #define DSP_MIX_OFF 0x240a 136 #define DSP_MIX_OFF 0x240a
137 #define DSP_DELAY 0x240b 137 #define DSP_DELAY 0x240b
138 #define DSP_JITTER 0x240c 138 #define DSP_JITTER 0x240c
139 #define DSP_TXDATA_ON 0x240d 139 #define DSP_TXDATA_ON 0x240d
140 #define DSP_TXDATA_OFF 0x240e 140 #define DSP_TXDATA_OFF 0x240e
141 #define DSP_TX_DEJITTER 0x240f 141 #define DSP_TX_DEJITTER 0x240f
142 #define DSP_TX_DEJ_OFF 0x2410 142 #define DSP_TX_DEJ_OFF 0x2410
143 #define DSP_TONE_PATT_ON 0x2411 143 #define DSP_TONE_PATT_ON 0x2411
144 #define DSP_TONE_PATT_OFF 0x2412 144 #define DSP_TONE_PATT_OFF 0x2412
145 #define DSP_VOL_CHANGE_TX 0x2413 145 #define DSP_VOL_CHANGE_TX 0x2413
146 #define DSP_VOL_CHANGE_RX 0x2414 146 #define DSP_VOL_CHANGE_RX 0x2414
147 #define DSP_BF_ENABLE_KEY 0x2415 147 #define DSP_BF_ENABLE_KEY 0x2415
148 #define DSP_BF_DISABLE 0x2416 148 #define DSP_BF_DISABLE 0x2416
149 #define DSP_BF_ACCEPT 0x2416 149 #define DSP_BF_ACCEPT 0x2416
150 #define DSP_BF_REJECT 0x2417 150 #define DSP_BF_REJECT 0x2417
151 #define DSP_PIPELINE_CFG 0x2418 151 #define DSP_PIPELINE_CFG 0x2418
152 #define HFC_VOL_CHANGE_TX 0x2601 152 #define HFC_VOL_CHANGE_TX 0x2601
153 #define HFC_VOL_CHANGE_RX 0x2602 153 #define HFC_VOL_CHANGE_RX 0x2602
154 #define HFC_SPL_LOOP_ON 0x2603 154 #define HFC_SPL_LOOP_ON 0x2603
155 #define HFC_SPL_LOOP_OFF 0x2604 155 #define HFC_SPL_LOOP_OFF 0x2604
156 /* for T30 FAX and analog modem */ 156 /* for T30 FAX and analog modem */
157 #define HW_MOD_FRM 0x4000 157 #define HW_MOD_FRM 0x4000
158 #define HW_MOD_FRH 0x4001 158 #define HW_MOD_FRH 0x4001
159 #define HW_MOD_FTM 0x4002 159 #define HW_MOD_FTM 0x4002
160 #define HW_MOD_FTH 0x4003 160 #define HW_MOD_FTH 0x4003
161 #define HW_MOD_FTS 0x4004 161 #define HW_MOD_FTS 0x4004
162 #define HW_MOD_CONNECT 0x4010 162 #define HW_MOD_CONNECT 0x4010
163 #define HW_MOD_OK 0x4011 163 #define HW_MOD_OK 0x4011
164 #define HW_MOD_NOCARR 0x4012 164 #define HW_MOD_NOCARR 0x4012
165 #define HW_MOD_FCERROR 0x4013 165 #define HW_MOD_FCERROR 0x4013
166 #define HW_MOD_READY 0x4014 166 #define HW_MOD_READY 0x4014
167 #define HW_MOD_LASTDATA 0x4015 167 #define HW_MOD_LASTDATA 0x4015
168 168
169 /* DSP_TONE_PATT_ON parameter */ 169 /* DSP_TONE_PATT_ON parameter */
170 #define TONE_OFF 0x0000 170 #define TONE_OFF 0x0000
171 #define TONE_GERMAN_DIALTONE 0x0001 171 #define TONE_GERMAN_DIALTONE 0x0001
172 #define TONE_GERMAN_OLDDIALTONE 0x0002 172 #define TONE_GERMAN_OLDDIALTONE 0x0002
173 #define TONE_AMERICAN_DIALTONE 0x0003 173 #define TONE_AMERICAN_DIALTONE 0x0003
174 #define TONE_GERMAN_DIALPBX 0x0004 174 #define TONE_GERMAN_DIALPBX 0x0004
175 #define TONE_GERMAN_OLDDIALPBX 0x0005 175 #define TONE_GERMAN_OLDDIALPBX 0x0005
176 #define TONE_AMERICAN_DIALPBX 0x0006 176 #define TONE_AMERICAN_DIALPBX 0x0006
177 #define TONE_GERMAN_RINGING 0x0007 177 #define TONE_GERMAN_RINGING 0x0007
178 #define TONE_GERMAN_OLDRINGING 0x0008 178 #define TONE_GERMAN_OLDRINGING 0x0008
179 #define TONE_AMERICAN_RINGPBX 0x000b 179 #define TONE_AMERICAN_RINGPBX 0x000b
180 #define TONE_GERMAN_RINGPBX 0x000c 180 #define TONE_GERMAN_RINGPBX 0x000c
181 #define TONE_GERMAN_OLDRINGPBX 0x000d 181 #define TONE_GERMAN_OLDRINGPBX 0x000d
182 #define TONE_AMERICAN_RINGING 0x000e 182 #define TONE_AMERICAN_RINGING 0x000e
183 #define TONE_GERMAN_BUSY 0x000f 183 #define TONE_GERMAN_BUSY 0x000f
184 #define TONE_GERMAN_OLDBUSY 0x0010 184 #define TONE_GERMAN_OLDBUSY 0x0010
185 #define TONE_AMERICAN_BUSY 0x0011 185 #define TONE_AMERICAN_BUSY 0x0011
186 #define TONE_GERMAN_HANGUP 0x0012 186 #define TONE_GERMAN_HANGUP 0x0012
187 #define TONE_GERMAN_OLDHANGUP 0x0013 187 #define TONE_GERMAN_OLDHANGUP 0x0013
188 #define TONE_AMERICAN_HANGUP 0x0014 188 #define TONE_AMERICAN_HANGUP 0x0014
189 #define TONE_SPECIAL_INFO 0x0015 189 #define TONE_SPECIAL_INFO 0x0015
190 #define TONE_GERMAN_GASSENBESETZT 0x0016 190 #define TONE_GERMAN_GASSENBESETZT 0x0016
191 #define TONE_GERMAN_AUFSCHALTTON 0x0016 191 #define TONE_GERMAN_AUFSCHALTTON 0x0016
192 192
193 /* MPH_INFORMATION_IND */ 193 /* MPH_INFORMATION_IND */
194 #define L1_SIGNAL_LOS_OFF 0x0010 194 #define L1_SIGNAL_LOS_OFF 0x0010
195 #define L1_SIGNAL_LOS_ON 0x0011 195 #define L1_SIGNAL_LOS_ON 0x0011
196 #define L1_SIGNAL_AIS_OFF 0x0012 196 #define L1_SIGNAL_AIS_OFF 0x0012
197 #define L1_SIGNAL_AIS_ON 0x0013 197 #define L1_SIGNAL_AIS_ON 0x0013
198 #define L1_SIGNAL_RDI_OFF 0x0014 198 #define L1_SIGNAL_RDI_OFF 0x0014
199 #define L1_SIGNAL_RDI_ON 0x0015 199 #define L1_SIGNAL_RDI_ON 0x0015
200 #define L1_SIGNAL_SLIP_RX 0x0020 200 #define L1_SIGNAL_SLIP_RX 0x0020
201 #define L1_SIGNAL_SLIP_TX 0x0021 201 #define L1_SIGNAL_SLIP_TX 0x0021
202 202
203 /* 203 /*
204 * protocol ids 204 * protocol ids
205 * D channel 1-31 205 * D channel 1-31
206 * B channel 33 - 63 206 * B channel 33 - 63
207 */ 207 */
208 208
209 #define ISDN_P_NONE 0 209 #define ISDN_P_NONE 0
210 #define ISDN_P_BASE 0 210 #define ISDN_P_BASE 0
211 #define ISDN_P_TE_S0 0x01 211 #define ISDN_P_TE_S0 0x01
212 #define ISDN_P_NT_S0 0x02 212 #define ISDN_P_NT_S0 0x02
213 #define ISDN_P_TE_E1 0x03 213 #define ISDN_P_TE_E1 0x03
214 #define ISDN_P_NT_E1 0x04 214 #define ISDN_P_NT_E1 0x04
215 #define ISDN_P_TE_UP0 0x05 215 #define ISDN_P_TE_UP0 0x05
216 #define ISDN_P_NT_UP0 0x06 216 #define ISDN_P_NT_UP0 0x06
217 217
218 #define IS_ISDN_P_TE(p) ((p == ISDN_P_TE_S0) || (p == ISDN_P_TE_E1) || \ 218 #define IS_ISDN_P_TE(p) ((p == ISDN_P_TE_S0) || (p == ISDN_P_TE_E1) || \
219 (p == ISDN_P_TE_UP0) || (p == ISDN_P_LAPD_TE)) 219 (p == ISDN_P_TE_UP0) || (p == ISDN_P_LAPD_TE))
220 #define IS_ISDN_P_NT(p) ((p == ISDN_P_NT_S0) || (p == ISDN_P_NT_E1) || \ 220 #define IS_ISDN_P_NT(p) ((p == ISDN_P_NT_S0) || (p == ISDN_P_NT_E1) || \
221 (p == ISDN_P_NT_UP0) || (p == ISDN_P_LAPD_NT)) 221 (p == ISDN_P_NT_UP0) || (p == ISDN_P_LAPD_NT))
222 #define IS_ISDN_P_S0(p) ((p == ISDN_P_TE_S0) || (p == ISDN_P_NT_S0)) 222 #define IS_ISDN_P_S0(p) ((p == ISDN_P_TE_S0) || (p == ISDN_P_NT_S0))
223 #define IS_ISDN_P_E1(p) ((p == ISDN_P_TE_E1) || (p == ISDN_P_NT_E1)) 223 #define IS_ISDN_P_E1(p) ((p == ISDN_P_TE_E1) || (p == ISDN_P_NT_E1))
224 #define IS_ISDN_P_UP0(p) ((p == ISDN_P_TE_UP0) || (p == ISDN_P_NT_UP0)) 224 #define IS_ISDN_P_UP0(p) ((p == ISDN_P_TE_UP0) || (p == ISDN_P_NT_UP0))
225 225
226 226
227 #define ISDN_P_LAPD_TE 0x10 227 #define ISDN_P_LAPD_TE 0x10
228 #define ISDN_P_LAPD_NT 0x11 228 #define ISDN_P_LAPD_NT 0x11
229 229
230 #define ISDN_P_B_MASK 0x1f 230 #define ISDN_P_B_MASK 0x1f
231 #define ISDN_P_B_START 0x20 231 #define ISDN_P_B_START 0x20
232 232
233 #define ISDN_P_B_RAW 0x21 233 #define ISDN_P_B_RAW 0x21
234 #define ISDN_P_B_HDLC 0x22 234 #define ISDN_P_B_HDLC 0x22
235 #define ISDN_P_B_X75SLP 0x23 235 #define ISDN_P_B_X75SLP 0x23
236 #define ISDN_P_B_L2DTMF 0x24 236 #define ISDN_P_B_L2DTMF 0x24
237 #define ISDN_P_B_L2DSP 0x25 237 #define ISDN_P_B_L2DSP 0x25
238 #define ISDN_P_B_L2DSPHDLC 0x26 238 #define ISDN_P_B_L2DSPHDLC 0x26
239 #define ISDN_P_B_T30_FAX 0x27 239 #define ISDN_P_B_T30_FAX 0x27
240 #define ISDN_P_B_MODEM_ASYNC 0x28 240 #define ISDN_P_B_MODEM_ASYNC 0x28
241 241
242 #define OPTION_L2_PMX 1 242 #define OPTION_L2_PMX 1
243 #define OPTION_L2_PTP 2 243 #define OPTION_L2_PTP 2
244 #define OPTION_L2_FIXEDTEI 3 244 #define OPTION_L2_FIXEDTEI 3
245 #define OPTION_L2_CLEANUP 4 245 #define OPTION_L2_CLEANUP 4
246 #define OPTION_L1_HOLD 5 246 #define OPTION_L1_HOLD 5
247 247
248 /* should be in sync with linux/kobject.h:KOBJ_NAME_LEN */ 248 /* should be in sync with linux/kobject.h:KOBJ_NAME_LEN */
249 #define MISDN_MAX_IDLEN 20 249 #define MISDN_MAX_IDLEN 20
250 250
251 struct mISDNhead { 251 struct mISDNhead {
252 unsigned int prim; 252 unsigned int prim;
253 unsigned int id; 253 unsigned int id;
254 } __attribute__((packed)); 254 } __attribute__((packed));
255 255
256 #define MISDN_HEADER_LEN sizeof(struct mISDNhead) 256 #define MISDN_HEADER_LEN sizeof(struct mISDNhead)
257 #define MAX_DATA_SIZE 2048 257 #define MAX_DATA_SIZE 2048
258 #define MAX_DATA_MEM (MAX_DATA_SIZE + MISDN_HEADER_LEN) 258 #define MAX_DATA_MEM (MAX_DATA_SIZE + MISDN_HEADER_LEN)
259 #define MAX_DFRAME_LEN 260 259 #define MAX_DFRAME_LEN 260
260 260
261 #define MISDN_ID_ADDR_MASK 0xFFFF 261 #define MISDN_ID_ADDR_MASK 0xFFFF
262 #define MISDN_ID_TEI_MASK 0xFF00 262 #define MISDN_ID_TEI_MASK 0xFF00
263 #define MISDN_ID_SAPI_MASK 0x00FF 263 #define MISDN_ID_SAPI_MASK 0x00FF
264 #define MISDN_ID_TEI_ANY 0x7F00 264 #define MISDN_ID_TEI_ANY 0x7F00
265 265
266 #define MISDN_ID_ANY 0xFFFF 266 #define MISDN_ID_ANY 0xFFFF
267 #define MISDN_ID_NONE 0xFFFE 267 #define MISDN_ID_NONE 0xFFFE
268 268
269 #define GROUP_TEI 127 269 #define GROUP_TEI 127
270 #define TEI_SAPI 63 270 #define TEI_SAPI 63
271 #define CTRL_SAPI 0 271 #define CTRL_SAPI 0
272 272
273 #define MISDN_MAX_CHANNEL 127 273 #define MISDN_MAX_CHANNEL 127
274 #define MISDN_CHMAP_SIZE ((MISDN_MAX_CHANNEL + 1) >> 3) 274 #define MISDN_CHMAP_SIZE ((MISDN_MAX_CHANNEL + 1) >> 3)
275 275
276 #define SOL_MISDN 0 276 #define SOL_MISDN 0
277 277
278 struct sockaddr_mISDN { 278 struct sockaddr_mISDN {
279 sa_family_t family; 279 sa_family_t family;
280 unsigned char dev; 280 unsigned char dev;
281 unsigned char channel; 281 unsigned char channel;
282 unsigned char sapi; 282 unsigned char sapi;
283 unsigned char tei; 283 unsigned char tei;
284 }; 284 };
285 285
286 struct mISDNversion { 286 struct mISDNversion {
287 unsigned char major; 287 unsigned char major;
288 unsigned char minor; 288 unsigned char minor;
289 unsigned short release; 289 unsigned short release;
290 }; 290 };
291 291
292 struct mISDN_devinfo { 292 struct mISDN_devinfo {
293 u_int id; 293 u_int id;
294 u_int Dprotocols; 294 u_int Dprotocols;
295 u_int Bprotocols; 295 u_int Bprotocols;
296 u_int protocol; 296 u_int protocol;
297 u_char channelmap[MISDN_CHMAP_SIZE]; 297 u_char channelmap[MISDN_CHMAP_SIZE];
298 u_int nrbchan; 298 u_int nrbchan;
299 char name[MISDN_MAX_IDLEN]; 299 char name[MISDN_MAX_IDLEN];
300 }; 300 };
301 301
302 struct mISDN_devrename { 302 struct mISDN_devrename {
303 u_int id; 303 u_int id;
304 char name[MISDN_MAX_IDLEN]; /* new name */ 304 char name[MISDN_MAX_IDLEN]; /* new name */
305 }; 305 };
306 306
307 /* MPH_INFORMATION_REQ payload */ 307 /* MPH_INFORMATION_REQ payload */
308 struct ph_info_ch { 308 struct ph_info_ch {
309 __u32 protocol; 309 __u32 protocol;
310 __u64 Flags; 310 __u64 Flags;
311 }; 311 };
312 312
313 struct ph_info_dch { 313 struct ph_info_dch {
314 struct ph_info_ch ch; 314 struct ph_info_ch ch;
315 __u16 state; 315 __u16 state;
316 __u16 num_bch; 316 __u16 num_bch;
317 }; 317 };
318 318
319 struct ph_info { 319 struct ph_info {
320 struct ph_info_dch dch; 320 struct ph_info_dch dch;
321 struct ph_info_ch bch[]; 321 struct ph_info_ch bch[];
322 }; 322 };
323 323
324 /* timer device ioctl */ 324 /* timer device ioctl */
325 #define IMADDTIMER _IOR('I', 64, int) 325 #define IMADDTIMER _IOR('I', 64, int)
326 #define IMDELTIMER _IOR('I', 65, int) 326 #define IMDELTIMER _IOR('I', 65, int)
327 327
328 /* socket ioctls */ 328 /* socket ioctls */
329 #define IMGETVERSION _IOR('I', 66, int) 329 #define IMGETVERSION _IOR('I', 66, int)
330 #define IMGETCOUNT _IOR('I', 67, int) 330 #define IMGETCOUNT _IOR('I', 67, int)
331 #define IMGETDEVINFO _IOR('I', 68, int) 331 #define IMGETDEVINFO _IOR('I', 68, int)
332 #define IMCTRLREQ _IOR('I', 69, int) 332 #define IMCTRLREQ _IOR('I', 69, int)
333 #define IMCLEAR_L2 _IOR('I', 70, int) 333 #define IMCLEAR_L2 _IOR('I', 70, int)
334 #define IMSETDEVNAME _IOR('I', 71, struct mISDN_devrename) 334 #define IMSETDEVNAME _IOR('I', 71, struct mISDN_devrename)
335 #define IMHOLD_L1 _IOR('I', 72, int) 335 #define IMHOLD_L1 _IOR('I', 72, int)
336 336
337 static inline int 337 static inline int
338 test_channelmap(u_int nr, u_char *map) 338 test_channelmap(u_int nr, u_char *map)
339 { 339 {
340 if (nr <= MISDN_MAX_CHANNEL) 340 if (nr <= MISDN_MAX_CHANNEL)
341 return map[nr >> 3] & (1 << (nr & 7)); 341 return map[nr >> 3] & (1 << (nr & 7));
342 else 342 else
343 return 0; 343 return 0;
344 } 344 }
345 345
346 static inline void 346 static inline void
347 set_channelmap(u_int nr, u_char *map) 347 set_channelmap(u_int nr, u_char *map)
348 { 348 {
349 map[nr >> 3] |= (1 << (nr & 7)); 349 map[nr >> 3] |= (1 << (nr & 7));
350 } 350 }
351 351
352 static inline void 352 static inline void
353 clear_channelmap(u_int nr, u_char *map) 353 clear_channelmap(u_int nr, u_char *map)
354 { 354 {
355 map[nr >> 3] &= ~(1 << (nr & 7)); 355 map[nr >> 3] &= ~(1 << (nr & 7));
356 } 356 }
357 357
358 /* CONTROL_CHANNEL parameters */ 358 /* CONTROL_CHANNEL parameters */
359 #define MISDN_CTRL_GETOP 0x0000 359 #define MISDN_CTRL_GETOP 0x0000
360 #define MISDN_CTRL_LOOP 0x0001 360 #define MISDN_CTRL_LOOP 0x0001
361 #define MISDN_CTRL_CONNECT 0x0002 361 #define MISDN_CTRL_CONNECT 0x0002
362 #define MISDN_CTRL_DISCONNECT 0x0004 362 #define MISDN_CTRL_DISCONNECT 0x0004
363 #define MISDN_CTRL_PCMCONNECT 0x0010 363 #define MISDN_CTRL_PCMCONNECT 0x0010
364 #define MISDN_CTRL_PCMDISCONNECT 0x0020 364 #define MISDN_CTRL_PCMDISCONNECT 0x0020
365 #define MISDN_CTRL_SETPEER 0x0040 365 #define MISDN_CTRL_SETPEER 0x0040
366 #define MISDN_CTRL_UNSETPEER 0x0080 366 #define MISDN_CTRL_UNSETPEER 0x0080
367 #define MISDN_CTRL_RX_OFF 0x0100 367 #define MISDN_CTRL_RX_OFF 0x0100
368 #define MISDN_CTRL_FILL_EMPTY 0x0200 368 #define MISDN_CTRL_FILL_EMPTY 0x0200
369 #define MISDN_CTRL_GETPEER 0x0400 369 #define MISDN_CTRL_GETPEER 0x0400
370 #define MISDN_CTRL_HW_FEATURES_OP 0x2000 370 #define MISDN_CTRL_HW_FEATURES_OP 0x2000
371 #define MISDN_CTRL_HW_FEATURES 0x2001 371 #define MISDN_CTRL_HW_FEATURES 0x2001
372 #define MISDN_CTRL_HFC_OP 0x4000 372 #define MISDN_CTRL_HFC_OP 0x4000
373 #define MISDN_CTRL_HFC_PCM_CONN 0x4001 373 #define MISDN_CTRL_HFC_PCM_CONN 0x4001
374 #define MISDN_CTRL_HFC_PCM_DISC 0x4002 374 #define MISDN_CTRL_HFC_PCM_DISC 0x4002
375 #define MISDN_CTRL_HFC_CONF_JOIN 0x4003 375 #define MISDN_CTRL_HFC_CONF_JOIN 0x4003
376 #define MISDN_CTRL_HFC_CONF_SPLIT 0x4004 376 #define MISDN_CTRL_HFC_CONF_SPLIT 0x4004
377 #define MISDN_CTRL_HFC_RECEIVE_OFF 0x4005 377 #define MISDN_CTRL_HFC_RECEIVE_OFF 0x4005
378 #define MISDN_CTRL_HFC_RECEIVE_ON 0x4006 378 #define MISDN_CTRL_HFC_RECEIVE_ON 0x4006
379 #define MISDN_CTRL_HFC_ECHOCAN_ON 0x4007 379 #define MISDN_CTRL_HFC_ECHOCAN_ON 0x4007
380 #define MISDN_CTRL_HFC_ECHOCAN_OFF 0x4008 380 #define MISDN_CTRL_HFC_ECHOCAN_OFF 0x4008
381 #define MISDN_CTRL_HFC_WD_INIT 0x4009 381 #define MISDN_CTRL_HFC_WD_INIT 0x4009
382 #define MISDN_CTRL_HFC_WD_RESET 0x400A 382 #define MISDN_CTRL_HFC_WD_RESET 0x400A
383 383
384 /* socket options */ 384 /* socket options */
385 #define MISDN_TIME_STAMP 0x0001 385 #define MISDN_TIME_STAMP 0x0001
386 386
387 struct mISDN_ctrl_req { 387 struct mISDN_ctrl_req {
388 int op; 388 int op;
389 int channel; 389 int channel;
390 int p1; 390 int p1;
391 int p2; 391 int p2;
392 }; 392 };
393 393
394 /* muxer options */ 394 /* muxer options */
395 #define MISDN_OPT_ALL 1 395 #define MISDN_OPT_ALL 1
396 #define MISDN_OPT_TEIMGR 2 396 #define MISDN_OPT_TEIMGR 2
397 397
398 #ifdef __KERNEL__ 398 #ifdef __KERNEL__
399 #include <linux/list.h> 399 #include <linux/list.h>
400 #include <linux/skbuff.h> 400 #include <linux/skbuff.h>
401 #include <linux/net.h> 401 #include <linux/net.h>
402 #include <net/sock.h> 402 #include <net/sock.h>
403 #include <linux/completion.h> 403 #include <linux/completion.h>
404 404
405 #define DEBUG_CORE 0x000000ff 405 #define DEBUG_CORE 0x000000ff
406 #define DEBUG_CORE_FUNC 0x00000002 406 #define DEBUG_CORE_FUNC 0x00000002
407 #define DEBUG_SOCKET 0x00000004 407 #define DEBUG_SOCKET 0x00000004
408 #define DEBUG_MANAGER 0x00000008 408 #define DEBUG_MANAGER 0x00000008
409 #define DEBUG_SEND_ERR 0x00000010 409 #define DEBUG_SEND_ERR 0x00000010
410 #define DEBUG_MSG_THREAD 0x00000020 410 #define DEBUG_MSG_THREAD 0x00000020
411 #define DEBUG_QUEUE_FUNC 0x00000040 411 #define DEBUG_QUEUE_FUNC 0x00000040
412 #define DEBUG_L1 0x0000ff00 412 #define DEBUG_L1 0x0000ff00
413 #define DEBUG_L1_FSM 0x00000200 413 #define DEBUG_L1_FSM 0x00000200
414 #define DEBUG_L2 0x00ff0000 414 #define DEBUG_L2 0x00ff0000
415 #define DEBUG_L2_FSM 0x00020000 415 #define DEBUG_L2_FSM 0x00020000
416 #define DEBUG_L2_CTRL 0x00040000 416 #define DEBUG_L2_CTRL 0x00040000
417 #define DEBUG_L2_RECV 0x00080000 417 #define DEBUG_L2_RECV 0x00080000
418 #define DEBUG_L2_TEI 0x00100000 418 #define DEBUG_L2_TEI 0x00100000
419 #define DEBUG_L2_TEIFSM 0x00200000 419 #define DEBUG_L2_TEIFSM 0x00200000
420 #define DEBUG_TIMER 0x01000000 420 #define DEBUG_TIMER 0x01000000
421 #define DEBUG_CLOCK 0x02000000 421 #define DEBUG_CLOCK 0x02000000
422 422
423 #define mISDN_HEAD_P(s) ((struct mISDNhead *)&s->cb[0]) 423 #define mISDN_HEAD_P(s) ((struct mISDNhead *)&s->cb[0])
424 #define mISDN_HEAD_PRIM(s) (((struct mISDNhead *)&s->cb[0])->prim) 424 #define mISDN_HEAD_PRIM(s) (((struct mISDNhead *)&s->cb[0])->prim)
425 #define mISDN_HEAD_ID(s) (((struct mISDNhead *)&s->cb[0])->id) 425 #define mISDN_HEAD_ID(s) (((struct mISDNhead *)&s->cb[0])->id)
426 426
427 /* socket states */ 427 /* socket states */
428 #define MISDN_OPEN 1 428 #define MISDN_OPEN 1
429 #define MISDN_BOUND 2 429 #define MISDN_BOUND 2
430 #define MISDN_CLOSED 3 430 #define MISDN_CLOSED 3
431 431
432 struct mISDNchannel; 432 struct mISDNchannel;
433 struct mISDNdevice; 433 struct mISDNdevice;
434 struct mISDNstack; 434 struct mISDNstack;
435 struct mISDNclock; 435 struct mISDNclock;
436 436
437 struct channel_req { 437 struct channel_req {
438 u_int protocol; 438 u_int protocol;
439 struct sockaddr_mISDN adr; 439 struct sockaddr_mISDN adr;
440 struct mISDNchannel *ch; 440 struct mISDNchannel *ch;
441 }; 441 };
442 442
443 typedef int (ctrl_func_t)(struct mISDNchannel *, u_int, void *); 443 typedef int (ctrl_func_t)(struct mISDNchannel *, u_int, void *);
444 typedef int (send_func_t)(struct mISDNchannel *, struct sk_buff *); 444 typedef int (send_func_t)(struct mISDNchannel *, struct sk_buff *);
445 typedef int (create_func_t)(struct channel_req *); 445 typedef int (create_func_t)(struct channel_req *);
446 446
447 struct Bprotocol { 447 struct Bprotocol {
448 struct list_head list; 448 struct list_head list;
449 char *name; 449 char *name;
450 u_int Bprotocols; 450 u_int Bprotocols;
451 create_func_t *create; 451 create_func_t *create;
452 }; 452 };
453 453
454 struct mISDNchannel { 454 struct mISDNchannel {
455 struct list_head list; 455 struct list_head list;
456 u_int protocol; 456 u_int protocol;
457 u_int nr; 457 u_int nr;
458 u_long opt; 458 u_long opt;
459 u_int addr; 459 u_int addr;
460 struct mISDNstack *st; 460 struct mISDNstack *st;
461 struct mISDNchannel *peer; 461 struct mISDNchannel *peer;
462 send_func_t *send; 462 send_func_t *send;
463 send_func_t *recv; 463 send_func_t *recv;
464 ctrl_func_t *ctrl; 464 ctrl_func_t *ctrl;
465 }; 465 };
466 466
467 struct mISDN_sock_list { 467 struct mISDN_sock_list {
468 struct hlist_head head; 468 struct hlist_head head;
469 rwlock_t lock; 469 rwlock_t lock;
470 }; 470 };
471 471
472 struct mISDN_sock { 472 struct mISDN_sock {
473 struct sock sk; 473 struct sock sk;
474 struct mISDNchannel ch; 474 struct mISDNchannel ch;
475 u_int cmask; 475 u_int cmask;
476 struct mISDNdevice *dev; 476 struct mISDNdevice *dev;
477 }; 477 };
478 478
479 479
480 480
481 struct mISDNdevice { 481 struct mISDNdevice {
482 struct mISDNchannel D; 482 struct mISDNchannel D;
483 u_int id; 483 u_int id;
484 u_int Dprotocols; 484 u_int Dprotocols;
485 u_int Bprotocols; 485 u_int Bprotocols;
486 u_int nrbchan; 486 u_int nrbchan;
487 u_char channelmap[MISDN_CHMAP_SIZE]; 487 u_char channelmap[MISDN_CHMAP_SIZE];
488 struct list_head bchannels; 488 struct list_head bchannels;
489 struct mISDNchannel *teimgr; 489 struct mISDNchannel *teimgr;
490 struct device dev; 490 struct device dev;
491 }; 491 };
492 492
493 struct mISDNstack { 493 struct mISDNstack {
494 u_long status; 494 u_long status;
495 struct mISDNdevice *dev; 495 struct mISDNdevice *dev;
496 struct task_struct *thread; 496 struct task_struct *thread;
497 struct completion *notify; 497 struct completion *notify;
498 wait_queue_head_t workq; 498 wait_queue_head_t workq;
499 struct sk_buff_head msgq; 499 struct sk_buff_head msgq;
500 struct list_head layer2; 500 struct list_head layer2;
501 struct mISDNchannel *layer1; 501 struct mISDNchannel *layer1;
502 struct mISDNchannel own; 502 struct mISDNchannel own;
503 struct mutex lmutex; /* protect lists */ 503 struct mutex lmutex; /* protect lists */
504 struct mISDN_sock_list l1sock; 504 struct mISDN_sock_list l1sock;
505 #ifdef MISDN_MSG_STATS 505 #ifdef MISDN_MSG_STATS
506 u_int msg_cnt; 506 u_int msg_cnt;
507 u_int sleep_cnt; 507 u_int sleep_cnt;
508 u_int stopped_cnt; 508 u_int stopped_cnt;
509 #endif 509 #endif
510 }; 510 };
511 511
512 typedef int (clockctl_func_t)(void *, int); 512 typedef int (clockctl_func_t)(void *, int);
513 513
514 struct mISDNclock { 514 struct mISDNclock {
515 struct list_head list; 515 struct list_head list;
516 char name[64]; 516 char name[64];
517 int pri; 517 int pri;
518 clockctl_func_t *ctl; 518 clockctl_func_t *ctl;
519 void *priv; 519 void *priv;
520 }; 520 };
521 521
522 /* global alloc/queue functions */ 522 /* global alloc/queue functions */
523 523
524 static inline struct sk_buff * 524 static inline struct sk_buff *
525 mI_alloc_skb(unsigned int len, gfp_t gfp_mask) 525 mI_alloc_skb(unsigned int len, gfp_t gfp_mask)
526 { 526 {
527 struct sk_buff *skb; 527 struct sk_buff *skb;
528 528
529 skb = alloc_skb(len + MISDN_HEADER_LEN, gfp_mask); 529 skb = alloc_skb(len + MISDN_HEADER_LEN, gfp_mask);
530 if (likely(skb)) 530 if (likely(skb))
531 skb_reserve(skb, MISDN_HEADER_LEN); 531 skb_reserve(skb, MISDN_HEADER_LEN);
532 return skb; 532 return skb;
533 } 533 }
534 534
535 static inline struct sk_buff * 535 static inline struct sk_buff *
536 _alloc_mISDN_skb(u_int prim, u_int id, u_int len, void *dp, gfp_t gfp_mask) 536 _alloc_mISDN_skb(u_int prim, u_int id, u_int len, void *dp, gfp_t gfp_mask)
537 { 537 {
538 struct sk_buff *skb = mI_alloc_skb(len, gfp_mask); 538 struct sk_buff *skb = mI_alloc_skb(len, gfp_mask);
539 struct mISDNhead *hh; 539 struct mISDNhead *hh;
540 540
541 if (!skb) 541 if (!skb)
542 return NULL; 542 return NULL;
543 if (len) 543 if (len)
544 memcpy(skb_put(skb, len), dp, len); 544 memcpy(skb_put(skb, len), dp, len);
545 hh = mISDN_HEAD_P(skb); 545 hh = mISDN_HEAD_P(skb);
546 hh->prim = prim; 546 hh->prim = prim;
547 hh->id = id; 547 hh->id = id;
548 return skb; 548 return skb;
549 } 549 }
550 550
551 static inline void 551 static inline void
552 _queue_data(struct mISDNchannel *ch, u_int prim, 552 _queue_data(struct mISDNchannel *ch, u_int prim,
553 u_int id, u_int len, void *dp, gfp_t gfp_mask) 553 u_int id, u_int len, void *dp, gfp_t gfp_mask)
554 { 554 {
555 struct sk_buff *skb; 555 struct sk_buff *skb;
556 556
557 if (!ch->peer) 557 if (!ch->peer)
558 return; 558 return;
559 skb = _alloc_mISDN_skb(prim, id, len, dp, gfp_mask); 559 skb = _alloc_mISDN_skb(prim, id, len, dp, gfp_mask);
560 if (!skb) 560 if (!skb)
561 return; 561 return;
562 if (ch->recv(ch->peer, skb)) 562 if (ch->recv(ch->peer, skb))
563 dev_kfree_skb(skb); 563 dev_kfree_skb(skb);
564 } 564 }
565 565
566 /* global register/unregister functions */ 566 /* global register/unregister functions */
567 567
568 extern int mISDN_register_device(struct mISDNdevice *, 568 extern int mISDN_register_device(struct mISDNdevice *,
569 struct device *parent, char *name); 569 struct device *parent, char *name);
570 extern void mISDN_unregister_device(struct mISDNdevice *); 570 extern void mISDN_unregister_device(struct mISDNdevice *);
571 extern int mISDN_register_Bprotocol(struct Bprotocol *); 571 extern int mISDN_register_Bprotocol(struct Bprotocol *);
572 extern void mISDN_unregister_Bprotocol(struct Bprotocol *); 572 extern void mISDN_unregister_Bprotocol(struct Bprotocol *);
573 extern struct mISDNclock *mISDN_register_clock(char *, int, clockctl_func_t *, 573 extern struct mISDNclock *mISDN_register_clock(char *, int, clockctl_func_t *,
574 void *); 574 void *);
575 extern void mISDN_unregister_clock(struct mISDNclock *); 575 extern void mISDN_unregister_clock(struct mISDNclock *);
576 576
577 static inline struct mISDNdevice *dev_to_mISDN(struct device *dev) 577 static inline struct mISDNdevice *dev_to_mISDN(struct device *dev)
578 { 578 {
579 if (dev) 579 if (dev)
580 return dev_get_drvdata(dev); 580 return dev_get_drvdata(dev);
581 else 581 else
582 return NULL; 582 return NULL;
583 } 583 }
584 584
585 extern void set_channel_address(struct mISDNchannel *, u_int, u_int); 585 extern void set_channel_address(struct mISDNchannel *, u_int, u_int);
586 extern void mISDN_clock_update(struct mISDNclock *, int, struct timeval *); 586 extern void mISDN_clock_update(struct mISDNclock *, int, struct timeval *);
587 extern unsigned short mISDN_clock_get(void); 587 extern unsigned short mISDN_clock_get(void);
588 588
589 #endif /* __KERNEL__ */ 589 #endif /* __KERNEL__ */
590 #endif /* mISDNIF_H */ 590 #endif /* mISDNIF_H */
591 591